linux - 汇编 - 为什么 strtol 破坏 %rcx 寄存器?

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

问题:

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

相关文章:

assembly - 如何清理格式错误的 x86_64 程序集?

c - x86_64 AT&T 汇编中的旋转函数

c++ - Linux写函数

linux - 如何从行号中查找封装函数名

assembly - 无法在 16 位实模式汇编中清除整个屏幕

arrays - 如何索引汇编中的字符串

assembly - E820h QuerySystemAddressMap 在 4GB+ 内存上返回的值

linux - (BASH)如何在命令中删除默认的 'newline' 运算符

linux - 使用grep命令查找Joomla版本1.6

c - 汇编:在调用函数之前加载有效地址的目的?