四、实验结论
1. 实验任务1
源程序:
assume cs:code, ds:data
data segmentstr db 'welcome to masm!'data ends
code segmentstart:
movax,0b800h;目标段地址movds,axmovbx,data;源段地址moves,bxmov cx,16
mov di,0
movsi,0720h;屏幕中间的位置的偏移地址s: jcxzsss;如果cx为零跳转下一个循环mov ax,es:[di]mov ds:[si],ax;将当前的字符复制给目标位置mov byte ptr ds:[si+1],02h;给当前字符添加颜色属性add si,2
incdi
loop ssss: mov cx,16
mov di,0
movsi,07c0hs1: jcxzss1mov ax,es:[di]mov ds:[si],axmov byte ptr ds:[si+1],24hadd si,2
incdi
loop s1ss1: mov cx,16
mov di,0
movsi,0860hs2: jcxzss2mov ax,es:[di]mov ds:[si],axmov byte ptr ds:[si+1],71hadd si,2
incdi
loop s2ss2: movah,4chint21h
code ends
end start
我实现该任务是是用了暴力的三次循环来完成对屏幕显示区域地址的赋值操作,即每次更改当前目标的偏移地址,相应的赋值 操作也可用ASCII码来完成。
运行结果截图
2. 实验任务2
源程序:
assume cs:code, ds:data
data segmentstr db 'another try', 0data ends
code segmentstart:
movax, datamovds, axmov si, offset str
mov al, 4
callprintStrmovah, 4chint21hprintStr:
pushbxpushcxpushsipushdimovbx, 0b800Hmoves, bxmov di, 0
s: movcl, [si]mov ch, 0
jcxzovermovch, almov es:[di], cxincsiadd di, 2
jmpsover: popdipopsipopcxpopbxretcode ends
end start
运行结果截图
修改后运行结果截图
1) 目的是为了事先将寄存器入栈,在接下来的程序结束后将已经更改过的寄存器的值恢复到原来的值,这样便可以起到保护现场的作用。
2) 将数据段的当前字符复制到屏幕显示的目标地址中。
3. 实验任务3
子任务1
反汇编截图
子任务二
源代码
assume cs:code, ds:data
data segment
x dw1234
str db 16 dup(0)
data ends
code segmentstart:
movax, datamovds, axmovax, xmov di, offset str
callnum2strmov si,offset str
mov al,4
callprintStrmovah, 4chint21hnum2str:
pushaxpushbxpushcxpushdxmov cx, 0
mov bl, 10
s1:
divblinccxmovdl, ahpushdxmov ah, 0
cmp al, 0
jnes1s2:
popdxordl, 30hmov[di], dlincdi
loop s2popdxpopcxpopbxpopaxret
printStr: pushbxpushcxpushsipushdimovbx, 0b800Hmoves, bxmov di, 0
s: movcl, [si]mov ch, 0
jcxzovermovch, almov es:[di], cxincsiadd di, 2
jmpsover: popdipopsipopcxpopbxretcode ends
end start
运行测试截图
4. 实验任务4
源代码
assume cs:code, ds:data
data segmentstr db 80dup(?)
data ends
code segmentstart:
movax, datamovds, axmov si, 0
s1:
mov ah, 1
int21hmov[si], alcmp al, '#'
jenextincsijmps1next:
movcx, simov si, 0
s2: mov ah, 2
movdl, [si]int21hincsi
loop s2movah, 4chint21h
code ends
end start
运行测试截图
1) 利用int 21h的一号子功能,将从键盘输入的字符保存到data段中,当判断输入为‘#’时,跳转到next段中,否则继续输入保存。
2) 将s1段中用于保存数据偏移地址的si寄存器作为循环次数,利用int 21h的2号子功能在屏幕上依次将输入的数据输出出来。
5.实验任务5
#include
int sum(int, int);intmain() {int a = 2, b = 7, c;
c=sum(a, b);return 0;
}int sum(int x, inty) {return (x +y);
}
通过观察分析可知,当进行函数调用的时候,对参数进行按自右向左的顺序,先存在寄存器中,利用寄存器进行入栈操作,然后通过call命令调用函数进入函数内部。在函数内部,执行具体的加法操作,将形参存储在寄存器中然后进行相关运算,最后通过ret指令返回。返回到主程序后将暂存运算结果的寄存器的值赋值给存储c变量的寄存器即完成了一次完整的函数调用。
五、实验总结
1.通过本次实验我了解并掌握了如何对屏幕显示区域进行赋值操作,并使得显示的字符属性按相应的要求设置。
2.学到了防止多次使用的寄存器在程序执行过程中被修改可以事先放入栈中保存。
3.熟悉了各种跳转指令的跳转原理和使用。
4.学到了int 21h的多个子功能。
5.通过对高级语言程序的反汇编进一步了解了高级语言函数的调用在汇编语言下是如何完成的,使我对高级语言的执行有了更深入的了解。