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

四、实验结论

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码来完成。

运行结果截图

d34b21a890fdaee100928e2e7f759183.png

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

运行结果截图

32505994351419ae761259ecc2b92624.png

修改后运行结果截图

be9c87803aee4ded8377fb431def48b8.png

1) 目的是为了事先将寄存器入栈,在接下来的程序结束后将已经更改过的寄存器的值恢复到原来的值,这样便可以起到保护现场的作用。

2) 将数据段的当前字符复制到屏幕显示的目标地址中。

3. 实验任务3

子任务1

反汇编截图

06264fa9819431a452dc31e4e6084286.png

子任务二

源代码

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

运行测试截图

fecc9dd217a6ad357f4c94bc3aae71cd.png

72f40cf803df06011a51d58962a50698.png

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

运行测试截图

5990cc7583dcb654c20b6e33178fe312.png

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);

}

23e0c9b23b70d9abbfa4140cf01c9e47.png

859c05493d64b37a7eaec65f717feb73.png

23d6c000c3c7eb9dcc16fcf7577b8aa5.png

通过观察分析可知,当进行函数调用的时候,对参数进行按自右向左的顺序,先存在寄存器中,利用寄存器进行入栈操作,然后通过call命令调用函数进入函数内部。在函数内部,执行具体的加法操作,将形参存储在寄存器中然后进行相关运算,最后通过ret指令返回。返回到主程序后将暂存运算结果的寄存器的值赋值给存储c变量的寄存器即完成了一次完整的函数调用。

五、实验总结

1.通过本次实验我了解并掌握了如何对屏幕显示区域进行赋值操作,并使得显示的字符属性按相应的要求设置。

2.学到了防止多次使用的寄存器在程序执行过程中被修改可以事先放入栈中保存。

3.熟悉了各种跳转指令的跳转原理和使用。

4.学到了int 21h的多个子功能。

5.通过对高级语言程序的反汇编进一步了解了高级语言函数的调用在汇编语言下是如何完成的,使我对高级语言的执行有了更深入的了解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值