How is the return address listed on the stack?

This is what I see, parsing function(1,2,3); for the operator function(1,2,3); :

 movl $0x3,0x8(%esp) movl $0x2,0x4(%esp) movl $0x1,(%esp) call 0x4012d0 <_Z8functioniii> 

It seems that the ret address didn't hit the stack at all, then how does ret work?

+7
assembly stack calling-convention
source share
4 answers

Ideally, the call operator should take care of this. The next program counter will be pushed onto the stack. When the function (subroutine) that was called terminates, and when it encounters a return statement, the control now goes to the address that was inserted on the stack and it will pop up.

+5
source share

On the x86 processor (as in the assembler language example), the call command pushes the return address onto the stack and transfers control to this function.

Not all processor architectures push the return address onto the stack β€” often there is a set of one or more registers for storing return addresses. On ARM processors, the BL command places the return address in a specific register ( LR or "reference register") and transfers control to the function. The ia64 processor does something similar, except that there are several possible registers ( b0 - b7 ) that can accept a return address, and one will be specified in the instruction (with b0 by default).

+5
source share

It depends on the ABI and architecture, but if the return address ends on the stack, this is a side effect of the call command that puts it there.

+3
source share

a call pushes the current value of the RIP register (return address) onto the stack + a call is made
ret outputs the return address (which the call is pressed) from the top of the stack (RSP registers are registered there) and writes it to the RIP register.

GNU / Linux box example: the f function calls the g function and allows you to look at the g frame.

LOW ADDRESS

... <- RSP (the stack pointer shows the top of the stack) registers points at this address
g local vars
f base pointer (old RBP value) <- RBP (base pointer) registers points at this address
f ret address (old RIP value) (this is what pressed the call (from f) and what ret (from g) will appear)
args that f is called g c and does not fit into registers (I think on Windows it is different)
...

HIGH ADDRESS

g will free local vars (movq% rsp,% rbp)
g "old RBP" appears and stores it in the RBP register (pop% rbp)
g will be ret , which will change the RIP with a value that is stored where the RSP points to

Hope this helps

+1
source share

All Articles