检测点10.2有些郁闷 求大牛!
下面的程序执行后,ax中的数值为多少?内存地址 机器码 汇编指令 1000:0 b8 00 00 mov ax,0 1000:3 e8 01 00 call s 1000:6 40 inc ax1000:7 58 s:pop ax执行完mov ax, 0后IP是3,根据甲鱼老师的公式标号处地址-call指令后的第一个字节=算出偏移量是6 ,call指令执行有2个操作 将当前IP或CS IP压栈,也就是说 先将cs压栈再将IP压栈,最上面的是当前的IP ,call指令处的IP是3将这个数据弹进ax 也只能是3怎么成6了 请详细解释下! destiny 发表于 2012-9-5 10:06 static/image/common/back.gif
1. (sp)=(sp)-2
((ss)*16+(sp))=(ip)
2. (ip)=(ip)+16位位移
(ip)=(ip)+16位位移16位位移由编译程序时在编译时算出,所以call s 在加入指令缓冲器时 ip=6,执行jmp near ptr 标号(这时ip=7) ,pop ax=6 呵呵 楼主你好~
问题: 你认为ax 是3 ,但是答案却是6。 那为什么是6呢?
分析: 首先,我要纠正你一个小小的混乱哦~
第一个:cpu执行 call 时, 先将 sp减二 (sp = sp-2) , 然后 将ip 入栈 ( push ip ) , 在转移( jmp near ptr) 这里你有个 知识点搞混了。 就是 如果是 call 标号。那么他是实现近转移,所以,就是 ip入栈, 而call far ptr才是实现段间转移是将当前ICS。 IP压栈
第二个: 就是cpu执行过程。
假设这时cpu的cs = 1000 , ip =3也就是指向 1000:3这个内存单元, 那么cpu首先通过地址总线,进入内存的1000:3, 在通过 控制总线,要求读这个内存单元(1000:3)的命令.然后通过 数据总线把e8 01 00(call s)这个指令 发给cpu,而cpu接到后,在发给指令缓冲器里,这是 ip = ip + 指令长度。( 提示, 这时还没执行 call s),然后执行 calls 这是 把ip 入栈。 (而这时的 ip = 6,因为前面说过ip = ip + 指令长度) 。 所以 执行 pop ax时 ax = 6
好了问题我以说明了。如果有哪些说的地方你认为不好(或有误), 请给我联系我, 我将好好改正。
886~ 我回复后查看发现 call far ptr标号, 漏了个标号。真是不好意思 梦幻羽羽 发表于 2012-9-4 19:20 static/image/common/back.gif
呵呵 楼主你好~
问题: 你认为ax 是3 ,但是答案却是6。 那为什么是6呢?
1. (sp)=(sp)-2
((ss)*16+(sp))=(ip)
2. (ip)=(ip)+16位位移
执行完mov ax, 0 是1000:3然后执行完call s也就执行了2个字节 这个时候IP指向了6
因为是跳转 所以ip+位移等于7 但是有一个问题就是 将IP入栈时候是(ip)=(ip)+16位位移
加过16位位移的IP入栈,还是执行完call指令后当前的IP入栈 视频里没有讲的细致 所以一直困惑在这里了
destiny 发表于 2012-9-5 10:06 static/image/common/back.gif
1. (sp)=(sp)-2
((ss)*16+(sp))=(ip)
2. (ip)=(ip)+16位位移
还是这个写的详细啊,3楼写了很多,但是有点看不懂 9天 发表于 2013-8-12 23:25 static/image/common/back.gif
还是这个写的详细啊,3楼写了很多,但是有点看不懂
慢慢就理解了 。刚开始也郁闷了一会 看不懂!!!!:sweat::sweat::sweat::sweat::sweat:
页:
[1]