鱼C论坛

 找回密码
 立即注册
查看: 5680|回复: 3

[已解决]JMP指令是怎么区分是向上跳转还是向下跳转的?

[复制链接]
发表于 2021-4-26 19:22:16 | 显示全部楼层 |阅读模式

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

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

x
请花两分钟看完内容再回帖,谢谢了!
我看到说16位位移的范围是 -32768~32767,为此定义了一个标签在jmp下面,在jmp和标签之间定义了个63356个字节的0,编译连接后发现能正确执行。
编译后机器码如下:


                               
登录/注册后可看大图

F77C转成十进制后正好是63356
然后我就纳闷了,这不已经超出32767了么,不是应该解释为负数吗,为什么能正确的JMP到偏移为F782的位置?
于是乎我又改了改代码,定义了一个标签在jmp上面,同样在jmp和标签之间定义了个63356个字节的0,但这次编译后的机器码我看不懂了,因为编译后机器码为:

                               
登录/注册后可看大图

0881转成十进制是2177
我搞不懂2177和63356有什么关系,但是却能正确的跳到标签定义的位置:0003
但如果E98108表示向上跳那么多字节的话,那么向下跳过2177字节的0会怎么表示?
于是我又写了代码测试向下跳2177字节个0,结果却是机器码完全一样。。但却仍然能正确区分向上还是向下。
下面是代码和截图:

T1代码:
assume cs:codesg
codesg segment
    mov ax,1
    s1:db 63356 dup(0)
    start:jmp near ptr s1
    mov cx,ax
codesg ends
end start
T2代码:
assume cs:codesg
codesg segment
    mov ax,1
    start:jmp near ptr s2
    db 2177 dup(0)
    s2:mov cx,ax
codesg ends
end start
对比截图:

                               
登录/注册后可看大图
可以看到,两个不同方向的jmp指令的机器码居然完全一样,但是debug解析出来的汇编指令却仍然能正确的区分出向上跳转还是向下跳转
这是什么原理?不是说16位位移的范围是 -32768~32767 吗?为什么能正确向上跳过63356个字节的0?为什么相同的机器码又能正确的向下跳过2177个字节的0?

最佳答案
2021-4-26 20:42:20
jmp near ptr 标号,它实现的是段内近转移。
其功能是:(ip)=(ip)+16位位移

0xf77f + 0x03 + 0x0881 = 0x10003
ip寄存器是16位的,只能保存低16位,前面的1丢弃,所以ip寄存器的内容是0x0003

1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-4-26 20:42:20 | 显示全部楼层    本楼为最佳答案   
jmp near ptr 标号,它实现的是段内近转移。
其功能是:(ip)=(ip)+16位位移

0xf77f + 0x03 + 0x0881 = 0x10003
ip寄存器是16位的,只能保存低16位,前面的1丢弃,所以ip寄存器的内容是0x0003

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

使用道具 举报

发表于 2021-4-26 20:44:23 | 显示全部楼层
0x03 + 0x03 + 0xf77c = 0xf782
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-4-26 20:47:02 | 显示全部楼层
cpu可不关心你往哪里跳,它只是做加法,把结果给ip寄存器
ip是16位的寄存器,超过16位的部分被丢弃
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-23 03:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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