[Chapter 10] - [检测点10.5]

检测点10.5

(1)

  • 这里要注意,程序将stack段同时与ss与ds进行了关联,也就是此段既被当作栈使用,同时被当作数据段使用

  • call word ptr ds:[0EH] 的理解

    • IP指向此call指令时,call指令被读取进CPU的指令缓存器

    • IP立第即指向了call指令的后的下一条指令,即本程序中的第1条 inc ax

    • 然后,指令缓冲器中的call指令开始正式被执行

    • 第1步动作就是push IP,即,将第1条 inc ax的偏移地址,压入栈中,栈顶元素的地址为0EH,共占用2个单元

      • 这里有几点需要注意,首先,push,pop都是以word为单位进行操作,在8086CPU中是16位,所以是2个单元
      • push动作的第一步,就是将SP=SP-2,即栈指针回退2位,指向新的栈顶元素
      • push动作的第二步,就是将IP值,存放进栈顶元素中,此时栈顶元素变为当前IP的值,即第1条inc ax指令的地址
    • 完成入栈后,接下来就是跳转的动作,是从目标内存单元中,读取指定的1个word长度的值作为地址,完成从当前IP跳转到这个地址的动作。从word的使用上也可以得知,读取的是16位数据,对应的也就是jmp near ptr s/单元地址

    • 而数据段的ds:[0EH]正好是栈段中的栈顶元素,所以最终读取出来的目标跳转地址,就是原来的IP,也正是第1条inc ax自己的偏移地址

    • 所以,call指令被执行完毕后,IP=原IP,而原IP就是第1条inc ax,于是开始从inc ax开始执行

    • 在这之前,ax值被 mov ax, 0 变更为0,所以经过3次 inc ax 操作后,ax值结果为3

(2)

  • 这里故意对解题者设置了迷惑,即,故意定义了data段,却将data段作为事实上的栈使用

  • mov word ptr ss:[0],offset s 执行后,是将s的 偏移地址EA 传递给了 data段 的前2个单元,此时data段也就是栈的内容如下:

在这里插入图片描述

  • mov ss:[2],cs 执行后,data段的第2,3两个单元中,存储了cs的值,data段变为:

在这里插入图片描述

  • call dword ptr ss:[0] 的执行过程如下:

    • 当IP指向call指令所在内存地址时,先将call指令传送到CPU指令缓冲器,然后IP马上指向它的下一条指令,即nop的地址,此时IP值变为nop的EA。然后执行入栈的动作

    • 首先栈指针回退4个单元,指向0CH

    • 然后向栈中分别push进2个数据,先入栈CS的值,再入栈IP的值,入栈完成后,data段变为:

在这里插入图片描述

  • 再接下来就是跳转。先从call指令中搭配的内存单元 ss:[0] 中读取目标地址,读取的结果是 s的EA。然后跳转到目标地址 s 处。从这里可以看出,从call指令语句的地址,越过nop,直达标号s的地址了

  • s处第1条指令,mov ax,offset s 是将s的EA,给到ax

  • sub ax,ss:[0cH],参考上图,是将 ax的值即 s的EA,减去 ss:[0cH]中的值,即 nop的EA,因二者相邻,差值也就是 nop 所占的数据长度,而 nop的长度为 1 byte,这是常识,所以,结果就是ax的值变成了1

  • mov bx,cs 执行后,(bx)=(cs)

  • sub bx,ss:[0eH],是从bx中减去cs的值,即 (cs)-(cs)=0,所以此条指令后,bx=0

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值