CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Jun 2004
    Posts
    106

    Call, push, and pop question

    To call a function (eg. printf), I push the values in reverse order and then "call printf". Then I have to pop them after the call. How does a function get the parameters from the stack? My instinct tells me by using pop, but then I'd have to push them back on so they can be popped after the call? Seems like wasted instructions. Can someone shed some light on this please? Thanks.

  2. #2
    Join Date
    Nov 2004
    Posts
    34

    Re: Call, push, and pop question

    Quote Originally Posted by Yasoo
    To call a function (eg. printf), I push the values in reverse order and then "call printf". Then I have to pop them after the call. How does a function get the parameters from the stack? My instinct tells me by using pop, but then I'd have to push them back on so they can be popped after the call? Seems like wasted instructions. Can someone shed some light on this please? Thanks.
    (Assuming x/86 processor)
    What normally happens is that a stack frame is built around the ebx register, then uses addressing [ebx +parm. offset] to get the parameters of the function and [ebx - var. offset] to get the automatic local variables.
    The offset must also take into account the return address, which is also pushed onto the stack.

    Here is a simple example that does not take into account more complex ideas such as a display and stack-alignmentm, also this example does not take automatic variables into account:

    Assume 2 dword-sized arguments pushed onto stack prior to call foo

    Code:
    foo:	; procedure foo
    ; fasm syntax
    	push	ebp		; preserve this
    	mov	ebp, esp	; grab current stack pointer
    	mov	eax, dword [ebp + 12 ]	; get 1st pushed parameter into eax
    	mov	ebx, dword [ebp + 8 ]	; get 2nd pushed parameter into ebx
    	; ... do other stuff
    	
    	; .. done, restore stuff before leaving
    	mov	esp, ebp	; restore esp to its original position
    	pop	ebp		; restore ebp	
    	ret		; this returns popping only the address pushed by 'call'
    Note that the offsets are +4 more than you would expect, this is because the x/86 'call' instruction pushes the current EIP address onto the stack before transferring control to the procedure (and 'ret' pops that address out).

    Noramlly, you should not write your own procedures this way. It is far better to have the procedure pop the paramters off the stack using 'ret n' where 'n' is the size in bytes of the pushed paramters.

    -sevagK
    www.geocities.com/kahlinor

  3. #3
    Join Date
    Apr 2003
    Posts
    1,755

    Smile Re: Call, push, and pop question

    Just an additional info.

    The reason why they did not use the "ret n" for functions such as printf is because they (the one who coded printf) don't now in advance how many paramaters does the caller want to pass. They don't know how much bytes need to be poped from the stack on return. For such functions like this, they made a way to determine how many parameters you passed. For example is the printf function, you have the first parameter as the "format specification" and you have to pass sufficient parameter to fill the values with %s, %d etc. Some other functions use a termination indicator to determine the end of the parameter. They go to the parameters until they reach a value of -1 for example.

    If you know in advance how many paramaters your function will get (fixed parameters), using the "ret n" is better. It is faster and is less code than the simple "retn".

  4. #4
    Join Date
    Jun 2004
    Posts
    106

    Re: Call, push, and pop question

    Thanks guys, that's some great info.

    Kahlinor, that's exactly what I was looking for.

    Rxbagain, I was wondering how unknown number of parameters is handled in assembly last night after I posted this. You read my mind. So, how do you know in assembly how many parameters were passed in a function like printf?

  5. #5
    Join Date
    Dec 2004
    Location
    Poland
    Posts
    1,165

    Re: Call, push, and pop question

    So, how do you know in assembly how many parameters were passed in a function like printf?
    Formatting functions (like printf) always take a format string as first parameter, and parsing this string lets function 'know' how many parameters was passed. Without some additional information passed during function call it would be not possible to determine how many parameters the call had. It is said that functions with variable number of arguments (those using '...' in prototype) always should have at least one fixed parameter, which makes possible to determine number (and type) of arguments passed.

    Hob
    B+!
    'There is no cat' - A. Einstein

    Use [code] [/code] tags!

    Did YOU share your photo with us at CG Members photo gallery ?

  6. #6
    Join Date
    Jun 2004
    Posts
    106

    Re: Call, push, and pop question

    Ah, right. I now remember reading that somewhere. Thanks Hobson.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured