Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS-2710 Dr. Mark L. Hornick 1 Defining and calling procedures (subroutines) in assembly And using the Stack.

Similar presentations


Presentation on theme: "CS-2710 Dr. Mark L. Hornick 1 Defining and calling procedures (subroutines) in assembly And using the Stack."— Presentation transcript:

1 CS-2710 Dr. Mark L. Hornick 1 Defining and calling procedures (subroutines) in assembly And using the Stack

2 Lecture Objectives 1. Define procedure (or subroutine) 2. Explain the MIPS calling convention for procedure calls. 3. Define the term program counter 4. Explain the relationship between the caller and callee in a procedure call 5. Explain the purpose for the stack when invoking procedures 6. Explain the relationship between characters and strings. 7. Explain the three main mechanisms for representing strings in memory. 8. Explain the relationship between the 5 MIPS addressing modes.

3 In Java, a method implements a procedure that can be called from other parts of a program public static void main(String[] args) { int x=1; doSomething(); int y=computeSomething(x); } private static void doSomething() { // no args or return … } private static int computeSomething( int x ){ … doSomething(); … return value; } CS-2710 Dr. Mark L. Hornick 3

4 When a procedure is called, execution jumps to that procedure’s instructions and then returns to the statement following the call public static void main(String[] args) { int x=1; doSomething(); int y=computeSomething(x); } private static void doSomething() { // no args or return … } private static int computeSomething( int x ){ … doSomething(); … return value; } CS-2710 Dr. Mark L. Hornick 4

5 Regardless of the location of the call, when the procedure ends, execution always resumes with the statement following the call public static void main(String[] args) { int x=1; doSomething(); int y=computeSomething(x); } private static void doSomething() { // no args or return … } private static int computeSomething( int x ){ … doSomething(); … return value; } CS-2710 Dr. Mark L. Hornick 5

6 6 Assembly languages support procedures Like methods in Java, procedures in assembly are used to implement instructions that you will call from other parts of a program Like methods, procedures may (or may not) take arguments and may (or may not) return values In assembly, the instructions for a procedure don’t look any different from the rest of the code – the difference is how you jump to that code: jal proc_label # jal: Jump and Link The jal instruction “calls” the procedure beginning at the address represented by the label “proc_label” In a jal call, the address of the next instruction following the call (the jal instruction) is automatically put into $ra – the Return Address register – to “link” it back to the call location.

7 CS-2710 Dr. Mark L. Hornick The return address register $ra is used to “link”, or “remember” the next instruction to execute after returning from the procedure. 0x00400000addi$t0, $t0, 1 # sample instruction 0x00400004jalproc1 # call procedure at proc1 0x00400008addi$t0, $t1, $t2 # sample instruction … proc1: # label of procedure 0x00600000addi$t0, $t0, 1 # sample instruction 0x00600004addi$t1, $t0, 2 # sample instruction 0x00600008jr$ra # “return” 1. When jal is called, the address 0x00400008 is stored in $ra 2. Program execution jumps to the first instruction in proc1 3. When proc1 returns, program execution continues with instruction 0x00400008

8 CS-2710 Dr. Mark L. Hornick 8 Only one instruction should ever be used for returning from a procedure: jr jr$ra #jump to register The return address (the address of the instruction that immediately followed the jal instruction must be supplied as an operand to the jr instruction jr is the ONLY way to return from a procedure NEVER use a plain j to return Also, never use j to call a procedure

9 CS-2710 Dr. Mark L. Hornick Now consider another call from within a called procedure: 0x00400000addi$t0, $t0, 1 # sample instruction 0x00400004jalproc1 # call procedure at proc1 0x00400008addi$t0, $t1, $t2 # sample instruction proc2: # label of procedure 0x00500000addi$t0, $t0, 1 # sample instruction 0x00500004addi$t1, $t0, 2 # sample instruction 0x00500008jr$ra # “return” proc1: # label of procedure 0x00600000addi$t0, $t0, 1 # sample instruction 0x00600004jalproc2 #call procedure at proc2 0x00600008jr$ra # “return” 1. When jal is used to call proc1, the address 0x00400008 is stored in $ra. 2. What happens to $ra when jal is used within proc1 to call proc2 ?

10 CS-2710 Dr. Mark L. Hornick 10 CS2852 Review: Stack A traditional CS data structure Classical semantics (behavior) Elements can only be inserted and removed from the front of the collection This is known as Last-In, First-Out (LIFO) Less commonly: First-Out, Last-In (FILO) Random-access is not defined

11 CS-2710 Dr. Mark L. Hornick 11 JCF Stack – behavioral methods The naming for the structure and the methods is an analogy for how the data elements within the structure are accessed Principal methods that define behavior: push() – place an element on (top of) the stack pop() – return and remove an element from the (top of the) stack peek() – return the top element of the stack Without removing (popping) it

12 CS-2710 Dr. Mark L. Hornick 12 Most CPUs have a built-in implementation of Stack The actual stack “data structure” is just an ordered collection of bytes in a section of memory known as the heap that lies between the.data and.kdata sections (in MIPS) A special register ($sp, for Stack Pointer) is used to keep track of the start of the stack Initially, the stack is empty In the MARS default memory configuration, $sp is automatically initialized to 0x7FFFEFFC By convention, the stack starts at (or very near) the end of data memory – more on memory layout later $sp 0x10010000 - - - 0x1003FFFF 0x10040000 - - - 0x7FFFEFFA 0x7FFFEFFB 0x7FFFEFFC 0x7FFFEFFD 0x7FFFEFFE 0x7FFFEFFF - - - 0x80000000 0x80000001.ktext.data To start of memory at 0x0 To end of memory at 0xFFFFFFFF.data

13 CS-2710 Dr. Mark L. Hornick 13 The front of the stack grows “downward” towards lower memory as data is “pushed” onto the stack. Each successive “push” of data onto the stack effectively decrements the stack pointer $sp to a smaller address: addi$t0, $zero, 0x12345678#load value into $t0 sw$t0, ($sp) #push $t0 onto stack addi$sp, $sp, -4 #decrement $sp 13 $sp at start 0x10010000 - - - 0x1003FFFF 0x10040000 - - - 0x7FFFEFFA 0x7FFFEFFB 0x7FFFEFFC 0x7FFFEFFD 0x7FFFEFFE 0x7FFFEFFF - - - 0x80000000 0x80000001.ktext.data 0x12 0x56 0x78 0x34.data To start of memory at 0x0.data $sp after decrement

14 CS-280 Dr. Mark L. Hornick 14 0x00400000addi$t0, $t0, 1 # sample instruction 0x00400004jalproc1 # call proc1 0x00400008adi$t0, $t1, $t2 # sample instruction … proc1: # label of procedure 0x00600000sw$ra, 0($sp) # push $ra onto stack 0x00600004 addi$sp, $sp, -4 # decrement $sp 0x00600008jalproc2 # call proc2 0x0060000c addi$sp, $sp, 4 # increment $sp 0x00600010lw$ra, ($sp) # pop $ra from stack 0x00600014jr$ra # “return” At the beginning of every procedure: 1. Push $ra onto stack, saving it 2. Decrement $sp by 4 bytes At the end of every procedure: 1. Increment $sp by 4 bytes 2. Pop $ra from the stack 3. Return to caller $sp at start. ktext.data 0x00 0x08 0x40.data To end of memory at 0xFFFFFFFF $sp after decrement.data

15 15 What happens if a nested procedure uses the same registers as the calling code? Every procedure must At the start of the procedure: Push the $ra register onto the stack Push the values of all $s registers onto the stack in order to restore them later before returning. Decrement the stack pointer $sp appropriately At the end of the procedure, in reverse order: Pop the $ra register from the stack Pop the values of all $s registers from the stack in order to restore them later before returning.  That’s why $s registers are called “saved registers”! Increment $sp appropriately Return to the caller Before calling a procedure, the calling code must: Push any $t, $v, $a registers it is using onto the stack, since the called procedure may arbitrarily change any of those registers After calling a procedure, the calling code must: Pop any $t, $v, $a registers it was using from the stack, since the called procedure may have arbitrarily changed any of those registers

16 16 What about procedure arguments and return values? By convention: Registers $a0-$a3 are used for procedure arguments The calling code must place values into the registers before calling the procedure! The calling code must save the $a registers before the call, since the procedure is free to modify those registers! If needed, the calling code must restore the $a registers after the call. Registers $v0 and $v1 are used to represent a procedure’s return value. $v0 is typically all that is needed $v1 is only used if a 64-bit value needs to be returned 64 bits are needed when the return value represents a long int or a double (more on that later in the course) The calling code must save the $v registers before the call, since the procedure is free to modify those registers! If needed, the calling code must restore the $v registers after the call.

17 17 What if a procedure takes more than 4 arguments? By convention: Registers $a0-$a4 are used for the first 4 arguments of any procedure. If additional arguments are required, the calling code puts them on the Stack before calling the procedure. Once the procedure is called, it gets the additional arguments from the Stack

18 CS-280 Dr. Mark L. Hornick 18 0x003FFFECaddi$a0, $zero, 1 # arg1 in $a0 = 1 0x003FFFF0addi$a1, $zero, 2 # arg2 in $a1 = 2 0x003FFFF4addi$a2, $zero, 3 # arg3 in $a2 = 3 0x003FFFF8addi$a3, $zero, 4 # arg4 in $a3 = 4 0x003FFFFCaddi$t0, $zero, 5 # arg5 in $t0 = 5 0x00400000sw$t0, ($sp) # push arg5 onto stack 0x00400004addi$sp, $sp, -4 # decrement $sp 0x00400008jalproc1 # call proc1 0x0040000caddi$sp, $sp, 4 # increment $sp … proc1: # label of procedure 0x00600000sw$ra, 0($sp) # push $ra onto stack 0x00600004 addi$sp, $sp, -4 # decrement $sp 0x00600008lw$t1, 8($sp) # load arg5 from stack … 0x0060001c addi$sp, $sp, 4 # increment $sp 0x00600020lw$ra, ($sp) # pop $ra from stack 0x00600024jr$ra # “return” $sp at start. ktext.data 0x00 0x0c 0x40 0x00 0x05 0x00.data To end of memory at 0xFFFFFFFF $sp after 1 st decrement Example showing how the calling code would put a 5 th argument on the stack, and how the procedure would retrieve it $sp after 2 nd decrement

19 Operating system services CS-280 Dr. Mark L. Hornick 19 The MARS simulator provides a small set of “service routines” Service routines are procedures provided by an operating system that are made available to a user-written program Service routines in MIPS are not accessed via “jal” Instead, a special instruction “syscall” is used. An argument provided via $v0 (!) indicates which service routine to invoke Arguments to the service routine are provided via $a0-$a4 Example: print an integer value to the console addi$a0, $zero, 5#load value to be printed addi$v0, $zero, 1 #service routine 1 means “Print integer” syscall#invoke the service routine See the MARS online help for more information about all available service routines.


Download ppt "CS-2710 Dr. Mark L. Hornick 1 Defining and calling procedures (subroutines) in assembly And using the Stack."

Similar presentations


Ads by Google