I'm reading my textbook and it has code for a swap function:
In C:
int exchange(int *xp, int y) {
int x = *xp;
*xp = y;
return x;
}
In x86 Assembly with annotations:
// xp is at %ebp + 8, y at %ebp + 12
movl 8(%ebp), %edx // get xp
movl (%edx), %eax // get x at xp
movl 12(%ebp), %ecx // get y
movl %ecx, (%edx) // store y at xp
So from my understanding, if the int* xp pointed to an int I at address A, then the first line of assembly code stores A at %edx. Then it gets dereferenced in the second line and stored at %eax.
If this is true, I'm wondering why line 1's "8(%ebp)" doesn't dereference the pointer, storing the int I in %edx instead of the address A? Isn't that what parentheses do in assembly?
Or does that mean that when pointers are pushed onto the stack, the address of the pointer is pushed on rather than the value it holds so 8(%ebp) technically holds &xp?
Just wanted to clarify if my understanding was correct.
xp
is a pointer. It has a four byte value. That value is pushed onto the stack by the calling function. The function prologue, which you haven't shown sets up a base pointer in ebp
. The value of xp
is stored at offset 8 relative to that base pointer.
So the first line of code dereferences the base pointer, as indicated by the parentheses, with an offset of 8 to retrieve the value of xp
(which is an address that points to an int) and puts it into edx
.
The second line of code uses the address in edx
to retrieve the value of the int
, and puts that value into eax
. Note that the function return value will be the value in eax
.
The third line dereferences the base pointer, with an offset of 12, to get the value of y
.
The fourth line uses the address in edx
to place y
at the location that xp
points to.