丶Haw 发表于 2012-7-31 23:43:07

检测点10.4

本帖最后由 丶Haw 于 2012-8-1 00:02 编辑

检测点10.4下面的程序执行后,ax中的数值为多少?内存地址   机器码      汇编指令       执行后情况1000:0   b8 06 00      mov ax,6       ax=6,ip指向1000:31000:3   ff d0         call ax      pop ip,ip指向1000:6   这里的IP为什么是6?为什么不是下面说的先将该指令后的第一个字节偏移地址ip入栈1000:5   40            inc ax1000:6   58            mov bp,sp      bp=sp=fffehSP的值是从哪里来的?                         add ax,    ax==6+5=0bh   为什么 ds:(fffeh)的值是5?用debug进行跟踪确认,“call ax(16位reg)”是先将该指令后的第一个字节偏移地址ip入栈,再转到偏移地址为ax(16位reg)处执行指令。 刚才看到一帖子,call ax的解如下,我觉得不对,call ax         ;将下一条指令的IP=0005压入栈,此时栈顶应该是sp=FFFE ,                因为AX=0006,然后跳转(位移)到1000:0006,
这里跳到1000:0006 是因为 ax=0006? 如果ax=ffff,那不是直接跳到1000:ffff?   ip不是call ax(16位reg)”是先将该指令后的第一个字节偏移地址ip入栈?

lukelqz 发表于 2012-7-31 23:43:08

call 16位 reg相当于
push ip (这步是把该指令后的第一个字节偏移地址ip入栈,你说的没错,比如这题就是把call后面的指令的第一个字节偏移0005h入栈,这里题目没设栈段你就想它把ip存到了一个系统给的小房子里,但是这个小房子的地址我们没必要知道,以后pop一下就出来了)
jump 16位reg (已经把ip的值保存下来了,就可以跳转到reg寄存器存储的地方去执行命令了,比如这题reg寄存器是ax,里面存的值是0006h,以后要回来ret一下就好了。)

你的第一个疑问:

1000:3   ff d0         call ax      pop ip,ip指向1000:6   这里的IP为什么是6?为什么不是下面说的先将该指令后的第一个字节偏移地址ip入栈

解释是:call是有两个步骤的,先保存,再跳转,先把ip=0005h,保存入栈。然后再跳转到,ax寄存器里面值,就是把ip修改为ax里面的值,如果ax=0ffffh,那么call完后,系统确实要跳到ip=ffffh处执行命令哦给你看我刚刚的debug图只不过你call完后你能不能回来呢?呵呵。也就是说你不知道ip=ffffh后指令是啥了。

你的第二个疑问:
1000:6 58 mov bp,sp bp=sp=fffeh SP的值是从哪里来的?

你的这个疑问明显是对栈不了解啊。因为刚刚不是call了吗?call的第一步就是把call指令后的第一个字节偏移地址ip入栈啊。入栈肯定要知道栈顶在哪儿,也就是sp呢?sp开始系统默认是0000h,入栈也是两步哦。sp先减2(0-2=0fffeh),然后把ip的值存入ss:sp 指向的内存单元,ss:sp此时指向新栈顶。也就是说此时ss:0fffeh里面保存的值是ip(刚刚说的ip=0005h)。这步执行完了,就是bp=sp=0fffeh。这段看不懂的话,去看书P60。

你的第三个疑问:
add ax, ax==6+5=0bh 为什么 dsfffeh)的值是5
注意一下,bp默认的寄存器是ss哦,不是ds,是栈段寄存器。刚刚上面解释了,ss:0fffeh里面保存的值是ip,这个ip是call指令后的第一个字节的ip=0005h。

{:5_96:}解释的不好。

丶Haw 发表于 2012-8-1 12:55:36

lukelqz 发表于 2012-7-31 23:43 static/image/common/back.gif
call 16位 reg相当于
push ip (这步是把该指令后的第一个字节偏移地址ip入栈,你说的没错,比如这题就是 ...

非常感谢 ,解释得很好,很强大!

lukelqz 发表于 2012-8-1 12:57:10

丶Haw 发表于 2012-8-1 12:55 static/image/common/back.gif
非常感谢 ,解释得很好,很强大!

{:5_102:}不谢。互助哈

哈喇子淌一手 发表于 2012-8-28 16:51:15

1000:3   ff d0         call ax      pop ip,ip指向1000:6
你 看答案了吧,答案都有写错了,是PUSH ip,push的时候sp由0000指向fffeh,然后把现在ip内的值,即下一行代码0005存入1000:fffe中,存入后就直接跳到ax的偏移中去,即下一行代码"mov bp,sp"


而sp由于push了一下,所以变为-2,即补码为fffe,下一行意思是把1000:fffe内的值,即之前push的ip值与0005相加,即为000bh

低手莫怪 发表于 2017-2-22 19:10:22

学到了
页: [1]
查看完整版本: 检测点10.4