Function calls using the stack Consider the following

  • Slides: 18
Download presentation
Function calls using the stack Consider the following program: void hello (){ print “Hi”;

Function calls using the stack Consider the following program: void hello (){ print “Hi”; friend(); } void friend(){ print “friend”; } main() { hello(); --} Does this program correct? . data hi: . asciiz “Hi” friends: . asciiz “friend”. text jal hello ---li $v 0, 10 syscall hello: la $a 0, hi li $v 0, 4 syscall jal friend jr $ra friend: la $a 0, friends li $v 0, 4 syscall jr $ra

Function calls using the stack (cont. ) ▪The problem can be avoided by using

Function calls using the stack (cont. ) ▪The problem can be avoided by using the stack to save the return address (the content of $ra). For a sequence of nested calls, we need to save several return addresses. ▪ There are several other reasons for using the stack in function implementations and calls: - The stack can be used to save the content of other registers which the caller wants to maintain their contents but there is possibility that their contents can be modified by a callee; - It supports any function with any number of parameters. For functions that have more than four parameters( usually the registers $a 0 -$a 3 are used for the parameters) ; - It can be used to save the values of local variables, register contents, and arguments of nested function calls, recursive and reentrant functions. ▪ Examples of reentrant functions: All shared operating-system functions and library functions on multitasking computer systems and time-sharing systems. ▪ The next slide shows the correct solution of the previous example.

. data hi: . asciiz “Hi” friends: . asciiz “friend”. text jal hello --li

. data hi: . asciiz “Hi” friends: . asciiz “friend”. text jal hello --li $v 0, 10 syscall hello: subu $sp, 4 #reserve four bytes to store the return address of hello($ra). sw $ra, ($sp) #save the return address. la $a 0, hi li $v 0, 4 syscall jal friend # jal friend can use $ra without problem lw $ra, ($sp) # load the register $ra with the return address addu $sp, 4 # release the four bytes used for storing the $ra of hello jr $ra friend: la $a 0, friends li $v 0, 4 syscall jr $ra •

Memory Layout in MIPS 0 x 0000 0 x 00400000 Reserve d Text Segment

Memory Layout in MIPS 0 x 0000 0 x 00400000 Reserve d Text Segment 0 x 10000000 Data Segment Stack Segment 0 x 7 fffefff Operating System 0 x. FFFF

MIPS register conventions to reduce the stack operations and enhancing program readability and maintenance

MIPS register conventions to reduce the stack operations and enhancing program readability and maintenance ▪ The s-registers($s 0 -$s 7), $sp, $fp, and $ra are by convention calleesave registers. Any function that modifies one of these registers is responsible for saving its content on the stack and restoring its original value before returning. This mean that the caller is guaranteed that all callee-save registers contain the same values after the call as before the call. ▪ All other registers including the t-registers($t 0 -$t 9), are by convention caller-save registers. A function is allowed to freely modify any caller -save registers. This means that the caller can not assume that these registers contain the same value after the call as before the call. If a caller-save register holds critical data, it is up to the caller to save the data on the stack before the call and to restore it after the call.

MIPS register conventions (cont. ) ▪ The stack can be used to pass any

MIPS register conventions (cont. ) ▪ The stack can be used to pass any number of parameters to a callee. This rule states that the first four parameters are passed to a function (callee) via the registers $a 0 -$a 3. All additional parameters are passed via the stack. ▪ The registers $v 0 and $v 1 are used for return values. ▪ All parameters in the examples and exercises of text#2 are passed via the stack even though it is not the necessary.

Template Of Nested Functions Function. F: -------If Function. G is going to change the

Template Of Nested Functions Function. F: -------If Function. G is going to change the content of Registers $t 0 -$t 7 and the Function. F will need the previous contents of these registers later, then save(sw) the content of registers $t 0 -$t 7 on the stack before calling Function. G. jal Function. G If you have pushed the content of $t 0 -$t 7 on the stack, pop the stack( lw) to get the old values of the Registers $t 0 -$t 7. --------Function. G: --------If Function. G is going to change the content of Registers $s 0 -$s 7 and the Function. F will need the previous contents of these registers later, then save(sw) the content of registers $s 0 -$s 7 on the stack. If the function G is going to call another function , then you must save $ra on the stack. If Function. H is going to change the content of Registers $t 0 -$t 7 and the Function. G will need the previous contents of these registers later(after calling Function. H), then save(sw) the content of registers $t 0 -$t 7 on the stack before calling Function. H. jal Function. H If you have pushed the content of $t 0 -$t 7 on the stack, pop the stack( lw) to get the old values of the Registers $t 0 -$t 7 Pop the stack to restore the content of the register $ra ------if you have pushed the content of $s 0 -$s 7 on the stack, before the end this function , pop the stack( lw) to get the old values of the Registers $s 0 -$s 7 Function. H: If Function. H is going to change the content of Registers $s 0 -$s 7 and the Function. G will need the previous contents of these registers later( after calling Function. H), then save(sw) the content of registers $s 0 -$s 7 -------if you have pushed the content of $s 0 -$s 7 on the stack, before the end this function , pop the stack( lw) to get the old values of the Registers $s 0 -$s 7 For more than three functions , the templates of all middle functions will be similar to that of Function. G, and the templates of the first and last functions will be similar to that of Function. F and Function. H, respectively. For only two functions case, the templates will be similar to that of Function. F and Function. H.

Example of Passing Arguments on the Stack Not Efficient Because It Requires Too Many

Example of Passing Arguments on the Stack Not Efficient Because It Requires Too Many Stack Operations An Example of Jack calling Jill(A, B, C, D, E) JACK: addiu $sp, -24 # Allocate Space on the Stack sw$t 1, 0($sp) # First In Parameter “A” at Mem[Sp] sw$t 2, 4($sp) #Second In Para. “B” at Mem[Sp+ 4] sw$t 3, 8($sp) # Third In Parameter “C” at Mem[Sp+ 8] sw$ra, 20($sp) # Save Return address #JACK does not has to save the registers $s 0 -$s 7 but it #does has to save the registers $t 0 -$t 7. This rule is #applicable if JACK needs the original values of registers #and might be changed by JILL. jal JILL # Call the Function lw $ra, 20($sp) #Restore Return Address to Main lw $t 4, 12($sp) # Get First Out Para. “D” lw $t 5, 16($sp) # Get Second Out Para. “E” addiu $sp, 24 # De-allocate Space on the Stack

Example of Jill accessing the Stack JILL: lw $a 0, 0($sp)# Get First In

Example of Jill accessing the Stack JILL: lw $a 0, 0($sp)# Get First In Parameter “A” at Mem[Sp] lw $a 1, 4($sp) # Get Second In Para. “B” at Mem[Sp+4] lw $a 2, 8($sp) # Get Third In Para. “C” at Mem[Sp+8]. . . <Body of Function> JILL may change the registers $t 0 -$t 9 but not the registers $s 0 -$s 7. If $t 0 -$t 9 are not enough for JILL computation and more registers are needed, JILL may use registers $s 0 -$s 7 and may change their contents, but before performing any change, the contents of $s 0 -$s 7 must be saved on the stack and be restored before retuning to JACK. . . sw $v 0, 12($sp)# First Out Para. “D” at Mem[Sp+12] sw $v 1, 16($sp)# Second Out Para. “E” at Mem[Sp+16] Jr $ra # Return to JACK

Example of Jack Saving Important Temporary Registers addiu sw $t 1, sw $t 2,

Example of Jack Saving Important Temporary Registers addiu sw $t 1, sw $t 2, sw $t 3, sw $ra, sw $t 6, $sp, -32 # Allocate More Space on the Stack <#### 0($sp) # First In Parameter “A” at Mem[Sp] 4($sp) # Second In Parameter “B” at Mem[Sp+ 4] 8($sp) # Third In Parameter “C” at Mem[Sp+ 8] 20($sp) # Save Return address 24($sp) # Save $t 6 on the stack because JIll may modify it and JACK # may need it later. sw $t 7, 28($sp) # Save $t 7 on the stack because JIll may modify it and #JACK may need it later. jal JILL # call the Function lw $t 6, 24($sp) # Restore $t 6 from the stack <#### lw $t 7, 28($sp) # Restore $t 7 from the stack <#### lw $ra, 20($sp) # Restore Return Address to Main Program lw $t 4, 12($sp) # Get First Out Parameter “D” at Mem[Sp+12] lw $t 5, 16($sp) # Get Second Out Parameter “E” at Mem[Sp+16] addiu $sp, 32 # De-allocate Space on the Stack <#### : :

Example 1 Write a function to search through an array 'X' of 'N' words

Example 1 Write a function to search through an array 'X' of 'N' words to find the minimum and maximum values. Min. Max (&X, N, Min, Max) The parameters &X and N are passed to the function on the stack, and the minimum and maximum values are returned on the stack. (Show Min. Max is called)

OPTIONAL Program of Min. Max(&X: $t 1, N: $t 2, min: $v 0, max:

OPTIONAL Program of Min. Max(&X: $t 1, N: $t 2, min: $v 0, max: $v 1). text Min. Max: lw $t 1, 0($sp) # get &X lw $t 2, 4($sp) # get N lw $v 0, 0($t 1) # Init. min move $v 1, $v 0 # Init. max addi $t 2, -1 blez $t 2, ret loop: addiu $t 1, 4 lw $t 0, 0($t 1) bge $t 0, $v 0, next move $v 0, $t 0 b chk next: ble $t 0, $v 1, chk move $v 1, $t 0 chk: addi $t 2, -1 bgtz $t 2, loop ret: sw $v 0, 8($sp) # put min sw $v 1, 12($sp) # put max jr $ra

An Example of calling the function Min. Max (&X, N, Min, Max) OPTIONAL .

An Example of calling the function Min. Max (&X, N, Min, Max) OPTIONAL . data array. space 400. text addiu $sp, -16 la $t 0, array sw $t 0, 0($sp) li $t 0, 100 sw $t 0, 4($sp) jal Min. Max lw $t 0, 8($sp) lw $t 1, 12($sp) addiu $sp, 16

Example 2 Search(&X, N, V, L) Write a function to sequentially search an array

Example 2 Search(&X, N, V, L) Write a function to sequentially search an array X of N bytes for the relative location L of a value V. The parameters &X, N, and V are passed to the procedure on the stack, and the relative location L (a number ranging from 1 to N) is returned on the stack. If the value V is not found, the value (-1) is returned for L.

Pseudocode OPTIONAL $t 3= Mem(sp); # get &X $t 1= Mem($sp + 4); #

Pseudocode OPTIONAL $t 3= Mem(sp); # get &X $t 1= Mem($sp + 4); # get N $t 0= Mem($sp + 8); # get V $t 2=$t 1; for ($t 2 = $t 2 - 1; $t 2 >= 0; $t 2= $t 2 - 1) { $t 4 = mem($t 3); $t 3=$t 3 + 1; if ( $t 4 == $t 0) go to found; } Mem(sp + 12) = -1; go to exit; found: Mem(sp + 12) = $t 1 - $t 2; exit: return;

Program of Example 2 OPTIONAL . text search: lw lw lw move addi $t

Program of Example 2 OPTIONAL . text search: lw lw lw move addi $t 3, $t 1, $t 0, $t 2, 0($sp) 4($sp) 8($sp) $t 1 $t 2, -1 # get &X # get N # get V lbu addiu beq addi bgez li sw b $t 4, $t 3, $t 4, $t 2, $t 4, exit 0($t 3) # get a character $t 3, 1 # increment pointer $t 0, found $t 2, -1 # decrement loop counter loop -1 12($sp) sub sw jr $t 1, $ra $t 1, $t 2 12($sp) # t 2 = N - 1 loop: found: exit:

Exercise AVA (&X, &Y, &Z, N, status) Write a function to perform an absolute

Exercise AVA (&X, &Y, &Z, N, status) Write a function to perform an absolute value vector addition. Use the stack to pass parameters. The parameters are: the starting address of three different word arrays : X, Y, Z, and an integer value N specifying the size of the vectors. If overflow ever occurs when executing this function, an error status of “ 1” should be returned and the function aborts any further processing. Otherwise, return the value “ 0” for status. The function will perform the vector addition: Xi = | Yi | + | Zi | ; with i going from 0 to N - 1. Also write a main program to test this function.

Iterative N Factorial $v 0 = Mem($sp); OPTIONAL For (a 0 = $v 0

Iterative N Factorial $v 0 = Mem($sp); OPTIONAL For (a 0 = $v 0 – 1; $a 0 > 0 ; $a 0 = $a 0 – 1) $v 0 = $v 0 * $a 0; Mem($sp+4) = $v 0; Return Fac: lw $v 0, 0($sp) addi $a 0, $v 0, -1 loopf: blez $a 0, return mult $v 0, $a 0 mflo $v 0 addi $a 0, $a 0. -1 b loopf return: sw $v 0, 4($sp) jr $ra