Stacks

Consecutive bytes in SRAM, from high addresses down to low.

Attributes

  • Stack Pointer (starts at 0x000 so we have to initialise it to RAMEND (low and high))
  • Bottom (highest address).

We need stacks to do functions with arguments.

(Aside: Functions = a label that we jmp to and return from. They have a stack overhead but don't take up flash space. Macros are expanded out into the whole code each time - no overhead but a space requirement. Also stacks let you overwrite registers by saving them on the stack - macros don't do that.).

Stack Frame

  • Return address (where to jump back to after the rcall)
  • Conflict registers that we had to save (push then pop in inverse order)
  • Paramaters/arguments (saved in registers when we enter the function)
  • Local variables (omg we can have stack space so good)

Function Usage of Stack

  • Epilogue
    • Push on Y and all conflict registers
    • Update size of Y to make space for local variables (In, sbiw, out)
    • Store parameter registers and local variables onto stack!
      • E.g. std Y+1, r22
      • Ldi r20, 6
      • Std Y+2, r20
  • Function Body
    • Do the stuff
  • Prologue
    • Save return value in r25:r24 (or other designated registers)
      • movw r25:r24, r21:r0
    • Update Y to size before local variables
      • adiw r29:r28, 8
    • Pop conflict registers and Y
    • Ret

We have to 'in rd, SPH' or 'out SPL, rd' in order to update it. So we read it in, subi the number of bytes we need for local variables and then out it again.

Call Trees

Trees that graph out the function calls each function makes, so we can see the max stack size needed.

stack%20tree.png