473,405 Members | 2,176 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,405 software developers and data experts.

Parameters and the Stack

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.

Nov 13 '05 #1
18 2637
IM**********@spammotel.com 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
Nov 13 '05 #2
<IM**********@spammotel.com> wrote in message
news:b4*************************@posting.google.co m...
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
Nov 13 '05 #3
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

<IM**********@spammotel.com> wrote in message news:b4*************************@posting.google.co m...
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.

Nov 13 '05 #4
On 28 Sep 2003 14:37:10 -0700, IM**********@spammotel.com 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

Nov 13 '05 #5
<IM**********@spammotel.com> schreef in berichtnieuws
b4*************************@posting.google.com...
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


Nov 13 '05 #6
IM**********@spammotel.com 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-newsgrou...mp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambl...me_to_clc.html

Nov 13 '05 #7
"R.Wieser" wrote:
<IM**********@spammotel.com> 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 (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #8
IM**********@spammotel.com 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
Nov 13 '05 #9
CBFalconer <cb********@yahoo.com> schreef in berichtnieuws
3F***************@yahoo.com...

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


Nov 13 '05 #10

"R.Wieser" <rw***************@xs4all.nl> wrote in message
news:3f***********************@dreader3.news.xs4al l.nl...
CBFalconer <cb********@yahoo.com> schreef in berichtnieuws
3F***************@yahoo.com...

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
Nov 13 '05 #11
On Mon, 29 Sep 2003 22:42:29 +0200
"R.Wieser" <rw***************@xs4all.nl> 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
Nov 13 '05 #12
In comp.lang.asm.x86 CBFalconer <cb********@yahoo.com> 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

Nov 13 '05 #13

"Bertrand Mollinier Toublet"
<be*****************************@enst-bretagne.fr> wrote in message
news:bl************@ID-168218.news.uni-berlin.de...
IM**********@spammotel.com 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
Nov 13 '05 #14
Thanks everyone! That was very helpful. Adding to SP to remove
arguments turned out to be the method employed.

-HG.

Nov 13 '05 #15
On Tue, 30 Sep 2003 02:26:53 GMT
"Glen Herrmannsfeldt" <ga*@ugcs.caltech.edu> wrote:
"Bertrand Mollinier Toublet"
<be*****************************@enst-bretagne.fr> wrote in message
news:bl************@ID-168218.news.uni-berlin.de...
IM**********@spammotel.com 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.

Nov 13 '05 #16
On Tue, 30 Sep 2003 10:30:45 +0100
Mark Gordon <sp******@flash-gordon.me.uk> 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

Nov 13 '05 #17
On Tue, 30 Sep 2003 11:30:07 -0700
"Charles A. Crayne" <cc*****@crayne.org> wrote:
On Tue, 30 Sep 2003 10:30:45 +0100
Mark Gordon <sp******@flash-gordon.me.uk> 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.

Nov 13 '05 #18
<IM**********@spammotel.com> schreef in berichtnieuws
b4**************************@posting.google.com...

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


Nov 13 '05 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: John Miles | last post by:
Hi -- This is a bit of an implementation-specific problem, but I'd like to post it here to see if there's a general answer within the auspices of the language. I'm developing a high(er)-level...
5
by: Andy | last post by:
Hi Could someone clarify for me the method parameter passing concept? As I understand it, if you pass a variable without the "ref" syntax then it gets passed as a copy. If you pass a...
22
by: bitshadow | last post by:
using the following code, i was able to have my compiler seg fault on me when i gave the argument as anythng greater than 20,832,000bytes. In the case of the struct its 868 instances of said...
2
by: news.microsoft.com | last post by:
Hi all. If I wanted to write something so that, when an exception was thrown, and the stack unwound, the stack trace was captured with the values of the parameters (instead of just the parameter...
18
by: John Friedland | last post by:
My problem: I need to call (from C code) an arbitrary C library function, but I don't know until runtime what the function name is, how many parameters are required, and what the parameters are. I...
10
by: ypjofficial | last post by:
Hello All, since the programs' stack is shared among all the function inside the program, I was just doing some R&D to see whether the same stack space is used for the variables inside the...
11
by: Googy | last post by:
Hi friends!! As we know that the input parameters in a function is fixed when the function is defined but how does printf processes variable number of input arguments ? For example: 1....
0
by: AxleWacl | last post by:
Hi, The below error is what I am receiving. The code im using is below the error, for the life of me, I can not see where any parameter is missing..... Server Error in '/FleetcubeNews'...
4
by: * Tong * | last post by:
First of all, thanks mlimber for answering my previous question. Now... I'm following the example in "C++ Templates: The Complete Guide", section 5.4 Template Template Parameters, and I'm...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.