Possible Duplicate:
Not sure why we add the registers %rdx and %rax when the assembly code has been using %eax and %edx
all. So, here's my minimal program:
int main(int argc, char * argv[]){
volatile int a;
volatile int b;
volatile int c;
a = 9;
b = 15;
c = a+b;
return c;
}
I now run gcc -S on this, and here's the meat of the generated assembly:
.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
Okay, so you see the line I indicate as the problem line. Here's my question: What on earth are %rdx and %rax? The only registers I've loaded things into are %edx and %eax.
Since the program works, %rdx and %rax must be some sort of alias to %edx and %eax, accordingly. Can someone possibly explain the nuances of x86 register nomenclature? I'm completely in the dark on this.
(Of note, if I change the problem line to addl %edx, %eax
, the result is identical, but if I change it to addl %rdx, %rax
, I get "Error: Incorrect register '%rax' used with l suffix")
Have a look here if you are unsure about the registers and their sizes. Think of it this way
union{
struct{
uint32_t eax;
uint32_t padd;
};
uint64_t rax;
};
eax
and rax
share the same register, eax
is low part of that register.
This is the reason why addl
won't work with the registers prefixed with r, they are longer than addl
is expecting. Try addq
instead.