程序集 - 为什么 strtol 会破坏 %rcx 寄存器?

Assembly - Why strtol clobbers %rcx register?

上下文:

Linux64.

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    , %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 应保留给第 4 个输入整数参数。

strtol有3个输入参数(分别是寄存器%rdi%rsi%rdx)和一个return、%eax.

为什么 %rcx 被破坏了? 此代码不会成功:

...
    movl    , %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 显然会这样做!