The Stack
Objectives
Notes
- This is Jorgensen chapter 9
- The stack is necessary for function calls.
- It allows us to build a place to store function local data
- Remember
- A stack is a data structure
- It holds data in a last-in-first-out manner
- Operations include
- push: add something to the top of the stack
- pop: remove something from the top of the stack
- In general, the stack is a portion of memory shared with the heap.
- Usually the stack is in the high portion of this memory and grows down.
- The heap grows up.
- The stack growing down is sort of counter intuitive to our general notion of a stack
- Just remember, pushing something will decrease the address of the top of the stack.
- And popping something will do the opposite.
- If you think about it, when you are busy you probably employ a stack
- You are working on a task.
- You get an email, so you push the task on the stack and start working on the email
- You have someone stop in, so you push the email and start consulting with the visitor
- You get an important phone call, so you push the visitor (?) and start working on the phone call.
- You finish the phone call, so you return to the visitor (by popping them off the stack)
- You finish the visitor, so you return to the email (by popping them off the stack)
- You finish the email, so you return to your base task. (ya right)
- We use the stack for
- Temporary storage of registers inside a function
- passing parameters
- Storing information necessary for function call maintenance
- Intel supports two instructions for manipulating the stack
-
push operand64 places the operand on the stack and changes the value of the stack pointer by 8
-
pop operand64 removes the operand on the stack and changes the value of the stack pointer by 8
- The operand my not be an immediate.
- When using a the stack, we generate a data structure
- The activation record or the stack frame
- This holds the local temporary data for the current function.
- The beginning of this (high memory) is pointed to by the bp (rbp, ebp, bp)
- The end of this (lower memory) is pointed to by the sp, (rsp, esp, sp)
- A calling convention
- Is a set of agreed on policies so that programs can work together.
- Describes how registers and memory should be used for function calls
- This is where the temporary and preserved registers are defined.
- Our main concern here is that the stack pointer must be 16-byte alligned.
- Or the stack pointer must contain a multiple of 16
- Or it must end in a multiple of 0x10 (0x1000, 0x1010, 0x1020...)
- Or the last digit must be a 0 in hex
- Remember addresses are byes in any case.
- So subtracting 1 from the stack pointer creates a 1 byte "padding" in the stack.
- You can push a byte or a quad word.
- So you will either need to add 8 or 15 to the stack to get it alligned.