12
votes

I'm learning Assembly language. What exactly is argument push order? i understand its how arguments are pushed to the stack but what does the left and right part mean? left or right of what? Or is this merely to do with the way the command is semantically written, i.e.:

mov ebp, esp ;esp is moved into ebp, right to left.

Is this correct or could someone enlighten me?

Many thanks!

2

2 Answers

16
votes

The processor knows no 'function arguments'. Therefore when you want to write f(a,b,c), you really need to push the arguments 'somewhere'.

This is convention. I know that on most x86 machines, function arguments are pushed on the stack from right to left, i.e. first c, then b, then a.

push c
push b
push a
call f

Now the called function can use ebx -1 for a, ebx - 2 for b and ebx - 3 for c.

You could as well establish a convention that says: first two arguments are in registers ebx and ecx, rest are on the stack. As long as the caller and callee agree, you're fine.

12
votes

In addition to xtofl's explanation you might like to have a look at this table of x86 calling conventions. What you'll note, with regards to argument order is that almost all of the arguments are pushed on right to left (rightmost argument is pushed first) with the exception of Pascal.

Another scenario xtofl doesn't cover are register arguments - some ABIs require that some arguments are in registers as opposed to on the stack. On a x86_64 system, for example, the function:

int add3(int a, int b, int c)

will put arguments:

a -> rdi
b -> rsi
c -> rdx

Specifically, this would look like (Intel syntax):

mov     rdi, [source-of-a]
mov     rsi, [source-of-b]
mov     rdx, [source-of-c]
call    add3

So the registers are filled up from the register list left to right and then the stack is used right to left.

As xtofl says, it doesn't matter what you do provided the caller and the callee agree - clearly, however, if the caller and the callee disagree that'll cause incompatibility problems and this is actually a concern not only for assembler, but for higher level languages too - luckily, compilers largely operate right to left. For further reading, you might find the callee/caller cleanup of the stack interesting - and note how it was standardised to one method for x86_64.

You don't say you're using x86 - your architecture will most certainly have a standard calling convention as working without it is difficult.