鱼C论坛

 找回密码
 立即注册
查看: 3502|回复: 11

[汇编作业] 关于甲鱼老师讲的第十章call指令和检测点10.2的问题

[复制链接]
发表于 2016-12-15 11:39:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
刚在学习小甲鱼老师的汇编视频,看到第十章call指令,讲的是cpu执行call指令时,进行两步操作:1、将当前的ip或cs和ip压入栈中;2、转移(jmp)。
本人认为老师讲的将当前的ip压入栈中这样说不恰当,应该是IP的值先变成call指令后的第一个字节的地址,然后才被压入栈中。然而老师在讲后边call和ret指令时,又强调了ip指向了call下一条指令,再将ip入栈。
这样就给很多初学汇编的同学造成了误解(包括我本人),以为两种指令的ip入栈不同,导致很多同学发帖问检测点10.2的答案ax的值为什么是6,表示不懂。以下为检测点10.2

下面的程序执行后,ax中的数值为多少?

内存地址    机器码      汇编指令     执行后情况

1000:0     b8 00 00     mov ax,0     ax=0 ip指向1000:3

1000:3     e8 01 00     call s       pop ip ip指向1000:7

1000:6     40           inc ax

1000:7     58         s:pop ax                 ax=6


现在没搞懂的同学应该知道为什么是6了吧。

这只是我本人的理解,不知道是否正确,说错的地方望大家给我指正。如果正确也希望能帮助大家走出误区,解决检测点10.2这道题目,谢谢!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-12-15 12:46:20 | 显示全部楼层
本帖最后由 兰陵月 于 2016-12-15 13:04 编辑

"本人认为老师讲的将当前的ip压入栈中这样说不恰当,应该是IP的值先变成call指令后的第一个字节的地址,然后才被压入栈中。然而老师在讲后边call和ret指令时,又强调了ip指向了call下一条指令,再将ip入栈。"

你上述的理解是错误~CPU运行指令的步骤不知道你是否还记得,
CPU执行指令的步骤:
1、读入当前指令;
2、IP=IP+1
3、执行第1步已经读入的指令。

所以说当读入CALL指令那一行时,IP指针就已经自动指向了CALL的下面一条指令,因此执行CALL指令的时候,直接压入IP就是了,因为此时的IP就已经指向了下一条指令。

不知道解释得是否正确,请批评指正~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-15 12:52:19 | 显示全部楼层
下面的程序执行后,ax中的数值为多少?

内存地址    机器码      汇编指令     执行后情况

1000:0     b8 00 00     mov ax,0     ax=0 ip指向1000:3

1000:3     e8 01 00     call s       读入此指令时,IP偏移为6,将偏移6压入栈,转到标号s执行。

1000:6     40           inc ax

1000:7     58         s:pop ax         弹出栈,因为压入的是6,所以AX结果为6,因为没有RET指令,因此IP不会跳转到1000:6处执行,将会直接执行s:pop ax后面的语句,1000:6将被直接跳过。

评分

参与人数 1荣誉 +3 鱼币 +5 收起 理由
ArmandXiao + 3 + 5

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-12-15 15:40:30 | 显示全部楼层
兰陵月 发表于 2016-12-15 12:52
下面的程序执行后,ax中的数值为多少?

内存地址    机器码      汇编指令     执行后情况

你2楼说的是正确的,但是3楼说的ip偏移地址为6,这里是错误的,老师讲过 e8 01 00 此处机器码的0001就是偏移地址,此偏移地址是由标号s处的地址(7)-call指令后的第一个字节地址(6)而得来的。     通过学习我是这样理解的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-12-15 15:48:05 | 显示全部楼层
兰陵月 发表于 2016-12-15 12:46
"本人认为老师讲的将当前的ip压入栈中这样说不恰当,应该是IP的值先变成call指令后的第一个字节的地址,然 ...

你说的这里我不太记得了,但是你说ip=ip+1,我觉得不应该加1,加的应该是这条指令的所占字节数,得出来的就是下条指令的地址,这样就和我说的是一样的了。按你说的ip+1,如果这条指令占3个字节,即使ip+1,得出来的还是在这条指令中的位置,这样cpu执行下条指令时就会出错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 09:47:59 | 显示全部楼层
王小2 发表于 2016-12-15 15:48
你说的这里我不太记得了,但是你说ip=ip+1,我觉得不应该加1,加的应该是这条指令的所占字节数,得出来的 ...

IP=IP+1的意思就是指向下一条指令的地址,不是纯粹的数字上+1,我是照书上解释的,请不要理解为IP+1就是IP+数字1~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 10:17:28 | 显示全部楼层
王小2 发表于 2016-12-15 15:40
你2楼说的是正确的,但是3楼说的ip偏移地址为6,这里是错误的,老师讲过 e8 01 00 此处机器码的0001就是 ...

e8 01 00,这个机器码的意思,你要反过来理解~

IP不是按照你这么推断的,你这是反推断IP结果值,你只要理解CPU的工作原理,就不难明白IP是怎么变化的了。
视频中小甲鱼的解释并没有错,但请仔细多听几次,他视频说到的那种推断是从另外一个角度来解释IP的变化的。

000.jpg
CPU加电启动后,就会永远按照CS:IP指向的地址一直不停执行下去,直到来到你编写的程序,然后就是下面顺序。
【这些图片来自王爽《汇编语言》(第2版)电子书第25页到第29页】
001.jpg
002.jpg
003.jpg
004.jpg
005.jpg
006.jpg
007.jpg
008.jpg
009.jpg
010.jpg
011.jpg
012.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 10:33:48 | 显示全部楼层
本帖最后由 兰陵月 于 2016-12-16 13:04 编辑

所以按照上面图片中的解释:

内存地址    机器码      汇编指令     

................    .....................   ..............        
本处指令读取后执行前,CS:IP=1000:0000,本条执行执行完后,CPU执行CS:IP指向的指令
                                                         
1000:0     b8 00 00     mov ax,0   
1、读取b8 00 00,2、CS:IP=1000:0003,3、执行指令 mov ax,0


1000:3     e8 01 00     call s          
1、读取e8 01 00,2、CS:IP=1000:0006(IP=IP+本条指令长度即3,所以IP=3+3),3、执行call s
CALL S执行过程:①将当前的IP或CS和IP压入栈:当前IP=6,所以将6压入栈;②转移到S处执行。



1000:6     40           inc ax


1000:7     58         s:pop ax           
1、读取pop ax,2、CS:IP=1000:0008(此前经过CALL指令,IP的值已经变成了7);3、执行pop ax。
最后一条第2部为什么IP变成8,请详细阅读CALL指令的执行,里面解释了如何跳转,跳转的长度是多少,例如本例题中的短转移,标号S的值怎么来的,S实际上就是IP+0001,即6+1(这个6就是读取第2部指令完后IP的值,这个0001也就是e8 01 00的后两个字节),S在题目中代表跳转的偏移值,如果跳的更远,比如说跳到1000:8,则e8后面就应该是02  00,即e8 02 00。


不知道这样解释,楼主是否清楚~~~
诶~这个蛋疼的排版,你将就着看吧~~

评分

参与人数 1荣誉 +5 鱼币 +5 贡献 +3 收起 理由
ArmandXiao + 5 + 5 + 3

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 12:52:07 | 显示全部楼层
本帖最后由 兰陵月 于 2016-12-16 12:58 编辑

关于JMP 后面相关标号的处理,CALL S后面跳转到S那一部分与JMP功能一样~~~请看下图~

小甲鱼同志的讲解应该是附录3里面的意思~


图片来自王爽《汇编语言》第2版电子书,附录3
101.jpg
102.jpg
103.jpg
104.jpg
105.jpg
106.jpg
107.jpg
108.jpg
109.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-12-16 14:23:11 | 显示全部楼层
兰陵月 发表于 2016-12-16 12:52
关于JMP 后面相关标号的处理,CALL S后面跳转到S那一部分与JMP功能一样~~~请看下图~

小甲鱼同志的讲解应 ...

谢谢你啦,真是用心良苦啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 14:48:50 | 显示全部楼层
王小2 发表于 2016-12-16 14:23
谢谢你啦,真是用心良苦啊

这玩意必须得真懂,真明白,否则到后面越学越纠结,越来越看不懂~你懂了就好~,呵呵!

其实我回答你的问题,我也是一个复习的过程,我也得到了进步~~

一起进步~~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-22 14:01:48 | 显示全部楼层
兰陵月 发表于 2016-12-16 10:33
所以按照上面图片中的解释:

内存地址    机器码      汇编指令     

楼主这个很棒。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-25 03:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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