Today's Plan: Write a function and call it Simple, right? Two new instructions: call This will push the instruction pointer onto the stack Then it'll jump to the specified label ret This will pop the instruction pointer off the stack Then it'll jump to the address it just popped off Alright, let's use them "normally": A function that prints "hi" Now we just call it a few times... Can we pop off the instruction pointer and manipulate it? Of course! How about a parameter? We could push it on the stack early Or just put it in a register and remember it's there Return value? Same idea Could do multiple returns? More than one register! Or pop off the instruction pointer, push on values, push on instruction pointer Isn't that kinda invasive? Well...it's all our program Isn't any documented behaviour fine? x86-64 C/Linux calling convention Registers have an order Return value has a register Anything other than the return value might get changed Nothing on the stack will have changed Unless we handed the function the address I kinda like traffic rules If you're writing it and using it, it's yours Do whatever you want with your own code If following C conventions, calling a function is slow 1. Push values we care to keep onto the stack 2. Put the right values in registers for the call 3. Call the function 4. Pop any values we wanted to keep back into registers Some expedients: If calling a few functions, don't bring back pushed values If you don't need a value anymore, don't save it Arrange instructions so parameters end up in the right place Don't pop off values you don't need Like, you might have needed it, but didn't actually need it Caveat: Remember ret will pop Point rsp to the right place, and you'll be ok Should we have an in-class exercise? Add ? feature to the demo we've got at this point