Demystify the return address in a stack frame

For the longest time, I’ve wondered how the instruction ret knows the location of the return address. I asked ChatGPT but it was not able to give me a straight answer.

This is copied from ChatGPT’s answer.

The ret Instruction:
When the ret instruction is executed, the CPU: Pops the value from the top of the stack (which is expected to be the return address). Jumps to that address. The ret instruction does not inherently know where the return address is. Instead, it simply pops whatever value is at the top of the stack (which is where the call instruction initially pushed the return address) and jumps to it.

This conflicts with my understanding that during the execution of a function, rsp moves with the amount of local data. Also when protections (stack canary, etc) are enabled, the distance between rbp and rsp can be quite large. So when the ret instruction is executed, the top of the stack, which is pointed to by rsp can not be the return address.

I then noticed another instruction leave right before ret. According to (leave), this instruction

Set %rsp to %rbp , then pop top of stack into %rbp

Ah, so that’s how it works. After this instruction, the caller’s rbp is restored and the return address is exposed as the top of the stack. This also implies that if the callee modifies rbp in any way, all bets are off. To test my theory, I loaded a toy program which calls a simple function from main. While within that function, I deliberately set rbp to a random value and that caused a Segmentation Fault at function return.

In fact, rbp is optional. I can disable the use of rbp by specifying gcc flag omit-frame-pointer. When compiled using this flag, there is no leave, nor pop rbp. Instead, the compiler either makes reference to rsp or makes sure that rsp is modified in such a way before ret that it always points to the return address.




Enjoy Reading This Article?

Here are some more articles you might like to read next:

  • Combine Short Videos from OMSCS
  • Serving a Dynamically Loaded Album from a Cloudflare R2
  • Migration to Cloudflare
  • The first post