0
votes

Let's say we have an array of 16 bytes, and some 4 byte integer. Before calling a function, we push the array onto the stack; then we push the integer.

Now, it is my understanding that "below" the base pointer is the return address and the parameters; right above, and "below" our stack pointer at the top, are local variables we've pushed onto the stack (and registers).

How would one figure out where the starting address of the array is, as well as the integer? Would it be accurate to simply do "ebp - 16" for the array, -20 for the integer, or is there a detail I'm missing? Could we also reference these things relative to esp, or is that unconventional?

Additionally, are there implementations that might handle this addressing differently?

And lastly, is it necessary to pop these things from the stack before our function ends?

2

2 Answers

1
votes

You push the address of the array, not the entire contents of the array.

The size of this address is 4 bytes on a 32-bit system and 8 bytes on a 64-bit system.

Since you know what system you're using, calculating the address of each argument is easy.


The last thing "left on the stack" before the function returns is... the returned value.

So yes, everything other than that is popped out of the stack before the function returns.

As a side note, some compilers pass some of the arguments via registers rather than the stack.

1
votes

"Pushing" means: Subtracting the size of the element pushed from ESP and then writing the element to the memory at ESP. When calling a function the "return address" is pushed.

This means: The return address will be located at ESP+0, the integer at ESP+4 and the first byte of the array at ESP+8 when the function is entered.

It is up to the called function to initialize the EBP register. Typically EBP will be initialized to the original value of ESP minus 4 so the integer is located at EBP+8 and the array at EBP+12 (decimal). Typically the following code is used:

push EBP    ; Save on stack so the old value can be restored later
mov EBP,ESP ; Initialize the EBP register

However - once again - if the calling function does not initialize the EBP register it has no useful value.

The programmer programming the function (or the compiler that compiled the C code) has to know which data is on the stack and where this data is located. So there is no possibility to "find out" where the data is but you have to design the program in a way that the data is located at a given address.

Btw.: User "barak manos" is right when he says that normally you push an address of an array, not an array itself. However there are few exceptions where the content of an array are pushed onto the stack (for example the function "WinUsb_ControlTransfer").