2.1 Order of pushing

Many functions require more than one parameters. If all parameters are pushed on the stack, then the order of pushing is important. The order of pushing parameters on the stack affects the relative offsets among the parameters, which in return affects how the subroutine can access the parameters.

While the order may seem to be somewhat “arbitrary” (like the choice of little endian versus big endian), it is not arbitrary. This is because the C programming language supports a variable number of parameters.

For example, consider the following function:

int sumInts(int first,...) 
{ 
  int sum = first; 
  int *pNum = &first; 
  while (*pNum <> 0) 
  { 
    sum += *(pNum++); 
  } 
  return sum; 
}

This function adds all the parameters and returns the sum. The adding stops when it encounters the first parameter that is 0. Yes, this is bad programming practice, but it gets the point across.

To utilize this function, a caller can do something similar to the following:

sum = sumInts(2,3,6,1,10,23,0);

The usage of variable number of parameters imposes a specific ordering of parameters in memory. The first parameter must have the lowest address, and the last parameter must have the highest address. This order (in terms of memory locations), in return, implies that the order of pushing is reversed.

The last parameter is pushed first, and the first parameter is pushed last. Remember that the stack grows down?

Hence, in this example, the caller’s code (to pass parameters can invoke the subroutine) should be as follows:

pushl $
pushl $23 
pushl $10 
pushl $
pushl $
pushl $
pushl $
call sumInts 
addl $4*7,%esp # reclaim the space used by parameters