最近和群友讨论指令集时,遇到一个有意思的问题,x86_64
的 CALL
指令长度会发生变化吗?
今天我们通过一个简单的例子验证一下长度会发生变化
CALL[1] 指令调用一个过程,指挥处理器从新的内存地址开始执行。过程使用 RET(从过程返回)指令将处理器转回到该过程被调用的程序点上。
根据源码的不同,会两种不同开头和长度的指令[2]: e8
和 ff
image
以下面的示例代码[3]为例:
0x1
的地址执行0x40113e
的地址执行image
经过编译后,会转为两种不同写法的 call
指令:
为了方便对照,采用
clang -O3
进行编译
call
指令是 ff
和 d1
,代表跳转到 $rcx 寄存器存储的地址执行e8
开头,后面跟着 1f 00 00 00
1f 00 00 00
代表实际执行的指令地址与下个指令地址的偏移量。
该行指令的地址是0x40111a
,下一个指令的地址是 0x40111f
两个地址相减:0x40113e - 0x40111f = 0x1f
所以,偏移量是 0x1f
[1]
CALL: http://c.biancheng.net/view/3537.html
[2]
指令: http://ref.x86asm.net/coder64-abc.html
[3]
示例代码: https://godbolt.org/z/5dMnsxq33