鱼C论坛

 找回密码
 立即注册
查看: 3452|回复: 5

检测点10.4

[复制链接]
发表于 2012-7-31 23:43:07 | 显示全部楼层 |阅读模式
1鱼币
本帖最后由 丶Haw 于 2012-8-1 00:02 编辑

检测点10.4
下面的程序执行后,ax中的数值为多少?
内存地址   机器码        汇编指令       执行后情况
1000:0     b8 06 00      mov ax,6       ax=6,ip指向1000:3
1000:3     ff d0         call ax        pop ip,ip指向1000:6   这里的IP为什么是6?为什么不是下面说的先将该指令后的第一个字节偏移地址ip入栈
1000:5     40            inc ax
1000:6     58            mov bp,sp      bp=sp=fffeh  SP的值是从哪里来的?
                         add ax,[bp]    ax=[6+ds:(fffeh)]=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入栈?

最佳答案

查看完整内容

call 16位 reg相当于 push ip (这步是把该指令后的第一个字节偏移地址ip入栈,你说的没错,比如这题就是把call后面的指令的第一个字节偏移0005h入栈,这里题目没设栈段你就想它把ip存到了一个系统给的小房子里,但是这个小房子的地址我们没必要知道,以后pop一下就出来了) jump 16位reg (已经把ip的值保存下来了,就可以跳转到reg寄存器存储的地方去执行命令了,比如这题reg寄存器是ax,里面存的值是0006h,以后要回来ret一 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 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图 calldebug.png 只不过你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,[bp] ax=[6+dsfffeh)]=6+5=0bh 为什么 dsfffeh)的值是5

注意一下,bp默认的寄存器是ss哦,不是ds,是栈段寄存器。刚刚上面解释了,ss:0fffeh里面保存的值是ip,这个ip是call指令后的第一个字节的ip=0005h。

解释的不好。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2012-8-1 12:55:36 | 显示全部楼层

非常感谢 ,解释得很好,很强大!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2012-8-1 12:57:10 | 显示全部楼层
丶Haw 发表于 2012-8-1 12:55
非常感谢 ,解释得很好,很强大!

不谢。互助哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2017-2-22 19:10:22 | 显示全部楼层
学到了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-19 01:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表