This belongs in the General Programming forum, but I'll answer it here and then this will all get moved with it.
1. To pass arguments to a function, you push them on the stack in some predefined order and then the function you call knows which order they were pushed. As for local variables, they are allocated on the stack, but in a different manner (using a base pointer) such that it is possible to clean up the stack at the end of a function without knowing how much was allocated.
There are two main ways of cleaning the stack up when returning from a function, C calling convention and PASCAL calling convention. In both of these conventions, arguments are passed from right to left*. There are others as well.
A function declared with C convention looks like this:
Code:
; void some_function(int val)
some_function:
push ebp
mov ebp, esp ; Create a stack frame
sub esp, 4 ; Allocate a single int-sized local variable
; Do things with the variable here
mov esp, ebp ; Restore the old ESP
pop ebp ; Restore the old EBP
ret
And it is called like this:
Code:
push some_value
call some_function
add esp, 4 ; The caller is responsible for cleaning up pushed parameters
In PASCAL convention, however, the function cleans up the stack:
Code:
; int PASCAL some_other_function(int val)
some_other_function:
push ebp
mov ebp, esp ; Uses the same kind of stack frame as C
; Do something
mov esp, ebp
pop ebp
ret 4 ; This adjusts ESP so the pushed argument is considered popped
And you call it like this:
Code:
push some_other_value
call some_other_function
; Stack is cleaned up for us, don't have to do anything.
2. I would use sub sp, xxx. rep stos has nothing to do with setting up a stack frame, and it doesn't even affect ESP. I think you can still use the bound instruction to make sure your stack isn't broken, even if you didn't use enter.
* PASCAL might have been originally the other way around but Microsoft changed it?