实验4 汇编应用编程和c语言程序反汇编分析
四、实验结论
1. 实验任务1
源程序:
assume cs:code, ds:data data segment str db 'welcome to masm!' data ends code segment start: mov ax,0b800h;目标段地址 mov ds,ax mov bx,data;源段地址 mov es,bx mov cx,16 mov di,0 mov si,0720h;屏幕中间的位置的偏移地址 s: jcxz sss;如果cx为零跳转下一个循环 mov ax,es:[di] mov ds:[si],ax;将当前的字符复制给目标位置 mov byte ptr ds:[si+1],02h;给当前字符添加颜色属性 add si,2 inc di loop s sss: mov cx,16 mov di,0 mov si,07c0h s1: jcxz ss1 mov ax,es:[di] mov ds:[si],ax mov byte ptr ds:[si+1],24h add si,2 inc di loop s1 ss1: mov cx,16 mov di,0 mov si,0860h s2: jcxz ss2 mov ax,es:[di] mov ds:[si],ax mov byte ptr ds:[si+1],71h add si,2 inc di loop s2 ss2: mov ah,4ch int 21h code ends end start
我实现该任务是是用了暴力的三次循环来完成对屏幕显示区域地址的赋值操作,即每次更改当前目标的偏移地址,相应的赋值 操作也可用ASCII码来完成。
运行结果截图

2. 实验任务2
源程序:
assume cs:code, ds:data data segment str db 'another try', 0 data ends code segment start: mov ax, data mov ds, ax mov si, offset str mov al, 4 call printStr mov ah, 4ch int 21h printStr: push bx push cx push si push di mov bx, 0b800H mov es, bx mov di, 0 s: mov cl, [si] mov ch, 0 jcxz over mov ch, al mov es:[di], cx inc si add di, 2 jmp s over: pop di pop si pop cx pop bx ret code ends end start
运行结果截图

修改后运行结果截图

1) 目的是为了事先将寄存器入栈,在接下来的程序结束后将已经更改过的寄存器的值恢复到原来的值,这样便可以起到保护现场的作用。
2) 将数据段的当前字符复制到屏幕显示的目标地址中。
3. 实验任务3
子任务1
反汇编截图

子任务二
源代码
assume cs:code, ds:data data segment x dw 1234 str db 16 dup(0) data ends code segment start: mov ax, data mov ds, ax mov ax, x mov di, offset str call num2str mov si,offset str mov al,4 call printStr mov ah, 4ch int 21h num2str: push ax push bx push cx push dx mov cx, 0 mov bl, 10 s1: div bl inc cx mov dl, ah push dx mov ah, 0 cmp al, 0 jne s1 s2: pop dx or dl, 30h mov [di], dl inc di loop s2 pop dx pop cx pop bx pop ax ret printStr: push bx push cx push si push di mov bx, 0b800H mov es, bx mov di, 0 s: mov cl, [si] mov ch, 0 jcxz over mov ch, al mov es:[di], cx inc si add di, 2 jmp s over: pop di pop si pop cx pop bx ret code ends end start
运行测试截图


4. 实验任务4
源代码
assume cs:code, ds:data data segment str db 80 dup(?) data ends code segment start: mov ax, data mov ds, ax mov si, 0 s1: mov ah, 1 int 21h mov [si], al cmp al, '#' je next inc si jmp s1 next: mov cx, si mov si, 0 s2: mov ah, 2 mov dl, [si] int 21h inc si loop s2 mov ah, 4ch int 21h code ends end start
运行测试截图

1) 利用int 21h的一号子功能,将从键盘输入的字符保存到data段中,当判断输入为‘#’时,跳转到next段中,否则继续输入保存。
2) 将s1段中用于保存数据偏移地址的si寄存器作为循环次数,利用int 21h的2号子功能在屏幕上依次将输入的数据输出出来。
5.实验任务5
#include <stdio.h> int sum(int, int); int main() { int a = 2, b = 7, c; c = sum(a, b); return 0; } int sum(int x, int y) { return (x + y); }



通过观察分析可知,当进行函数调用的时候,对参数进行按自右向左的顺序,先存在寄存器中,利用寄存器进行入栈操作,然后通过call命令调用函数进入函数内部。在函数内部,执行具体的加法操作,将形参存储在寄存器中然后进行相关运算,最后通过ret指令返回。返回到主程序后将暂存运算结果的寄存器的值赋值给存储c变量的寄存器即完成了一次完整的函数调用。
五、实验总结
1.通过本次实验我了解并掌握了如何对屏幕显示区域进行赋值操作,并使得显示的字符属性按相应的要求设置。
2.学到了防止多次使用的寄存器在程序执行过程中被修改可以事先放入栈中保存。
3.熟悉了各种跳转指令的跳转原理和使用。
4.学到了int 21h的多个子功能。
5.通过对高级语言程序的反汇编进一步了解了高级语言函数的调用在汇编语言下是如何完成的,使我对高级语言的执行有了更深入的了解。
浙公网安备 33010602011771号