为何反汇编输出中会出现跳转到下一条指令的条件跳转?
为什么反汇编会出现跳转到下一行的条件跳转?
有时查看反汇编输出时,会出现跳转到下一行的条件跳转,这看似毫无意义——无论条件是否满足,最终都会执行下一条指令。
比如编译这段C++代码:
#include <stdexcept> bool f(int x, int y, int z) { switch(x) { case 0: return z < y; case 1: return y < z; default: throw std::runtime_error("bad x"); } }
生成.o文件后用objdump -C -d反汇编,会看到这样的片段:
0000000000000000 <f(int, int, int)>: 0: f3 0f 1e fa endbr64 4: 39 d6 cmp %edx,%esi 6: 0f 9f c0 setg %al 9: 85 ff test %edi,%edi b: 75 03 jne 10 <f(int, int, int)+0x10> d: c3 ret e: 66 90 xchg %ax,%ax 10: 83 ff 01 cmp $0x1,%edi 13: 0f 85 00 00 00 00 jne 19 <f(int, int, int)+0x19> 19: 39 d6 cmp %edx,%esi 1b: 0f 9c c0 setl %al 1e: c3 ret
其中0f 85 00 00 00 00这条指令是相对偏移为0的条件跳转,反汇编显示为jne 19,看起来只是跳转到下一行,这背后的原理是:
这是链接阶段的重定位占位逻辑。你反汇编的是未完成链接的.o目标文件,而非最终的可执行文件:
- 编译时,编译器明确知道当
x既不是0也不是1时,需要跳转到抛出异常的代码段,但此时异常处理代码的最终内存地址还无法确定——这部分代码可能来自标准库或其他目标文件,必须等到链接阶段才能确定准确位置。 - 于是编译器生成了一个占位的
jne指令,暂时把跳转偏移量设为0(也就是跳转到下一行),这样既保证了当前指令流的结构完整、不会出现反汇编错误,也给后续链接器留下了修改空间。 - 当链接器处理所有目标文件时,会找到抛出
std::runtime_error的代码入口,把这个占位跳转的偏移量替换成正确的地址,让它真正跳转到异常处理逻辑。
简单说,这个“无意义”的跳转只是编译过程中的临时占位,链接完成后它就会变成真正有效的跳转指令。
内容的提问来源于stack exchange,提问作者Daniel McLaury
相关产品推荐
相关产品推荐

