Procedures A procedure or subroutine is a tool
Procedures A procedure or subroutine is a tool used to structure programs, both to make them easier to understand allow code to be reused. Six steps the program must follow 1. Place parameters in a place where the procedure can access them. 2. Transfer control to the procedure. 3. Acquire the storage resources needed for the procedure. 4. Perform the desired task. 5. Place the result value in a place where the calling program can access it. 6. Return control to the point of origin.
Procedures • Program Counter (PC): a register to hold the address of the current instruction being executed. • $a 0 -$a 3: four argument registers in which to pass parameters • $v 0 -$v 1: two value registers in which to return values • $ra: one return address register to return to the point of origin Jump-and-Link jal Procedure. Address Jumps to an address and simultaneously saves the address (PC+4) of the following instruction in jump register $ra. The callee performs the calculations, places the results in $v 0 -$v 1, and returns control to the caller using jr $ra.
Stack • A last-in-first-out(LIFO) queue • push – placing data onto the stack • pop – removing data from the stack • Stack Pointer (another register) points the most recently allocated address in the stack to show where the next procedure should place the registers to be spilled or where old register values can be found. • Any registers needed by the caller is restored to the values that they contained before the procedure was invoked. Those data is stored in the stack. • Stacks grow from higher addresses to lower addresses.
Example int leaf_example (int g, int h, int i, int j) { int f; f = (g + h) – ( i + j); return f; } g, h, i, and j are $a 0, $a 1, $a 2, and $a 4. f is $s 0. leaf_example: subi $sp, 12 sw $t 1, 8($sp) sw $t 0, 4($sp) sw $s 0, 0($sp) # # adjust stack save $t 1 for save $t 0 for save $s 0 for to make room for 3 items use afterwards add $t 0, $a 1 add $t 1, $a 2, $a 3 sub $s 0, $t 1 # g + h # i + j # f = $t 0 - $t 1 add $v 0, $s 0, $zero #return f ($v 0) lw $s 0, 0($sp) lw $t 0, 4($sp) lw $t 1, 8($sp) # restore $s 0 for caller # restore $t 1 for caller jr $ra # jump back to calling routine
The Values of the Stack Pointer High Address Contents of register $t 1 Contents of register $t 0 $sp Contents of register $s 0 $sp Low Address (A) before (b) during (c) after
Recursive Procedure int fact (int n) { if (n < 1) return (1); else return (n * fact(n-1)); }
Recursive Procedure fact: sub $sp, 8 sw $ra, 4($sp) sw $a 0, 0($sp) # adjust stack for 2 items # save the return address # save argument n (the original value) slti $t 0, $a 0, 1 beq $t 0, $zero, L 1 #test for n < 1 # if n >= 1, go to L 1 addi $v 0, $zero, 1 addi $sp, 8 jr $ra # return value 1 # pop 2 items off statck # return to after jal subi $a 0, 1 jal fact # set argument to n – 1 # call fact with (n - 1) lw $a 0, 0($sp) lw $ra, 4($sp) addi $sp, 8 # return from jal: restore n # restore the return address # adjust stack pointer to pop 2 items mult $a 0, $v 0 mflo $v 0 # n * fact (n – 1) # set return value jr # return to the caller L 1: $ra
String Copy Procedure void strcpy (char x[], char y[]) { int i; i = 0; while ((x[i] = y[i]) != 0) i = i + 1; }
String Copy Procedure strcpy: sub $sp, 4 sw $s 0, 0($sp) # adjust stack for 2 items # save $s 0 = i add $s 0, $zero # initialize $s 0 = 0 L 1: add $t 1, $a 1, $s 0 # address of y[i] lb $t 2, 0($t 1) # $t 2 = y[i] actual char not the address add $t 3, $a 0, $s 0 sb $t 2, 0($t 3) # address of x[i] # x[i] = y[i] addi $s 0, 1 bne $t 2, $zero, L 1 # i = i + 1 # if y[i] != 0, go to L 1 (continue) lw $s 0, 0($sp) addi $sp, 4 jr $ra # restore old $s 0 # pop 1 word off stack # return
MIPS System Call How to use SYSCALL system services Step 1. Load the service number in register $v 0. Step 2. Load argument values, if any, in $a 0, $a 1, $a 2, or $f 12 as specified. Step 3. Issue the SYSCALL instruction. Step 4. Retrieve return values, if any, from result registers as specified. Example: display the value stored in $t 0 on the console li $v 0, 1 # service 1 is print integer add $a 0, $t 0, $zero # load desired value into argument register $a 0, using pseudo-op syscall
System Calls and I/O • used to read or print values or strings from input/output window, and indicate program end • use syscall operating system routine call • first supply appropriate values in registers $v 0 and $a 0 -$a 1 • result value (if any) returned in register $v 0 print_int print_float print_double print_string read_int read_float read_double Code in $v 0 1 2 3 4 5 6 7 read_string 8 $a 0 = memory address of string input buffer $a 1 = length of string buffer (n) Sbrk (allocate heap memory) 9 $a 0 = amount exit 10 Service Arguments Results $a 0 = integer to be printed $f 12 = float to be printed $f 12 = double to be printed $a 0 = address of string in memory integer returned in $v 0 float returned in $v 0 double returned in $v 0 address in $v 0
Example Input/output integers and strings
- Slides: 12