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

1. 实验任务1

教材「实验9 根据材料编程」(P187-189)

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

 1 assume cs:code, ds:data
 2 data segment
 3     db 'welcome to masm!'
 4     db 00000010B,00100100B,01110001B
 5 data ends
 6 
 7 code segment
 8 start:
 9     mov ax, data
10     mov ds, ax
11 
12     mov ax, 0b800H
13     mov es, ax
14 
15     mov cx,3
16     mov bx,0
17     mov di, 1760+64
18 
19 s0:    push cx
20     mov cx, 16
21     mov si, 0
22 
23 s1:    mov al, [si]
24     mov es:[di], al
25     mov al, [16+bx]
26     mov es:[di+1], al
27     inc si
28     add di, 2
29     loop s1
30 
31     pop cx
32     inc bx
33     add di,128
34     loop s0
35 
36     mov ah, 4ch
37     int 21h
38 code ends
39 end start
task4_1.asm

 

  •  屏幕中间对应的显存位置的计算:在80*25彩色字符模式下,显示器可以显示25行,每行80个字符,即160个字节

    所以中间行是11~13行;中间列是64~95

  • data的前16个字节存放字符信息,后面三个是颜色信息

    00000010B,  绿色

    00100100B,  绿底红色

    01110001B,  白底蓝色

  • 主要是两个循环,内循环每次输入16个字符,外循环则控制3次字符串的输出,在外循环选择颜色信息

2. 实验任务2

编写子程序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 str
12     mov al, 2
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
task4_2.asm

把line3改为:

str db 'another try', 0

把line12改为:

mov al, 4

  •  line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么?

    将寄存器的值存入栈中,可暂时释放寄存器,用于其他数据存储,再依次出栈,防止数据错乱

  • line30的功能是什么?

    把数据放入显示缓冲区,低字节是字符信息,高字节是颜色信息

3. 实验任务3

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

 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
task4_3.asm

子任务1

对task3.asm进行汇编、链接,得到可执行程序后,在debug中使用u命令反汇编,使用g命令执行 到line15(程序退出之前),使用d命令查看数据段内容,观察是否把转换后的数字字符串'1984'存放 在数据段中str标号后面的单元。

 子任务2

对task3.asm源代码进行修改、完善,把task2.asm中用于输出以0结尾的字符串的子程序加进来, 实现对转换后的字符串进行输出。

 1 assume cs:code, ds:data
 2 data segment
 3         x dw 1999
 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 si,offset str
16     mov al,2
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 printStr:
52     push bx
53     push cx
54     push si
55     push di
56 
57 
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     ret
75 code ends
76 end start
task4_3_.asm

4. 实验任务4

 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
task4_4.asm

  • line12-19实现的功能是?

    从键盘输入字符,直到遇到‘#’则跳到next段执行,否则一直循环

    cmp是比较指令,执行后对标志寄存器产生影响

    je跳转函数,比较后相等则跳转

  • line21-27实现的功能是?

    使用int 21h的2号子功能,在屏幕输出单个字符

    mov cx, si  ;字符串长度即为要循环的次数

5. 实验任务5

在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 }

高级语言中参数传递,从汇编的角度是如何传递的,返回值是如何返回的;多个参数的入栈顺序 是什么样的;函数调用栈,等

 调用函数时,先把参数压入栈,然后利用call指令将函数返回地址入栈。且如上图所示,b先入栈,a再入栈。

call指令执行时自动将函数返回地址入栈,之后转到sum函数开始执行此函数。最后把返回值赋给c

在函数体内,进行各寄存器初始化,将oxcccH存入ax寄存器。然后把x的值移入ax寄存器,再与bx相加。也就解释了主函数部分把ax寄存器的值送给c

原文地址:https://www.cnblogs.com/zuiyankh/p/14142470.html