上下文:
Linux 64。
GCC 4.8.2(使用 -O3 -march=native)
我左手下的x86_64 abi,在第21页打开。
C 代码:
int main (int argc, char ** argv) {
printf("%d %s\n", atoi(argv[2]),argv[1] );
}
汇编代码:
(注意编译器自己用strtol替换了atoi)
...
movl $10, %edx
movq 16(%rsi), %rdi
movq 8(%rsi), %rbx
xorl %esi, %esi
call strtol
movl $.LC0, %edi
movq %rbx, %rdx
movl %eax, %esi
xorl %eax, %eax
call printf
xorl %eax, %eax
popq %rbx
...
问题:
%rcx
应保留给第四个输入整数参数。
strtol
有 3 个输入参数(分别注册 %rdi
、%rsi
、%rdx
)和 1 个输入参数返回,%eax
。
为什么%rcx
会被破坏?
此代码不会成功:
...
movl $10, %edx
movq 16(%rsi), %rdi
movq 8(%rsi), %rcx <-- look I replaced with %ecx
xorl %esi, %esi
call strtol
movl $.LC0, %edi
movq %rcx, %rdx <-- look I replaced with %ecx
movl %eax, %esi
xorl %eax, %eax
call printf
xorl %eax, %eax
popq %rbx
...
谢谢
最佳答案
在每个调用约定中,我知道有一些寄存器可以由被调用函数修改,而有些寄存器则不能修改。
在 32 位程序中,ecx 可以被修改,而 ebx 不能被修改 - 或者,更准确地说 - 必须在返回之前重新存储。对于 64 位程序,此规则似乎是相同的。
事实上,大多数函数都会修改大多数寄存器;因此,您发布的代码末尾有一个“popq %rbx”,因为函数不能修改 rbx。 rcx 可以被修改,strtol 显然就是这样做的!
关于linux - 汇编 - 为什么 strtol 破坏 %rcx 寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28604274/