PASSING DATA TO THE STACK
Stack Overview
Letβs take this simple code as an example:
addTwo:
add eax, ebx
ret
main:
push 4
push 1
call addTwo
mov ebx, eax
mov eax, 1
int 80h
The stack layout will look like this:
| Stack |
|---|
ret (sp) |
1 |
4 |
ret = return address sp = stack pointer
If I call addTwo, how does it know that the first parameter is 4 and the second parameter is 1!? One of the most common ways is to create a base pointer to reference the parameters.
Creating a Base Pointer
Before accessing the parameters, I need to set up a base pointer ebp to reference the stack frame.
addTwo:
push ebp
mov ebp, esp
add eax, ebx
ret
main:
push 4
push 1
call addTwo
mov ebx, eax
mov eax, 1
int 80h
push ebp- Save the base pointer;mov ebp, esp- Set the base pointer to the stack pointer;
The stack layout will look like this:
| Stack |
|---|
ebp (sp) |
ret |
1 |
4 |
ret = return address sp = stack pointer
The ebp acts like the base of my stack frame and the divider between the stack frames. It helps me reference the parameters and local variables. If I had procedures nested in procedures, I could use the base pointer to reference the parameters and local variables of the outer procedure.
Accessing and Cleaning the Stack
Parameters are accessed relative to the base pointer ebp.
addTwo:
push ebp
mov ebp, esp
mov eax, [ebp + 8]
mov ebx, [ebp + 12]
add eax, ebx
pop ebp
ret
main:
push 4
push 1
call addTwo
mov ebx, eax
mov eax, 1
int 80h
| Stack | Value |
|---|---|
ebp (sp) | +0 |
ret | +4 |
1 | +8 |
4 | +12 |
ret = return address sp = stack pointer
I can use x/x or x/4x to inspect the stack in GDB. This will help me understand how the stack is laid out and how I can access the parameters.