2012-12-18 173 views
2

Possible Duplicate:
Not sure why we add the registers %rdx and %rax when the assembly code has been using %eax and %edxGCC生成的asm ::我分配了哪個寄存器?

全部。 所以,這是我最小的方案:

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後綴使用」)

+0

它是x86_64,而不是x86。一個64位指令需要後綴「q」而不是「l」,所以你會得到錯誤 –

回答

1

如果您不確定寄存器及其大小,請查看here。它認爲這種方式

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

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

這就是爲什麼addl不能與以r爲前綴的寄存器一起工作,它們比addl期望的要長。改爲嘗試addq