12

Why are function arguments pushed on the stack in right to left order?

Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
Rajendra Uppal
  • 19,218
  • 15
  • 59
  • 57
  • @Some platforms (ARM and PowerPC) push some functions into registers and they may never appear on the stack. – doron Oct 27 '10 at 14:24

2 Answers2

19

To enable the existence of functions with a variable number of arguments, like printf. The function can extract the first one or two arguments and then use their values to deduce the total number of arguments on the stack.

Eugene Smith
  • 9,126
  • 6
  • 36
  • 40
  • 10
    I should mention that there's nothing in the C standard that requires this (in fact, I don't think it even _requires_ a stack). You could just as easily push them in the other order followed by a count so that you could find the first one (brain-dead though that implementation would be). Don't take this as criticism of your answer since you're dead right. + 1. – paxdiablo Oct 27 '10 at 09:17
  • 1
    The number of arguments may be passed in registers, and even normal parameters can also be passed in registers. Or you can just push the count last regardless of the parameters. So it doesn't matter which order you use – phuclv Sep 09 '14 at 13:13
  • @phuclv: correctness is *possible* that way, but it does matter for efficiency. C doesn't require a side-channel for functions to know how many args they received, and if you're not getting any other advantage out of it, it's clearly worse to need a `mov reg, immediate` before every call (or every unprototyped or variadic call) to indicate the number of args, or the number of *bytes* of args; remember they can be different sizes. (x86-64 SysV requires the number of FP args in XMM regs for possibly-variadic function calls, with the upside being many more possible FP/integer args in regs.) – Peter Cordes Aug 06 '22 at 09:45
  • Re: efficiency and extra work in the caller defeating the purpose, see [Why can't stdcall handle varying amounts of arguments?](https://stackoverflow.com/a/73055218) – Peter Cordes Aug 06 '22 at 09:46
11

The only reason is for variadic functions: the first arguments popped from the stack are the "known" ones for the function, and it can determine from them how many other arguments it should read from the stack.

Notice that, for this to work fine, in such calling conventions the stack cleanup is left to the caller, that knows how many arguments it pushed on the stack. This is slightly less efficient than callee-cleanup, because the cleanup code has to be written after each function call, while in calling conventions that do not allow variadic functions it can be embedded at the end of each function.

Other than this, there's no particular reason, in facts there are several calling conventions (e.g. Pascal, Borland Fastcall) that do not admit variadic functions and push parameters left to right.

Matteo Italia
  • 123,740
  • 17
  • 206
  • 299