毁掉自己的汇编程序

下午的上机课,有位同学写的程序死了。她百思不得其解。 

我看了几遍程序,没有发现问题。 

多次观察后,发现程序修改数据时,由于循环次数错误地设多了,以致于改到了代码段——代码段的指令于是被当作数据改掉了,而此处的数据,当然它仍然还要被当作指令执行,恰好对应了wait指令!于是,程序进入了等待…… 

那程序到底有没有问题?我看的程序没有问题,但运行的,却是老版本的.exe。开始时,源程序是错误的,她修改后,却没有再编译、接连!唉,这样的错也能犯?难为我当教师的了。麻子不叫麻子,叫什么来着? 

按下这个不表,想给大家展示能毁掉自己的奇葩代码。为简单化,我不再用她当时调试的程序,而是设计一个能说明问题的错误程序,把事情说清楚,大家也见识一下就行了。 

我要编的程序,其任务是:将数据区中的所有数据,变为其2倍并存储在原处。阅读下面的有逻辑错误的程序:

assume cs:codesg,ds:datasg
datasg segment
dw 1,2,3,4,5,6,7,8
datasg ends

codesg segment
start: mov ax, datasg
mov ds, ax
mov si, 0
mov cx, 16 ;这儿应该是8,修改8个字,但错误地写成16了
s: mov ax, [si]
add ax, ax
mov [si], ax
add si, 2
loop s

mov ax,4c00h
int 21h
codesg ends
end start

把连接好的程序用debug装入内存观察: 

(图1) 

可见,数据从物理地址076A0H处开始,一共同8个字,由1到8;从076B0处始,是代码!图1中,用d命令看到的076B0处的值与用u命令看到的,是一样的值,只不过,前者被当作数据,后者被当作指令。内存中的数据就是那样的,到底是数据还是指令,取决于我们要将它当作什么。 

下面我们执行程序。 

我先揭晓了迷底,这个程序就是循环次数设错了。前8次的循环,完成的是任务中要求的事情,后8次循环,彻底的捣乱。 

用g命令和t命令交替,让循环执行8次: 

 

(图2) 

执行8次后,是这样的: 

 

(图3) 

注意:由(DS)=076AH, (SI)=0010H,(CS)=076BH,当再执行mov [si], ax指令时,修改的就是代码了!程序在毁掉自己! 

我们将循环再执行3次: 

 

(图4) 

再用d命令和u命令观察: 

 

(图5) 

快对照图2!看到了吗?076B0H处的mov ax, 076A呢?076B3H处的mov ds, ax呢?现在的代码已经被改的面目全非! 

再用t和g执行两次: 

 

(图6) 

江山已经破败到如此境地,无法收拾了!

 

好了,毁掉自己的汇编程序演示到此。说点什么。 

这种情况,放在高级语言中很难发生。在操作系统尽责的内存管理下,在各种机制约束下,程序安全地存储、运行。 

然而,汇编语言就这么任性! 

这需要我们这些专业人士要对底层熟悉,有足够的敏感不犯这些错误,当然也要有足够的职业道德,不用这种手段去搞破坏。 

 

当这种问题就要发生,我们还需要用debug之类的底层调试工具,找出bug,使之曝光于天下! 

自豪吧,小猿们!

永不止步步 发表于04-20 10:00 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67417个|学分:382741个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号