Parameters and the Stack

Discussion in 'C Programming' started by IMSHURKKPWII@spammotel.com, Sep 28, 2003.

  1. Guest

    Hi all,

    I am confused about the methods by which C passes things to other
    routines. If I have a routine,

    void rt([type] [name1], [type] [name2], ...);

    Then I know that the process to call this function is this:

    1. Push values onto the stack, from right to left.
    2. Push return address onto stack.
    3. Set PC = address of rt.

    The stack looks like:

    ---
    arg_n
    ---
    arg_n-1
    ---
    ....
    ---
    Return Address
    ---

    I noticed that when exiting a function, the stack pointer should be
    pointing to the position on the stack where the Return Address is
    stored; and when returning to the caller, PC gets set to SP, and then
    SP gets incremented by 4 bytes or so-- however long the Return Address
    is.

    Now I have a problem with this: SP will be pointing to the last
    argument on the stack that was pushed by the caller. I've looked at
    assembly listings and I can't seem to find any section that is
    responsible for actually removing those arguments from the stack once
    they've been pushed.

    Thanks
    -HG.
     
    , Sep 28, 2003
    #1
    1. Advertising

  2. wrote:
    > Now I have a problem with this: SP will be pointing to the last
    > argument on the stack that was pushed by the caller. I've looked at
    > assembly listings and I can't seem to find any section that is
    > responsible for actually removing those arguments from the stack once
    > they've been pushed.


    Afair in the C calling convention the caller removes the arguments. So a
    typical thing would be:

    push param3
    push param2
    push param1
    call foobarfunc
    add esp, 0xc
     
    Dennis Bliefernicht, Sep 29, 2003
    #2
    1. Advertising

  3. wrote:

    > Hi all,
    >
    > I am confused about the methods by which C passes things to other
    > routines. If I have a routine,
    >

    The "method by which C passes things to other routines" is not
    specified. Every implementor is free, from the C standard's point of
    view, to implement it as they please.

    Now, there are conventions amond implementors, but

    a) I am far from clear about them
    b) in any case, we do not discuss them in comp.lang.c

    --
    Bertrand Mollinier Toublet
    Currently looking for employment in the San Francisco Bay Area
    http://www.bmt.dnsalias.org/employment
     
    Bertrand Mollinier Toublet, Sep 29, 2003
    #3
  4. Matt Taylor Guest

    <> wrote in message
    news:...
    > Hi all,
    >
    > I am confused about the methods by which C passes things to other
    > routines. If I have a routine,
    >
    > void rt([type] [name1], [type] [name2], ...);
    >
    > Then I know that the process to call this function is this:
    >
    > 1. Push values onto the stack, from right to left.
    > 2. Push return address onto stack.
    > 3. Set PC = address of rt.
    >
    > The stack looks like:
    >
    > ---
    > arg_n
    > ---
    > arg_n-1
    > ---
    > ...
    > ---
    > Return Address
    > ---
    >
    > I noticed that when exiting a function, the stack pointer should be
    > pointing to the position on the stack where the Return Address is
    > stored; and when returning to the caller, PC gets set to SP, and then
    > SP gets incremented by 4 bytes or so-- however long the Return Address
    > is.
    >
    > Now I have a problem with this: SP will be pointing to the last
    > argument on the stack that was pushed by the caller. I've looked at
    > assembly listings and I can't seem to find any section that is
    > responsible for actually removing those arguments from the stack once
    > they've been pushed.
    >
    > Thanks
    > -HG.


    Usually the function is followed by an add esp, n instruction to remove all
    of the parameters simultaneously rather than tediously popping them off one
    at a time. Some compilers will even delay cleaning up the stack across
    several functions. The space wasted by the parameters is negligible, and you
    save yourself a few instructions.

    There are other methods of passing parameters to a function, too. One
    popular variant requires the called function to clean up the stack. Another
    convention passes parameters in registers and the stack is completely
    avoided except for the call/ret implicit usage.

    Here's an example from GCC 3.2:

    subl $12, %esp
    pushl $LC0 ; "0\0"
    call _atoi
    addl $16, %esp

    It reserves an extra 12 bytes to try and keep stack allocations to a
    multiple of 16 for architectural reasons (at least, I think). After the
    function call, it cleans up the stack with the add instruction.

    -Matt
     
    Matt Taylor, Sep 29, 2003
    #4
  5. Randall Hyde Guest

    You might want to take a look at the chapter on
    "Mixed Language Programming" in "The Art of Assembly Language"
    http://webster.cs.ucr.edu.
    It wouldn't hurt to read the chapters on procedures in that book too.
    Cheers,
    Randy Hyde

    <> wrote in message news:...
    > Hi all,
    >
    > I am confused about the methods by which C passes things to other
    > routines. If I have a routine,
    >
    > void rt([type] [name1], [type] [name2], ...);
    >
    > Then I know that the process to call this function is this:
    >
    > 1. Push values onto the stack, from right to left.
    > 2. Push return address onto stack.
    > 3. Set PC = address of rt.
    >
    > The stack looks like:
    >
    > ---
    > arg_n
    > ---
    > arg_n-1
    > ---
    > ...
    > ---
    > Return Address
    > ---
    >
    > I noticed that when exiting a function, the stack pointer should be
    > pointing to the position on the stack where the Return Address is
    > stored; and when returning to the caller, PC gets set to SP, and then
    > SP gets incremented by 4 bytes or so-- however long the Return Address
    > is.
    >
    > Now I have a problem with this: SP will be pointing to the last
    > argument on the stack that was pushed by the caller. I've looked at
    > assembly listings and I can't seem to find any section that is
    > responsible for actually removing those arguments from the stack once
    > they've been pushed.
    >
    > Thanks
    > -HG.
    >
     
    Randall Hyde, Sep 29, 2003
    #5
  6. Jack Klein Guest

    On 28 Sep 2003 14:37:10 -0700, wrote in
    comp.lang.c:

    While this message is topical in comp.lang.asm.x86, it is severely
    off-topic in comp.lang.c.

    > Hi all,
    >
    > I am confused about the methods by which C passes things to other
    > routines. If I have a routine,


    C does not have either "things" or "routines".

    The methods that any particular C compiler uses to pass _arguments_ to
    _functions_ are not specified at all by the language, and as such are
    completely off-topic in comp.lang.c.

    > void rt([type] [name1], [type] [name2], ...);
    >
    > Then I know that the process to call this function is this:
    >
    > 1. Push values onto the stack, from right to left.


    No such guarantee or requirement in the C language standard, and quite
    a few compilers do not do it this way.

    > 2. Push return address onto stack.


    On my ARM compiler, the return address goes into the link register
    (R14), no stack involved.

    In the future please keep your questions about low-level mechanisms of
    compilers for the x86 architecture in clax where they belong, and out
    of comp.lang.c where they don't.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c /faq
     
    Jack Klein, Sep 29, 2003
    #6
  7. R.Wieser Guest

    <> schreef in berichtnieuws
    ...
    > Hi all,


    Hello HG,

    > I am confused about the methods by which C passes things to other
    > routines. If I have a routine,


    [Snip]

    > Now I have a problem with this: SP will be pointing to the last
    > argument on the stack that was pushed by the caller. I've looked at
    > assembly listings and I can't seem to find any section that is
    > responsible for actually removing those arguments from the stack once
    > they've been pushed.


    There are two way's to handle the arguments that where pushed onto the stack
    before a routine is called :
    1) The routine itself removes them off the stack.
    2) the program that calls the routine removes them off the stack.

    if 1) is used, you will probably see that the RETF command of the routine
    allso has a number behind it. Like : RETF 4 -> return and add 4 to the
    stack-pointer (removing 4 bytes off the stack)

    In the case of 2), you will notice a "ADD SP,{value}" command, just below
    the call to the routine. the {value}should equal the number of bytes
    pushed.

    Regards,
    Rudy Wieser
     
    R.Wieser, Sep 29, 2003
    #7
  8. Chris Dollin Guest

    wrote:

    > Hi all,
    >
    > I am confused about the methods by which C passes things to other
    > routines. If I have a routine,
    >
    > void rt([type] [name1], [type] [name2], ...);
    >
    > Then I know that the process to call this function is this:
    >
    > 1. Push values onto the stack, from right to left.
    > 2. Push return address onto stack.
    > 3. Set PC = address of rt.


    No; you do *not* know this. It may (or may not) be the way that the
    call gets executed on some processor, but that's a detail not addressed
    by the C standard.

    If you _need_ to know how your C implementation passes arguments
    to functions, you need an implementation-specific resource [newsgroup,
    documentation, whatever].

    If you don't _need_ to know, then what we can tell you is that the
    arguments are evaluated in some order, possibly interleaved, and
    that when that's done, the values are assigned to the freshly-created
    function-local argument variables, and execution of that function
    starts, and that when it finishes [normally], control will return
    to just after the call.

    No stack need be involved *at all*. For example, this:

    int spoogleAdd( struct spoogle *spoo, int n )
    { return spoo->anIntField + n; }

    will compile to something like this:

    LDR r0, [r1, #anIntFieldOffset]
    ADD r0, r0, r2
    MOV pc, r14

    No stack for the arguments - they come in in registers; no stack for
    the result; that goes out in a register; no stack for the return
    address: that arrives in r14.

    Of course that's on a real processor, not the x86 :)

    --
    Chris "electric pig" Dollin
    C FAQs at: http://www.faqs.org/faqs/by-newsgroup/comp/comp.lang.c.html
    C welcome: http://www.angelfire.com/ms3/bchambless0/welcome_to_clc.html
     
    Chris Dollin, Sep 29, 2003
    #8
  9. CBFalconer Guest

    "R.Wieser" wrote:
    > <> schreef in berichtnieuws
    >
    > > I am confused about the methods by which C passes things to
    > > other routines. If I have a routine,

    >
    > [Snip]
    >
    > > Now I have a problem with this: SP will be pointing to the
    > > last argument on the stack that was pushed by the caller. I've
    > > looked at assembly listings and I can't seem to find any
    > > section that is responsible for actually removing those
    > > arguments from the stack once they've been pushed.

    >
    > There are two way's to handle the arguments that where pushed
    > onto the stack before a routine is called :
    > 1) The routine itself removes them off the stack.
    > 2) the program that calls the routine removes them off the
    > stack.
    >
    > if 1) is used, you will probably see that the RETF command of
    > the routine allso has a number behind it. Like : RETF 4 ->
    > return and add 4 to the stack-pointer (removing 4 bytes off
    > the stack)
    >
    > In the case of 2), you will notice a "ADD SP,{value}" command,
    > just below the call to the routine. the {value}should equal
    > the number of bytes pushed.


    This is still OT for c.l.c. In addition, as others have pointed
    out, there need not be any stack, or stack use, whatsoever. Even
    if a stack and method 2 is used there is no need to clean up
    immediately. Some code generators postpone stack cleanup to a
    convenient point. No C system is required to have a RETF or an
    "ADD SP,(value)" instruction. My Microdata 810 certainly doesn't.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Sep 29, 2003
    #9
  10. R.Wieser Guest

    CBFalconer <> schreef in berichtnieuws
    ...

    Hello CB,

    > This is still OT for c.l.c. In addition, as others have
    > pointed out, there need not be any stack, or stack
    > use, whatsoever.


    1) if this is OT, than your own "in addition" is certainly too ... Tsk, tsk.
    :-\

    2) If parameters are transferred by pushing them on a stack (as the OP
    describes), that stack should bloody well be there :)

    > Even if a stack and method 2 is used there is no
    > need to clean up immediately.


    Ofcourse. But would your "explanation" add something to the comprehension
    of the matter with the novice the answer was aimed at ? Or are you out to
    complicate matters ? Maybe even initiate a (pardon my language)
    pissing-contest ?

    > Some code generators postpone stack cleanup to a
    > convenient point. No C system is required to have a RETF or an
    > "ADD SP,(value)" instruction. My Microdata 810 certainly doesn't.


    Jup, it's a pissing-contest allready :-(((

    Man, get a *life* for gods sake ! Having problems with what others do, but
    nevertheless adding to them yourself. Bad show I would say.

    And please learn to read a message (the OP's) before you answer it ... It
    should save you some embarrassment.

    Regards,
    Rudy Wieser
     
    R.Wieser, Sep 29, 2003
    #10
  11. Mike Wahler Guest

    Re: [OT] Parameters and the Stack

    "R.Wieser" <> wrote in message
    news:3f789adc$0$31496$4all.nl...
    > CBFalconer <> schreef in berichtnieuws
    > ...
    >
    > Hello CB,
    >
    > > This is still OT for c.l.c. In addition, as others have
    > > pointed out, there need not be any stack, or stack
    > > use, whatsoever.

    >
    > 1) if this is OT, than your own "in addition" is certainly too ... Tsk,

    tsk.
    > :-\


    I don't think so. I think he explained *why* OP's
    query is OT.

    >
    > 2) If parameters are transferred by pushing them on a stack (as the OP
    > describes), that stack should bloody well be there :)


    But 'stack' is not part of the language. OP was observing
    and asking about behavior of a given *implementation*, not
    the language itself. Particular implementations are not
    topical here, only the language.

    >
    > > Even if a stack and method 2 is used there is no
    > > need to clean up immediately.

    >
    > Ofcourse. But would your "explanation" add something to the comprehension
    > of the matter with the novice the answer was aimed at ? Or are you out

    to
    > complicate matters ? Maybe even initiate a (pardon my language)
    > pissing-contest ?
    >
    > > Some code generators postpone stack cleanup to a
    > > convenient point. No C system is required to have a RETF or an
    > > "ADD SP,(value)" instruction. My Microdata 810 certainly doesn't.

    >
    > Jup, it's a pissing-contest allready :-(((


    I don't think so. I think he's trying to clarify things
    for OP.

    >
    > Man, get a *life* for gods sake !


    A very common utterance by those who don't understand,
    or simple refuse to accept reality.

    >Having problems with what others do,


    When folks post off topic in a topical forum, it is
    indeed a problem. This is why we point it out when
    something is OT, so that the OP and anyone else
    reading becomes informed.

    > but
    > nevertheless adding to them yourself.


    I don't see any additional problems, only an attempt
    to correct one, and hopefully prevent future ones.

    >Bad show I would say.


    Good show I say. Chuck informed OP about OT-nes,
    and gave a simple example to illustrate why.


    >
    > And please learn to read a message (the OP's) before you answer it ...


    Chuck's reply indicates to me that he *did* read the message.
    I find his words quite appropriate to the situation.

    >It
    > should save you some embarrassment.


    Go look in a mirror. :)

    -Mike
     
    Mike Wahler, Sep 29, 2003
    #11
  12. On Mon, 29 Sep 2003 22:42:29 +0200
    "R.Wieser" <> wrote:

    :Jup, it's a pissing-contest allready :-(((

    And therefore, it has been placed on the Robomoderator's "suspicious
    subjects" list. So play nice. :)

    -- The Moderator
     
    Charles A. Crayne, Sep 29, 2003
    #12
  13. In comp.lang.asm.x86 CBFalconer <> wrote:
    > "R.Wieser" wrote:
    >> There are two way's to handle the arguments that where pushed
    >> onto the stack before a routine is called :
    >> 1) The routine itself removes them off the stack.
    >> 2) the program that calls the routine removes them off the
    >> stack.


    > This is still OT for c.l.c. In addition, as others have pointed
    > out, there need not be any stack, or stack use, whatsoever. Even


    Perhaps I can bring it a bit closer to c.l.c and clax86:

    `c` permits variable numbers of perameters in a fn call.
    `printf` is an excellent example.

    If there is a hardware stack as on x86, it is more robust
    the caller adjust it (2 above via add esp,NPARMS) than the
    callee adjust it (1 above via ret NPARMS). The caller is
    more likely to get it right and is less bug-sensitive:

    printf ("%d one bug %d", i);

    will likely crash the caller when it tried to return if
    `printf` has done stack adjustment. If the caller does
    adjustment, the printf will just print i & it's return addr.

    -- Robert
     
    Robert Redelmeier, Sep 30, 2003
    #13
  14. "Bertrand Mollinier Toublet"
    <> wrote in message
    news:bl80ln$95nll$-berlin.de...
    > wrote:


    > > I am confused about the methods by which C passes things to other
    > > routines. If I have a routine,
    > >

    > The "method by which C passes things to other routines" is not
    > specified. Every implementor is free, from the C standard's point of
    > view, to implement it as they please.


    Well, not completely free. C's use of functions with a variable number of
    arguments limits it somewhat.

    For example, a convention where the called routine pops the arguments off
    the stack, while assuming that the number of arguments agrees with the
    number in the function definition would not work. The called routine must
    be able to get to earlier arguments to determine the number of arguments,
    which is one reason for the right to left push of the arguments on the
    stack.

    (I believe it is legal to use a different calling convention for varargs
    functions and normal functions, but it is more convenient not to do that.)

    Note that the IBM S/370 doesn't have a stack, and the normal calling
    convention doesn't require one.

    Whether or not a particular calling convention was compatible with the
    requirements of C should be on topic. The advantages or disadvantages might
    also be. The ability to call subprograms in other languages, or to call C
    functions from other languages might be.

    -- glen
     
    Glen Herrmannsfeldt, Sep 30, 2003
    #14
  15. Guest

    Thanks everyone! That was very helpful. Adding to SP to remove
    arguments turned out to be the method employed.

    -HG.
     
    , Sep 30, 2003
    #15
  16. Mark Gordon Guest

    On Tue, 30 Sep 2003 02:26:53 GMT
    "Glen Herrmannsfeldt" <> wrote:

    > "Bertrand Mollinier Toublet"
    > <> wrote in message
    > news:bl80ln$95nll$-berlin.de...
    > > wrote:

    >
    > > > I am confused about the methods by which C passes things to other
    > > > routines. If I have a routine,
    > > >

    > > The "method by which C passes things to other routines" is not
    > > specified. Every implementor is free, from the C standard's point of
    > > view, to implement it as they please.

    >
    > Well, not completely free. C's use of functions with a variable
    > number of arguments limits it somewhat.
    >
    > For example, a convention where the called routine pops the arguments
    > off the stack, while assuming that the number of arguments agrees with
    > the number in the function definition would not work. The called
    > routine must be able to get to earlier arguments to determine the
    > number of arguments, which is one reason for the right to left push of
    > the arguments on the stack.


    The called routine does not need to be able to determine the number of
    arguments, only where to find them. One option if using a stack and
    pushing the left most argument first is to leave a register pointing to
    the first argument. Another is to leave a register pointing to the last
    argument before the varargs.

    > (I believe it is legal to use a different calling convention for
    > varargs functions and normal functions, but it is more convenient not
    > to do that.)


    It is legal to use different calling conventions for every individual
    function as long as the compiler/linker make it all tie up at the end of
    the day.

    > Note that the IBM S/370 doesn't have a stack, and the normal calling
    > convention doesn't require one.
    >
    > Whether or not a particular calling convention was compatible with the
    > requirements of C should be on topic. The advantages or disadvantages
    > might also be. The ability to call subprograms in other languages, or
    > to call C functions from other languages might be.


    Calling conventions are completely OT for this group because they are
    entirely implementation dependant. If you want to discuss the merits of
    different calling conventions you either want a group dealing with
    writing compilers or a group for a specific processor (since the "best"
    convention will depend on the details of the processor).
    --
    Mark Gordon
    Paid to be a Geek & a Senior Software Developer
    Although my email address says spamtrap, it is real and I read it.
     
    Mark Gordon, Sep 30, 2003
    #16
  17. On Tue, 30 Sep 2003 10:30:45 +0100
    Mark Gordon <> wrote:

    :Calling conventions are completely OT for this group because they are
    :entirely implementation dependant.

    Please note that the phrase "for this group" is a meaningless referent,
    because there is no way for a reader to determine which newsgroup you are
    posting from.

    -- clax86 moderator
     
    Charles A. Crayne, Sep 30, 2003
    #17
  18. Mark Gordon Guest

    On Tue, 30 Sep 2003 11:30:07 -0700
    "Charles A. Crayne" <> wrote:

    > On Tue, 30 Sep 2003 10:30:45 +0100
    > Mark Gordon <> wrote:
    >
    > :Calling conventions are completely OT for this group because they are
    > :entirely implementation dependant.
    >
    > Please note that the phrase "for this group" is a meaningless
    > referent, because there is no way for a reader to determine which
    > newsgroup you are posting from.


    Sorry, I missed the cross-post. Calling conventions are OT in
    comp.lang.c, over in comp.lang.asm.x86 I can see that they could be on
    topic.
    --
    Mark Gordon
    Paid to be a Geek & a Senior Software Developer
    Although my email address says spamtrap, it is real and I read it.
     
    Mark Gordon, Oct 1, 2003
    #18
  19. R.Wieser Guest

    <> schreef in berichtnieuws
    ...

    Hello HG,

    > Thanks everyone! That was very helpful. Adding to SP to remove
    > arguments turned out to be the method employed.


    I'm glad our answers helped. Thanks for telling us :)

    Regards,
    Rudy Wieser
     
    R.Wieser, Oct 1, 2003
    #19
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Surinder Singh
    Replies:
    1
    Views:
    1,255
    Richard Bos
    Dec 20, 2007
  2. Casey Hawthorne
    Replies:
    3
    Views:
    1,158
    Flash Gordon
    Nov 1, 2009
  3. Debajit Adhikary
    Replies:
    36
    Views:
    2,411
    Andre Kaufmann
    Feb 10, 2011
  4. Sam Roberts
    Replies:
    1
    Views:
    239
    Yukihiro Matsumoto
    Feb 11, 2005
  5. Kenneth McDonald

    Why stack overflow with such a small stack?

    Kenneth McDonald, Aug 30, 2007, in forum: Ruby
    Replies:
    7
    Views:
    292
    Kenneth McDonald
    Sep 1, 2007
Loading...

Share This Page