【问题标题】:GCC-generated asm :: Where did I assign to that register? [duplicate]GCC 生成的 asm :: 我在哪里分配给该寄存器? [复制]
【发布时间】:2012-12-05 05:54:35
【问题描述】:

可能重复:
Not sure why we add the registers %rdx and %rax when the assembly code has been using %eax and %edx

全部。 所以,这是我的最小程序:

int main(int argc, char * argv[]){
    volatile int a;
    volatile int b;
    volatile int c;
    a = 9;
    b = 15;
    c = a+b;
    return c;
}

我现在对此运行 gcc -S,这是生成程序集的主要内容:

.LCFI1:
    movl    %edi, -20(%rbp)    //unknown setup
    movq    %rsi, -32(%rbp)    //unknown setup
    movl    $9, -4(%rbp)       //a=9, so -4(%rbp) is the register for a.
    movl    $15, -8(%rbp)      //b=15, so -8(%rbp) is b's register.
    movl    -4(%rbp), %edx     //move a into the register for addition.
    movl    -8(%rbp), %eax     //move b into the register for additon.
    leal    (%rdx,%rax), %eax  //Add a and b, store in %eax. (PROBLEM LINE)
    movl    %eax, -12(%rbp)    //Store %eax in c's register.
    movl    -12(%rbp), %eax    //get ready to return c. 
    leave                      //we're done here.
    ret

好的,所以你看到我指出的那条线是问题线。这是我的问题:%rdx 和 %rax 到底是什么?我加载的唯一寄存器是 %edx 和 %eax。

由于程序有效,因此 %rdx 和 %rax 必须是 %edx 和 %eax 的某种别名。有人可以解释 x86 寄存器命名法的细微差别吗?我对此一无所知。

(注意,如果我把问题行改成addl %edx, %eax,结果是一样的,但是如果我把它改成addl %rdx, %rax,我得到“错误:不正确的寄存器'%rax'使用l后缀”)

【问题讨论】:

  • 它是 x86_64,而不是 x86。一个 64 位指令需要后缀“q”,而不是“l”,所以你会得到错误

标签: gcc assembly x86 cpu-registers att


【解决方案1】:

如果您不确定寄存器及其大小,请查看here。这样想

union{
  struct{
    uint32_t eax;
    uint32_t padd;
  };
  uint64_t rax;
};

eaxrax 共享同一个寄存器,eax 是该寄存器的低位部分。

这就是为什么addl 不能使用以 r 为前缀的寄存器的原因,它们比addl 预期的要长。请改用addq

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 2011-07-04
    • 2015-01-22
    • 2012-11-27
    • 2021-05-19
    • 1970-01-01
    相关资源
    最近更新 更多