[Assembly Language] 实验4 汇编应用编程和c语言程序反汇编分析

Task1 在屏幕中间分别显示绿色、绿底红色、白底蓝色的字符串'welcome to masm!'

编写程序如下:

 1 assume cs:codesg, ds:datasg
 2 
 3 datasg segment
 4     db 'welcome to masm!';
 5     db 02H,24H,71H;
 6 datasg ends
 7 
 8 codesg segment
 9 start:
10     mov ax, datasg
11     mov ds, ax
12     mov ax, 0b800h
13     mov es, ax
14     mov di, 1984;初始偏移位置,第一行位置
15     
16     mov cx, 4;三行循环三次
17     mov bx, 0;从datasg的第一个位置开始
18 s1:    push cx;保存外层循环
19     mov cx,16;16个字符,循环16次
20     mov si,0;字符数据的偏移地址
21 s2:    mov al,ds:[si];字符样式
22     mov ah,ds:[bx+16];颜色样式
23     mov es:[di],ax;输出到指定地址
24     inc si;下一个字符指针
25     add di,2;下一个输出位置指针
26     loop s2
27     pop cx;
28     inc bx;切换下一个颜色
29     add di, 128;到下一行的起始位置
30     loop s1;
31     
32     mov ah,4ch;
33     int 21h
34 
35 codesg ends
36 end start

效果如下:

 

实现原理已注释在代码中。

 

Task2 编写子程序printStr,实现以指定颜色在屏幕上输出字符串,调用它,完成字符串输出

代码如下:

 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
10  
11     mov si, offset str12     mov al, 213     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     ret41  
42 code ends
43 end start

运行结果如下:

 

将第三行改成 str db 'another try', 0 ,第12行改成 mov al, 4,结果如下:

 

line19-22, line36-39,这组对称使用的push、pop,这样用的目的是为了将工作状态保存在栈中,当函数结束后,再从栈中恢复工作状态。这样可以确保调用函数前后对无关寄存器不产生副作用。(原理与C语言函数开栈类似)

line30的功能参考task1,即将cx中带颜色样式的字符保存到显示器对应地址,相当于输出到显示器中。

 

Task3 使用任意文本编辑器,录入汇编源程序task3.asm

代码如下:

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     str db 'another try', 0
 5 data ends
 6 
 7 code segment
 8 start:
 9     mov ax, data
10     mov ds, ax
11     mov si, offset str
12     mov al, 4
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 s:    mov cl, [si]
27     mov ch, 0
28     jcxz over
29     mov ch, al
30     mov es:[di], cx
31     inc si
32     add di, 2
33     jmp s
34     
35 over:
36     pop di
37     pop si
38     pop cx
39     pop bx
40     ret
41 
42 code ends
43 end start

子任务1,运行到程序结束前,查看ds里的数据:

 

子任务2,加入输出到屏幕的子函数,代码如下:

 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         mov al, 2
16         mov di, 0
17         call printStr
18  
19         mov ah, 4ch
20         int 21h
21  
22 num2str:
23         push ax
24         push bx
25         push cx
26         push dx
27          
28         mov cx, 0
29         mov bl, 10
30 s1:     
31         div bl
32         inc cx
33         mov dl, ah
34         push dx
35         mov ah, 0
36         cmp al, 0
37         jne s1
38 s2:       
39         pop dx
40         or dl, 30h
41         mov [di], dl
42         inc di
43         loop s2
44          
45         pop dx
46         pop cx
47         pop bx
48         pop ax
49  
50         ret
51 
52 printStr:
53       push bx
54       push cx
55       push si
56       push di
57     
58       mov bx, 0b800H
59       mov es, bx
60 s:     mov cl, [si]
61       mov ch, 0
62       jcxz over
63       mov ch, al
64       mov es:[di], cx
65       inc si
66       add di, 2
67       jmp s
68     
69 over:
70       pop di
71       pop si
72       pop cx
73       pop bx
74       ret
75 
76 code ends
77 end start

运行结果如下:

 

 

Task4 使用任意文本编辑器,录入汇编源程序task4.asm

 代码如下:

 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

运行结果如下:

 

 

line12-line19 将输入的字符利用si作为指针保存到ds中,并判断是否为#,如果是#则结束输入,否则继续读入新的字符。

line21-line27 将保存在ds中的字符逐个输出到#后面。

Task5 在visual studio集成环境中,编写一个简单的包含有函数调用的c程序,并查看汇编

代码如下:

 1 #include <stdio.h>
 2 int sum(int, int);
 3 
 4 int main() {
 5     int a = 2, b = 7, c;
 6 
 7     c = sum(a, b);
 8 
 9     return 0;
10 }
11 
12 int sum(int x, int y) {
13     return (x + y);
14 }

 

在line7、line13插入断点,查看汇编:

 

高级语言调用函数主要使用call指令,寄存器eax,ecx等,以及一个工作栈完成。

函数传参的原理,即先保存各种寄存器的工作状态,再将参数压入到栈中,待跳转到函数所在地址开始执行时,先取出栈中的参数,再执行。

函数返回后,各个寄存器的状态从栈中恢复。

 

posted @ 2020-12-17 21:02  Kusunoki  阅读(153)  评论(1)    收藏  举报