跳转指令有几种不同的编码,但最常用的一些是PC相关的(PC-relative, PC = Program Counter)。也就是,他们会将目标指令的地址与紧跟在跳转指令后面那条指令的地址之差作为编码。
我们用例子来验证上面这句话,先写个简单的C程序:
然后转化为汇编代码,用gdb调试,设好断点,程序运行起来后,进入断点,输入disassemble /r,可以看到如下代码:
我们看main+36这里0x08048098 <main+36>: 7e 06 jle 0x80480a0 <main+44>
7e 06就是机器码了,7e就是jle,而程序的跳转地址0x80480a0 = 06 + 0x804809a(下一条指令的地址),而06并不是真正的跳转地址。