当前位置: 代码迷 >> 汇编语言 >> 王爽《编译语言》检测点10.5的疑问
  详细解决方案

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

热度:397   发布时间:2016-05-02 04:50:21.0
王爽《汇编语言》检测点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,压栈的两个返回地址也无用武之地。

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