汇编 - 为什么strtol clobbers%rcx注册?

时间:2015-02-19 10:44:28

标签: linux assembly x86-64 cpu-registers att

背景:

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
...

问题:

应为第4个输入整数参数保留

%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
...

由于

1 个答案:

答案 0 :(得分:4)

在每个调用约定中,我知道有些寄存器可能被被调用的函数修改,有些寄存器不能被修改。

在32位程序中,可以修改ecx而不必修改ebx - 或者更确切地说 - 必须在返回之前重新存储。对于64位程序,此规则似乎是相同的。

实际上,大多数函数会修改大多数寄存出于这个原因,有一个&#34; popq%rbx&#34;在您发布的代码的末尾,因为函数不能修改rbx。 rcx可能会被修改,strtol显然会这样做!