More Functions and the Stack

Slides:



Advertisements
Similar presentations
1 Lecture 3: MIPS Instruction Set Today’s topic:  More MIPS instructions  Procedure call/return Reminder: Assignment 1 is on the class web-page (due.
Advertisements

Branches Two branch instructions:
1 Procedure Calls, Linking & Launching Applications Lecture 15 Digital Design and Computer Architecture Harris & Harris Morgan Kaufmann / Elsevier, 2007.
ECE 232 L6.Assemb.1 Adapted from Patterson 97 ©UCBCopyright 1998 Morgan Kaufmann Publishers ECE 232 Hardware Organization and Design Lecture 6 MIPS Assembly.
10/6: Lecture Topics Procedure call Calling conventions The stack
Procedure Calls Prof. Sirer CS 316 Cornell University.
Ch. 8 Functions.
Procedures II (1) Fall 2005 Lecture 07: Procedure Calls (Part 2)
Apr. 12, 2000Systems Architecture I1 Systems Architecture I (CS ) Lecture 6: Branching and Procedures in MIPS* Jeremy R. Johnson Wed. Apr. 12, 2000.
The University of Adelaide, School of Computer Science
Procedure call frame: Hold values passed to a procedure as arguments
CSCI-365 Computer Organization Lecture Note: Some slides and/or pictures in the following are adapted from: Computer Organization and Design, Patterson.
MIPS Coding. Exercise – the bubble sort 5/8/2015week04-3.ppt2.
Register Conventions (1/4) °CalleR: the calling function °CalleE: the function being called °When callee returns from executing, the caller needs to know.
CS 536 Spring Code generation I Lecture 20.
20/06/2015CSE1303 Part B lecture notes 1 Functions, part 2 Lecture B15 Lecture notes, section B15.
Intro to Computer Architecture
CS-2710 Dr. Mark L. Hornick 1 Defining and calling procedures (subroutines) in assembly And using the Stack.
Computer Organization CS345 David Monismith Based upon notes by Dr. Bill Siever and notes from the Patterson and Hennessy Text.
Slides revised 3/25/2014 by Patrick Kelley. 2 Procedures Higher Level languages have adopted a standard Referred to as C-style calling Uses the stack.
Lecture 18: 11/5/2002CS170 Fall CS170 Computer Organization and Architecture I Ayman Abdel-Hamid Department of Computer Science Old Dominion University.
Lecture 19: 11/7/2002CS170 Fall CS170 Computer Organization and Architecture I Ayman Abdel-Hamid Department of Computer Science Old Dominion University.
Procedure Basics Computer Organization I 1 October 2009 © McQuain, Feng & Ribbens Procedure Support From previous study of high-level languages,
Procedure (Method) Calls Ellen Spertus MCS 111 September 25, 2003.
Lecture 4: MIPS Instruction Set
Computer Architecture CSE 3322 Lecture 4 crystal.uta.edu/~jpatters/cse3322 Assignments due 9/15: 3.7, 3.9, 3.11.
Function Calling. Mips Assembly Call and Return Steps for procedure calling –Save the return address –Jump to the procedure (function) –Execute the procedure.
Computer Organization CS345 David Monismith Based upon notes by Dr. Bill Siever and notes from the Patterson and Hennessy Text.
Function Calls in Assembly MIPS R3000 Language (extensive use of stack) Updated 7/11/2013.
Programs – Calling Conventions
Computer Science 210 Computer Organization
Computer structure: Procedure Calls
Lecture 5: Procedure Calls
Prof. Hsien-Hsin Sean Lee
Pseudo-ops and Bitwise Operations
Functions and the Stack
Function Calls in MIPS To call a function: jal func
© Craig Zilles (adapted from slides by Howard Huang)
Procedures 101: There and Back Again
CSCI206 - Computer Organization & Programming
MIPS Procedures.
CS/COE 0447 (term 2181) Jarrett Billingsley
Procedures (Functions)
The Interconnect, Control, and Instruction Decoding
CS41B recursion David Kauchak CS 52 – Fall 2015.
CSCI206 - Computer Organization & Programming
CSCI206 - Computer Organization & Programming
MIPS Procedures.
Programs – Calling Conventions
Bitwise Operations and Bitfields
Arrays, Control flow, and Loops
MIPS Procedure Calls CSE 378 – Section 3.
MIPS Functions.
MIPS Functions.
Lecture 5: Procedure Calls
MIPS Procedures.
Review.
10/4: Lecture Topics Overflow and underflow Logical operations
MIPS function continued
MIPS Functions.
Program and memory layout
Procedures and Calling Conventions
Conditionals and Functions
Where is all the knowledge we lost with information? T. S. Eliot
Program and memory layout
© Craig Zilles (adapted from slides by Howard Huang)
MIPS Functions.
MIPS function continued
MIPS Functions.
Topic 2b ISA Support for High-Level Languages
Presentation transcript:

More Functions and the Stack CS/COE 0447 Jarrett Billingsley

Class announcements uh CS447

Passing arguments and returning values CS447

How did you write syscalls? a syscall is a weird kind of call, but when you pass an argument… what register(s) do you put them in? and when you get a value back (like the "read int" syscall in lab 2)… what register do you get the value back in? a0-a3 are the argument registers v0-v1 are the return value registers this is just a convention, there's no special features for them - arguments go in a0, a1 etc - return values come back in v0, v1 CS447

Well that's what we do v0 a0 a1 int gcd(int a, int b) { if we have a function in a higher level language… v0 a0 a1 the two arguments will come in in a0 and a1. int gcd(int a, int b) { while(a != b) { if(a > b) a -= b; else b -= a; } return a; for this, just put the value you want to return in v0 before jr ra. CS447

int add_nums(int x, int y) {return x + y;} Input, output let's write a function like this: int add_nums(int x, int y) {return x + y;} inside of our add_nums asm function… which register represents x? which register represents y? which register will hold the sum that we return? add_nums: add __, __, __ v0 a0 a1 jr ra - x = a0 - y = a1 - return value will go into v0 CS447

Calling that function li a0, 3 print(add_nums(3, 8)) li a1, 8 now let's make main do this: print(add_nums(3, 8)) how do we set 3 and 8 as the arguments? how do we call add_nums? afterwards, which register holds the sum? so how can we print that value? why do syscalls put the number of the syscall in v0? well what do you get when you cross an elephant and a rhino? hell if I know li a0, 3 li a1, 8 jal add_nums move a0, v0 li v0, 1 syscall - and what's worse, SOME SYSCALLS RETURN VALUES IN THE A REGISTERS, LIKE WHAT THE FUCK????? CS447

The Call Stack CS447

One busy desk there's a tiny desk that three people have to share person 1 is working at the desk. it's covered in their stuff. person 2 interrupts them and needs to do some important work what does person 2 do with the stuff? throw it in the trash? they put it somewhere else. P1 P1 what if person 2 didn't move person 1's stuff and started scribbling all over it? Trash P1 P1 - kind of a weird metaphor but just go with it, okay? - if person 2 did that, that would be a really dick move. - and it'd mess up person 1's work. - (HINT HINT) CS447

One busy desk P2 P2 P1 now person 2 is interrupted by person 3. when person 3 is done, person 2 will come back. where do we put person 2's stuff? on top of the stack of stuff. the desk is the registers. the people are functions. the stack of stuff is… the stack. P2 P2 P2 P2 P1 P1 CS447

What's the stack? Stack Memory it's an area of memory provided to your program by the OS when your program starts, it's already there the stack is holds information about function calls: the return address to the caller copies of registers that we want to change local variables/arguments that can't fit in registers how do we access the stack? through the stack pointer (sp) register Memory Stack - check out the sp register when your program first starts – it's already initialized to a value CS447

The stack pointer (animated) let's say sp starts at the address 0xF000 we want to push something on the stack the first thing we'll do is move sp to the next available slot clearly, that's the previous address subtract 4 from sp then, we can store something in the memory that sp points to. ... 0xF008 0x00000000 0xF004 0xF000 sp 0xEFFC 0x00000000 0xC0DEBEEF - we say the stack "grows down" from higher addresses to lower ones - this is a common way for call stacks to work - cause now all the offsets to things on the stack are positive offsets from sp, rather than negative CS447

Doing that in MIPS (animated) say ra = 0xC0DEBEEF first: move the stack pointer down (up?): sub sp, sp, 4 then, store ra at the address that sp holds. sw ra, (sp) now the value in ra is saved on the stack, and we can get it back later. and we can store as many return addresses as we want! ... 0xF008 0x00000000 0xF004 0xF000 sp 0xEFFC 0x00000000 0xC0DEBEEF - remember stores copy from left to right, and (sp) means "into memory at the address held in sp" CS447

Going the other direction (animated) now we wanna pop the value off the stack and put it back in ra we do the same things, but in reverse what's the opposite of sw? lw ra, (sp) what's the opposite of sub? add sp, sp, 4 now we got back the old value of ra! and sp is back where it was before! ra 0xABAD1DEA 0xC0DEBEEF ... 0xF008 0x00000000 0xF004 0xF000 sp 0xEFFC 0xC0DEBEEF making sure sp ends up where it started is called "balancing the stack." - if you don't balance the stack, that's like leaving junk on the stack of stuff before you leave the desk… - and the person who comes back to it won't be able to find their stuff. it's super important, OK? CS447

Shortening the pushes and pops the push and pop operations always look and work the same since you'll be using them in most functions, I shortened em if you write push ra or pop ra, it'll do these things for you! sub sp, sp, 4 sw ra, (sp) push ra lw ra, (sp) add sp, sp, 4 pop ra these are pseudo-ops: fake instructions to shorten common tasks these can be used with ANY register, not just ra! - there are many pseudo-ops… many of the instructions you'll use are! - they make coding in assembly a little more bearable. CS447

Toes = protected ra PC 0x8000 jal fork fork: 0x8020 push ra 0x8028 jal spoon 0x802C pop ra 0x8034 jr ra spoon: 0x8040 sp 0x8004 stuff 0x8000 0x0000 After jal fork: 0x8020 0x8004 Then we push ra on the stack! After jal spoon: 0x8040 0x802C After spoon jr ra: 0x802C 0x802C Then we pop ra off the stack! Before fork jr ra: 0x8034 0x8004 After fork jr ra: 0x8004 0x8004 CS447

Writing a simple function Writing a function is actually pretty easy: spoon: 1. Give it a name (label). push ra 2. Save ra to the stack. your code goes here 3. Do whatever. 4. Load ra from the stack. pop ra 5. Return! jr ra You only have to push/pop ra once in each function! ONLY PUSH/POP REGISTERS AT THE BEGINNINGS AND ENDS OF FUNCTIONS CS447

Doing a simple function call On the caller side… 1. Put the arguments in the ax registers. li a0, 1 lw a1, some_var 2. Call the function. jal spoon 3. if it returns values, look at the vx registers. beq v0, 0, blahhhh CS447

Saved and Unsaved registers CS447

Lah dee daa .data counter: .word 0 .text increment: la t0, counter let's make a variable and a function to change it .data counter: .word 0 .text increment: la t0, counter lw t1, (t0) add t1, t1, 1 sw t1, (t0) jr ra then we can call it main: jal increment CS447

Everything's just fine, right? let's write a loop that calls it ten times in a row so we need a loop counter ('i' in a for loop) li t0, 0 # our counter loop_begin: jal increment add t0, t0, 1 blt t0, 10, loop_begin loop_end: if we run this, it only increments the variable once. why? let's put a breakpoint on blt and see what it sees. (another way to write a for loop) CS447

Scribbling on someone else's notes both functions are trying to use t0 for different purposes but there's only ONE t0! the increment function is in the clear the problem is actually the loop this is one of the contracts between the caller and the callee… a caller cannot depend on the t, a, or v registers to have the same values after a jal as before it. or to put it another way, callees are allowed to trash those registers. CS447

Another piece of the calling convention puzzle when you call a function, it's allowed to change some registers but other registers must be left exactly as they were functions are required to put these registers back the way they were before they were called. anyone can change these. after you call a function, they might have totally different values from before you called it. Saved s0-s7 sp ra* Unsaved v0-v1 a0-a3 t0-t9 *ra is a little weird cause it's kinda "out of sync" with the other saved regs but you DO save and restore it like the others CS447

Whenever you call a function… after a jal, you have no idea what's in these registers. ... jal increment Unsaved v0-v1 a0-a3 t0-t9 could be nonsense! garbage! bogus! CS447

Why it broke li t0, 0 loop_begin: jal increment add t0, t0, 1 if we look at this code again… t0 is our loop counter and everything's fiiiine. li t0, 0 loop_begin: jal increment add t0, t0, 1 blt t0, 10, loop_begin loop_end: uh oh. WHAT IS IN t0 NOW?? instead, this is a great place to use an s register. CS447

The fixed version li s0, 0 loop_begin: jal increment add s0, s0, 1 if we use an s register… s0 is our loop counter and everything's fiiiine. li s0, 0 loop_begin: jal increment add s0, s0, 1 blt s0, 10, loop_begin loop_end: uh oh. oh whew, we used an s register, it's fine. but s registers aren't magic. they don't do this automatically. CS447

The s register contract if your function wants to use an s register… you must save and restore it, just like ra. my_func: push ra push s0 pop s0 pop ra jr ra moving the papers off the desk code that uses s0! it's fine! we saved it! the pops happen in reverse order! putting the papers back CS447

Oh, and… my_func: push ra push s0 ... bge ... b exit_func exit_func: you must always pop the same number of registers that you push. to make this simpler for yourself… make a label before the pops. then you can leave the function by jumping/branching there. my_func: push ra push s0 ... bge ... b exit_func exit_func: pop s0 pop ra jr ra CS447