实验4 汇编应用编程和c语言程序反汇编分析
四、实验结论
1. 实验任务1
task1.asm的源代码如下:
1 assume cs: code,ds: data 2 3 data segment 4 db 119,101,108,99,111,109,101,32,116,111,32,109,97,115,109,33 5 data ends 6 7 code segment 8 start: 9 mov ax, 0b800h 10 mov ds, ax 11 mov bx, data 12 mov es, bx 13 14 mov di, 0 15 mov bx, 1984 16 mov cx, 16 17 s0: 18 mov al, es:[di] 19 20 mov [bx], al 21 inc bx 22 mov word ptr [bx], 2 23 inc bx 24 25 inc di 26 loop s0 27 28 mov di, 0 29 mov bx, 2144 30 mov cx, 16 31 s1: 32 mov al, es:[di] 33 34 mov [bx], al 35 inc bx 36 mov word ptr [bx], 36 37 inc bx 38 39 inc di 40 loop s1 41 42 mov di, 0 43 mov bx, 2304 44 mov cx, 16 45 s2: 46 mov al, es:[di] 47 48 mov [bx], al 49 inc bx 50 mov word ptr [bx], 113 51 inc bx 52 53 inc di 54 loop s2 55 56 mov ax, 4c00h 57 int 21h 58 59 code ends 60 end start
程序运行结果如下:
2. 实验任务2
task2.asm的源代码如下:
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
编译运行结果如下:
将源程序中的line3改为
str db ‘another try’ , 0
并将源程序的line12改为
mov al , 4
重新调试程序,运行结果如下:
问题①:line19-22, line36-39,这组对称使用的push、pop,这样用的目的是什么?
这一组push、pop指令可以在程序调用call指令时,通过寄存器保存当前的寄存器信息。在子程序运行完毕,调用ret指令后,可以恢复之前上层程序的上下文状态。
问题②:line30的功能是什么?
将当前内存中字符的值和属性等存入彩色字符模式显示缓冲区。
3. 实验任务3
task3.asm的修改后的程序如下:
1 assume cs:code, ds:data 2 data segment 3 str db 'another 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, 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 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
运用debug指令调试程序:
使用d命令查看数据段的数据,1984已经转换为字符串。
对task3.asm源代码进行修改、完善,把task2.asm中用于输出以0结尾的字符串的子程序加进来, 实现对转换后的字符串进行输出。
运行测试截图:
把task3.asm源代码中,line3中整数改成0~2559之间的任意数值,运行测试,观察结果。
运行测试截图:
4. 实验任务4
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-19实现的功能是?
通过21号中断读入输进去的所有字符,并通过si的递增管理存放字符的内存单元位置。当通过比较发现输入字符为 ‘#’ 时, 跳转至输出程序部分。
问题②:line21-27实现的功能是?
通过循环指令,利用21号中断的2号功能输出之前存放的字符。
5. 实验任务5
c程序源代码:
1 #include <stdio.h>
2 int sum(int, int);
3 int main() {
4 int a = 2, b = 7, c;
5 c = sum(a, b);
6 return 0;
7 }
8
9 int sum(int x, int y) {
10 return (x + y);
11 }
分别在line5和line10添加断点。
反汇编代码如下:
经分析,由line7-8我们可以发现,函数参数的入栈顺序是从右向左的,并且以内存单元的方式复制给函数内寄存器edx、eax,作为值传递使用。
返回值由寄存器rbp返回。