x86 Stack Confusion



Hello everybody.

I'm reading Dr. Paul Carters book "PC Assembly Language". I'm currently
finished with chapter 4 which covered the stack and I've written a few
sample programs to assure that I have understood the contents of the
chapter. However, one of the programs is not working as expected.

There are two modules to the program: main.c and stack.asm

---main.c---
#include <stdio.h>
#include <stdlib.h>

void stack(int parameter, int* parameter2);

int main(int argc, char* argv[])
{
int i;
if (argc != 3)
{
fprintf(stderr, "Usage: %s <number> <number 2>\n", argv[0]);
exit(EXIT_FAILURE);
}

i = atoi(argv[2]);
stack(atoi(argv[1]), &i);

return 0;
}
---main.c---

---stack.asm---
segment .data

parameter_val db "Value of parameter: %d",0xA,0
parameter_adr db "Address of parameter: %p",0xA,0
parameter2_val db "Value of parameter 2: %d",0xA,0
parameter2_adr db "Address of parameter 2: %p",0xA,0
locvar_val db "Value of local variable: %d",0xA,0
locvar_adr db "Address of local variable: %p",0xA,0
esp_val db "Value of EBP: %p",0xA,0
ebp_val db "Value of ESP: %p",0xA,0

segment .text
global stack
extern printf
stack:
push ebp
mov ebp, esp
sub esp, 4
push ebx

push esp
push esp_val
call printf
add esp, 8

push ebp
push ebp_val
call printf
add esp, 8

push dword [ebp+8]
push parameter_val
call printf
add esp, 8

lea ebx, [ebp+8]
push ebx
push parameter_adr
call printf
add esp, 8

mov ebx, [ebp+12]
mov ebx, [ebx]
push ebx
push parameter2_val
call printf
add esp, 8

lea ecx, [ebp+12]
push ecx
push parameter2_adr
call printf
add esp, 8

inc ebx
push ebx
push locvar_val
call printf
add esp, 8

lea ebx, [ebp-4]
push ebx
push locvar_adr
call printf
add esp, 8

pop ebx
mov esp, ebp
pop ebp
ret
---stack.asm---

The assembler used is NASM and the commands to compile the program are
as follows (on my system):

nasm -f elf stack.asm
gcc -Wall -pedantic -c main.c
gcc -Wall -pedantic -o stack stack.o main.o

As you can see the program just passes two parameters to a function
which prints various values and addresses. The output of the program,
however, confuses me.

---output---
lithium@darkstar stack $ ./stack 1 2
Value of EBP: 0xbf9884b0
Value of ESP: 0xbf9884b8
Value of parameter: 1
Address of parameter: 0xbf9884c0
Value of parameter 2: 2
Address of parameter 2: 0xbf9884c4
Value of local variable: 3
Address of local variable: 0xbf9884b4
---output---

First of all I do not understand the value of esp. The stack function
subtracts 4 from esp and saves ebp (to comply with the C calling
convention). Thus, ebp and esp should differ by 8. They do, but why is
esp 8 higher than ebp? Shouldn't esp be lower than esp since pushing to
the stack subtracts from esp?

Also, I am confused about the addresses of the parameters. The address
of parameter 1 is 16 higher than ebp. However in the assembly code
parameter 1 is [ebp+8]. Parameter 2 is 4 off from parameter 1 so that
makes sense. The address of the local variable also doesn't make sense
since in the assembly code I refer to the local variable as [ebp-4]
however the address given by the output of my program is 4 higher than
ebp?

Thanks in advance for clearing up any of my confusion.

.



Relevant Pages

  • Re: Newbie question...
    ... "and esp, 0xFFFFFFF0" probably makes it clearer that we're aligning the stack to 16 bytes. ... Make ebp a kind of "semi stack frame pointer". ... We "return foo " in eax. ...
    (alt.lang.asm)
  • Re: newbie questions
    ... mov ebp, esp ... What's a stack? ... in calls directly between compiled functions. ...
    (alt.lang.asm)
  • Re: Newbie question...
    ... and esp, -16 ... mov ebp, esp ... Since the x86 increments esp with "pop", the new stack pointer is aligned ... add eax, 15 ...
    (alt.lang.asm)
  • Re: Stack frames
    ... > ESP with the common stack frame models. ... ESP, why not simply move the "MOV esp, ebp" ... You can't rely on "size(locals + align)" to keep the ...
    (alt.lang.asm)
  • Re: beginner, explanation help with output
    ... ebp, esi, and edi, in that order. ... but how does assembler know how to use it? ... stack; most people would just add 8 to esp. ...
    (alt.lang.asm)