实验4 汇编应用编程和c语言程序反汇编分析
1 assume cs:code, ds:data, ss:stack 2 3 data segment 4 db 'welcome to masm!' 5 db 02H, 24H, 71H 6 dw 0720H, 07C0H, 0860H ;11*160+64,12*160+64,13*160+64 7 data ends 8 9 stack segment 10 dw 8 dup(0) 11 stack ends 12 13 code segment 14 start: 15 mov ax, stacksg 16 mov ss, ax 17 mov sp, 16 18 19 mov ax, datasg 20 mov ds, ax 21 22 mov ax, 0B800H 23 mov es, ax 24 25 mov cx, 3 ;外循环循环三次 26 mov bx, 16 ; 颜色从数据段的16个字节开始 27 mov di, 32 ; 显示位置从数据段的32个字节开始 28 29 s0: push cx 30 mov cx, 16 ;内循环循环16次 31 mov bp, [di] 32 mov si, 0 33 34 s1: 35 mov al, [si] ; 低位字节写存储字符的ASCII码 36 mov ah, [bx] ; 高位字节写存储字符的属性 37 mov es:[bp], ax 38 39 inc bp 40 inc bp ; 1个字符占用的是2个字节,需要+2 41 inc si ; 下一个显示的字符 42 loop s1 43 44 pop cx 45 add bx, 1 ; 使用下一个颜色 46 add di, 2 ; 下一个显示字符开始位置 47 loop s0 48 49 mov ax, 4c00H 50 int 21H 51 52 code ends 53 end start
分析:
在80*25彩色字符模式下,显示器可以显示25行,那么中间位置设置为11,12,13行来显示字符串。又因为每行80个字符,目标字符串16个字符,所以每行的开始位置设置成从第32个字符开始,又因为每个字符占用2个字节,所以计算字符位置时要在每行的初始位置上再加上64。
计算显示字符的位置:(第一行)11*160+64=1824==>07C0H(第二行)12*160+64=1984==>07C0H(第三行)13*160+64=2144==>0860H
根据书上属性字节的格式可以按位设置属性字节,配出各种不同的前景色和背景色:
黑底绿字:0000 0010B==>02H 绿底红字:0010 0100B==>24H 白底蓝字:0111 0001B==>71H
cx:参与内外循环,bx:颜色在数据段的索引,di:每行开始位置在数据段的索引,si:字符在数据段的索引,bp:每个字符具体的显示位置,al:存储字符 ASCII码,ah:存储字符的属性。
运用两层循环解决问题。
运行结果:
1 assume cs:code, ds:data 2 data segment 3 str db 'try', 0 4 data ends 5 6 code segment 7 start: 8 mov ax, data 9 mov ds, ax ;设置入口参数ds 10 11 mov si, offset str ;设置入口参数si 12 mov al, 2 ;设置入口参数al 13 call printStr 14 15 mov ah, 4ch 16 int 21h 17 18 printStr: 19 push bx 20 push cx 21 push si 22 push di 23 24 mov bx, 0b800H 25 mov es, bx 26 mov di, 0 27 s: mov cl, [si] 28 mov ch, 0 29 jcxz over 30 mov ch, al 31 mov es:[di], cx 32 inc si 33 add di, 2 34 jmp s 35 36 over: pop di 37 pop si 38 pop cx 39 pop bx 40 ret 41 42 code ends 43 end start
1 assume cs:code, ds:data 2 data segment 3 x dw 1984 4 str db 16 dup(0) 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 mov ax, x 12 mov di, offset str 13 call num2str 14 15 mov ah, 4ch 16 int 21h 17 18 num2str: 19 push ax 20 push bx 21 push cx 22 push dx 23 24 mov cx, 0 25 mov bl, 10 26 s1: 27 div bl 28 inc cx 29 mov dl, ah 30 push dx 31 mov ah, 0 32 cmp al, 0 33 jne s1 34 s2: 35 pop dx 36 or dl, 30h 37 mov [di], dl 38 inc di 39 loop s2 40 41 pop dx 42 pop cx 43 pop bx 44 pop ax 45 46 ret 47 code ends 48 end start
1 assume cs:code, ds:data 2 data segment 3 x dw 1984 4 str db 16 dup(0) 5 data ends 6 7 code segment 8 start: 9 mov ax, data 10 mov ds, ax 11 mov ax, x 12 mov di, offset str 13 call num2str 14 mov si, offset str 15 call printfstr 16 17 mov ah, 4ch 18 int 21h 19 20 num2str: 21 push ax 22 push bx 23 push cx 24 push dx 25 26 mov cx, 0 27 mov bl, 10 28 s1: 29 div bl 30 inc cx 31 mov dl, ah 32 push dx 33 mov ah, 0 34 cmp al, 0 35 jne s1 36 s2: 37 pop dx 38 or dl, 30h 39 mov [di], dl 40 inc di 41 loop s2 42 43 pop dx 44 pop cx 45 pop bx 46 pop ax 47 48 ret 49 50 printfstr: 51 push ax 52 push bx 53 push cx 54 push si 55 push di 56 57 mov ax,2 58 mov bx,0b800H 59 mov es,bx 60 mov di,0 61 s: mov cl,[si] 62 mov ch,0 63 jcxz over 64 mov ch,al 65 mov es:[di],cx 66 inc si 67 add di,2 68 jmp s 69 70 over: pop di 71 pop si 72 pop cx 73 pop bx 74 pop ax 75 ret 76 code ends 77 end start
1 assume cs:code, ds:data 2 data segment 3 str db 80 dup(?) 4 data ends 5 6 code segment 7 start: 8 mov ax, data 9 mov ds, ax 10 mov si, 0 11 12 s1: 13 mov ah, 1 14 int 21h 15 mov [si], al 16 cmp al, '#' 17 je next 18 inc si 19 jmp s1 20 next: 21 mov cx, si 22 mov si, 0 23 s2: mov ah, 2 24 mov dl, [si] 25 int 21h 26 inc si 27 loop s2 28 29 mov ah, 4ch 30 int 21h 31 code ends 32 end start
1 mov ah, 1 2 int 21h ; 出口参数为al, 从键盘输入的字符保存在al中
1 mov ah, 2 2 mov dl, ; ××是待输出的字符,或其ASCⅡ码值 3 int 21h
1 #include <stdio.h> 2 int sum(int, int); 3 int main() 4 { 5 int a = 2, b = 7, c; 6 c = sum(a, b); 7 return 0; 8 } 9 int sum(int x, int y) 10 { 11 return (x + y); 12 }
c = sum(a, b);
00DF13AC mov eax,dword ptr [b] // 把内存地址b中的双字型数据赋给eax
00DF13AF push eax //将eax入栈
00DF13B0 mov ecx,dword ptr [a]
00DF13B3 push ecx
00DF13B4 call sum (0DF1055h) // 通过call指令调用函数sum
00DF13B9 add esp,8
00DF13BC mov dword ptr [c],eax // 将结果存放在c中
return (x + y);
00DF140E mov eax,dword ptr [x]
00DF1411 add eax,dword ptr [y] // x,y相加后赋值给eax