读书人

王爽《编译语言》检测点10.5的疑问

发布时间: 2013-09-05 16:02:07 作者: rapoo

王爽《汇编语言》检测点10.5的疑问

assume cs:code

stack segment
dw 8 dup (0)
stack ends

code segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ds,ax
mov ax,0
call word ptr ds:[0EH]
inc ax
inc ax
inc ax

mov ax,4c00h
int 21h

code ends
end start

我用debug执行上面的代码,到call指令之前我看了一下ss:0e到0f之间的数据为77,0e。当call执行完了ss:0e到0f之间的数据变为11,00没错,但是现在call指令push ip后,ip的数据再会改为ds:[0EH]内存处的数据,因为ds==ss,所以ds:[0EH]即为ss:[0EH],但是ss:[0EH]处的数据为77,0e, 但是我d查看内存ip为什么是3302,而不是0e77或者是0011呢?
请高手们多多指点,谢谢了!
[解决办法]
这个代码不是这么看的,更不能用 debug 来单步什么的,而应该是单纯的静态分析,主要是针对堆栈的作用来的。如果用 debug 单步什么的话,会给堆栈写入内容导致 call 去了错误的地方,失去了这个代码设计的本来意义。
call word ptr ds:[0EH],正常运行时 ds:[0Eh] 应该是 00 00 吧,所以其实这个 call 应该是转移到 start: 处,并将返回地址及其下一指令地址压栈在 ds:[0Eh] 处;当程序再次有 start: 运行到这个 call 指令时,由于 ds:[0Eh] 处为其后的 inc ax 指令的地址,所以会跳到这个 inc ax 指令接着向下运行,并再次将返回地址压栈到 ds:[0Ch] 处(尽管已经没有意义了);这么运行到最后的程序结束返回 DOS,压栈的两个返回地址也无用武之地。

窃以为,这样的题目设计,有点儿小聪明,但也仅仅是小聪明,并不怎么适合初期的,没有必要在这上面耽搁多少的时间。

读书人网 >汇编语言

热点推荐