Hi,
I noticed that a lot of assembly programs, especially those compiled from C/C++ programs follows the pattern bellow.
_Functions:
push ebp
mov ebp,esp
; ..... the bulk of the function
pop ebp
ret
_Main:
push ebp
mov ebp,esp
; ... bulk of the program
xor eax, eax
mov esp, ebp
pop ebp
Can some one explain to me this skeleton form?
it seems that ebp is used to pass parameters to functions, functions access the parameters passed to it by referring to [ebp + 8], [ebp + 0Ch]... etc,
but why "mov ebp,esp", esp isn't even initialized with any value, why copy esp to ebp?
Does order matter? can you do
mov ebp, esp
; and then
push ebp
What I mean is, when a register is pushed up to stack, does a copy of the register get pushed or register itself?
By the same token, I also don't understand "mov esp, ebp" before popping ebp and returning.
thanks in advance,
-Jerry
Hi Jerry,
You have a nick of "Epic" proportions. :bg
The use of ESP and EBP indicate what you call a stack frame and tis is an automated method so that you can safely use LOCAL variables and pass argumets to a procedure. ESP is where te stack parameters are pushed by the caller and it is stored in EBP with the stack frame. You can write procedures without a stack frame with a bit more work and ther are other formats for creating ad exiting a stack frame. MASM for example normally uses LEAVE then RET bytecount where bytecount is the number of parameter passed on the stack in bytes.
The return value is by convention EAX.
QuoteDoes order matter? can you do
mov ebp, esp
; and then
push ebp
Order does matter.
Consider: push ebp this saves the value of base pointer on stack.
pop ebp puts the saved value in ebp
mov ebp,esp
puts value of stack pointer in base pointer register
push ebp saves the value of stack pointer, not the base pointer
best regards,
czDrillard
Thank you all for your patience, I guess I shouldn't have just posted without even reading about how pushing and popping and stacks work. But now that I did, I have another question:
I saw this implementation from the PC assembly book, and it calls the C printf function, I understand just about all of it, except...
Why does it use pushf and popf and all? If I understand it right, pusha stores all the values of registers(except ESP), including the flag register, and then pushf stores the flag register, and then popf restores the flag register, and then popf restores all the registers(except ESP).
Is it just me or are the pushf, popf sequence unnecessary?
Here's the code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; prelimiary declarations here, including:
; extern _printf
; int_format db "%d", 0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
print_int:
enter 0,0
pusha
pushf
push eax
push dword int_format
call _printf
pop ecx
pop ecx
popf
popa
leave
ret
-Jerry
:8)
Jerry,
Its a reasonably sloppy way to perform this task. Starting a stack frame with ENTER is really slow, there is no need to preserve any of the registers used and there are no operations that change flags in the proc so they are not needed either. You can use PUSHAD, PUSHFD --- code --- POPFD POPAD in some debugging situations but its poor production code.
LATER :
Hee is how you would write this code in modern MASM.
_printf PROTO C :VARARG ; prototype for external prcedure
........
.data
int_format db "%d", 0
.code
........
; manual code
push OFFSET int_format
call _printf
add esp, 4
; invoke code
invoke _printf,ADDR int_format ; invoke balances the stack after the C call.
Note that this will not work as it is as there are no argumets specified as to what to display. Additional arguments would require that stack to be balanced diferently.