10
votes

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.

2
Ebp is an address of stack frame, where all arguments are. Ebp+8 is an address of xp's value (that is address of int). Technically, yes – ebp+8 == &xp.user3125367
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 – And no, a pointer value is pushed on stack.user3125367

2 Answers

7
votes

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.

2
votes

%bp is the stack base pointer which must be deferenced before I can access anything on the stack. So movl8(%bp),%edx` fetches the value which sits on offset 8 in the current stack frame.

This value is a pointer, so we have to dereference it in order to access its contents, no matter if for reading or writing.

OTOH, y is an int, so to get it is just movl 12(%ebp), %ecx and no further actoin required.

So movl %ecx, (%edx) is exactly the right thing: put the value which is stored in ecx to the memory pointed to by edx.