DakienDX
November 13th, 2001, 15:35
It's very easy
arg_? points to a parameter, var_? to a variable. Everything clear? I don't think so.
Lets show an example:
Code:
Push Offset Param1
Push Offset Param2
Call TestProc
Add ESP, 8
...
TestProc:
Push EBP
Mov EBP, ESP
Sub ESP, 8
Mov EDI, [EBP+arg_8]
Mov EDI, [EBP+var_8]
Mov ESP, EBP
Pop EBP
Ret
If we follow the code, at the beginning of TestProc there's the return address at [ESP], the pointer to Param2 at [ESP+4] and the pointer to Param1 at [ESP+8].
With the "Push EBP" each value is increased by 4 so Param2 would be at [ESP+8].
Then we make EBP=ESP, so we can access Param? by [EBP+?].
But why do we do this?
Simple: We can decrease ESP by a count to get space for local variables. So the [EBP+?] is still valid, but we can also access [EBP-?].
You must imagine that arg_? is a positive number and var_? is a negative number.
So accessing [EBP+var_8] means [EBP-8], which will access the data which is currently at [ESP].
We must take care to never access data
under [ESP], because this data will be destroyed with the next "Push" instruction.
So we write down:
The address space over EBP+8 is used for accessing parameters given to the procedure.
The address space between ESP and EBP is used for local variables. Their values will be random on init and will loose their values on exit of the procedure.
[EBP] contains the
old value of EBP at the begin of the procedure, which must be resored at the end
[EBP+4] contains the return address and must also stay intact
All this rules only apply to normal programs. Protectors may sometimes use ESP and EBP in other ways to prvent debugging and disassembling.
Historical Review
Why don't we use just ESP+? to access both local variables and parameters?
1. We would have to change the '?' after each "Push" and "Pop" intruction.
2. In 16-bit code there is no [SP+?]. You can only use [BP+?] to access the data on the stack (as well as BX, SI, DI)
And we all know that the PC started at 16-bit code. 