Linux 64。
GCC 4.8.2(-O3 -march = native)
左手下方的x86_64 abi,在第21页打开。
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
)和一个返回%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
...
由于
答案 0 :(得分:4)
在每个调用约定中,我知道有些寄存器可能被被调用的函数修改,有些寄存器不能被修改。
在32位程序中,可以修改ecx而不必修改ebx - 或者更确切地说 - 必须在返回之前重新存储。对于64位程序,此规则似乎是相同的。
实际上,大多数函数会修改大多数寄存出于这个原因,有一个&#34; popq%rbx&#34;在您发布的代码的末尾,因为函数不能修改rbx。 rcx可能会被修改,strtol显然会这样做!