More C functions and Big Picture [MIPSc Notes] Implementing C functions Passing parameters Local variables Stack frames Big picture Compiling Assembling Passing parameters by value or reference Galen H. Sasaki EE 361 University of Hawaii 1 C Functions: Passing Parameters k = max(i,j) max(int x, int y) Caller Load values i and j jal max Unload result Callee Reference values x and y Return result Where to pass parameters? Input parameters: registers global memory locations stack not ideal Return parameter: $2 (not always but true for our textbook) Galen H. Sasaki EE 361 University of Hawaii 2
Callee max(int i, int j) if (i>j) return i; max: # $4 = i, $5 = j # return max in $2 slt $1,$5,$4 # $1 = 1 if j < i beq $0,$1,Else move $2,$4 jr $31 else return j; Else: move $2,$5 jr $31 Galen H. Sasaki EE 361 University of Hawaii 3 Caller: Calling Procedure main() # $8 = n, $9 = m, $10 = k, $11 = temporary # Put input parameters in registers k = max(n,m); move $11,$31 # Save $31 jal max # goto max (prev. slide) move $31,$11 # Restore $31 # Put result in k Galen H. Sasaki EE 361 University of Hawaii 4
Review Calling Procedure: Save any registers that must be preserved across the call [Any reg values that could destroyed should by the function should be stored] Input parameters jal Get output parameters Restore any registers that must be preserved across the call Galen H. Sasaki EE 361 University of Hawaii 5 MIPS Convention For Registers Register Name Number Usage $zero 0 constant 0 $at 1 reserved for assembler $v0-$v1 2-3 expression evaluation and results of a function (return values) a0-$a3 4-7 arguments 1-4 (input parameters) $t0-$t7 8-15 temporary (not preserved across call) (callee s responsible to $s0-$s7 16-23 saved temporary (preserved across call) preserve values) $t8-$t9 24-25 temporary (not preserved across call) (caller s responsibility $k0-$k1 26-27 reserved for OS kernel to preserve values) $gp 28 pointer to global area $sp 29 stack pointer $fp 30 frame pointer $ra 31 return address Galen H. Sasaki EE 361 University of Hawaii 6
Stacks Problem: Limited number of registers to save stuff in Solution: Stack can store lots of stuff and in a dynamic way (i.e., as needed). Passing paramaters via stack: input values and return (output) values C function local variables Galen H. Sasaki EE 361 University of Hawaii 7 Parameter Passing Via Stack: Caller main k = max(n,m); # n = $8, m = $9, k = $10 addi $sp,$sp,-12 sw sw sw jal $ra,0($sp) $8,4($sp) $9,8($sp) max move $10,$2 $sp $sp ra n m lw $ra,$0($sp) addi $sp,$sp,+12 Galen H. Sasaki EE 361 University of Hawaii 8
Parameter Passing Via Stack: Callee max(int i, int j) if (i>j) return i; else return j; max: lw $4,0($sp) lw $5,4($sp) Else: slt $1,$5,$4 beq $0,$1,Else move $2,$4 jr $31 move $2,$5 jr $31 same as before $sp ra 1st 2nd Galen H. Sasaki EE 361 University of Hawaii 9 Local Variables Registers are good locations for local variables because of speed. But we need to save and restore them when calling a function -- on stack -- other registers Review: Who is responsible for saving? Caller or callee? Caller save: Calling function is responsible to save register values Disadvantages: - have to save register values for every function call even if not used by callee Callee save: Called function is responsible to save register values Disadvantages: - have to save registers even if not used by caller Galen H. Sasaki EE 361 University of Hawaii 10
k ji Local Variables on Stack Created by callee funct: addi $sp,$sp,-12 m n k jip funct(int i, int j, int k) int n, m, p; lw $1, ($sp) # $1 = j sw $1, ($sp) # m = $1 m = j; addi $sp,$sp,12 jr $ra # $ra = $31 Convention: input parameters are pushed into stack from right to left. Galen H. Sasaki EE 361 University of Hawaii 11 Example: factorial factorial(n) = n! = n (n-1) (n-2). (1) // Recursive implementation in C int fact(int n) if (n<1) return(1); else return(n * fact(n-1)); Fact: sub $sp,$sp,8 sw $ra,4($sp) sw $a0,0($sp) slt $t0,$a0,1 beq $t0,$zero,else add $v0,$zero,1 add $sp,$sp,8 jr $ra Else: sub $a0,$a0,1 jal fact lw $a0,0($sp) lw $ra,4($sp) add $sp,$sp,8 mul $v0,$a0,$v0 jr $ra if (n<1) return(1) return(n*fact(n-1)) Galen H. Sasaki EE 361 University of Hawaii 12
Stack Frame (or procedure call frames) Stack pointer $sp n m j 1) is used to point to top of stack 2) used as a reference to variables It has two jobs -- bad Frame point $fp takes over job 2 During execution of a function, the fp is stable. Galen H. Sasaki EE 361 University of Hawaii 13 Stack Frame For each call there is a block of memory on the stack called the stack frame. * to pass arguments * to save registers * for local variables Typical stack frame: $sp $fp local variables arrays, structs saved reg values including ret address arg reg values arguments (from caller) Stack can dynamically change and we still have stable $fp Left to right (4th, 5th, etc arguments because 0th, 3rd are in regs) Galen H. Sasaki EE 361 University of Hawaii 14
Stack Frames # $t0 = i, $s0 = j, $s1 = k; # Save $t0, $a0, $a1, and $ra on the stack addi $sp,$sp,-16 main() sw $t0,0($sp) sw $ra,4($sp) sw $a0,8($sp) sw $a1,12($sp) k = addumup(i,j); # Load parameters move $a0,$t0 old $t0 move $a1,$s0 old $ra # go to addumup old $a0 jal addumup old $a1 # Load output into k move $s1,$2 addumup(int i, int j) # Restore $t0, $a0, $a1, and $ra from the stack lw $t0,0($sp) int n; lw $ra,4($sp) n = i + j; lw $a0,8($sp) return n; lw $a1,12($sp) # Balance stack addi $sp,$sp,16 Galen H. Sasaki EE 361 University of Hawaii 15 main() k = addumup(i,j); addumup(int i, int j) int n, m; n = i + j; m = n + 10; return m; Stack Frames addumup: # n is in $s0, and m is in stack addi $sp,$sp,-16 sw $s0,8($sp) sw $fp,12($sp) addi $fp,$sp,12 # n = i+j add $s0,$a0,$a1 # m = n + 10 lw $t0,-8($fp) addi $t0,$t0,10 sw $t0,-12($fp) # return m lw $v0,-12($fp) # restore $fp move $fp,0($fp) # restore $s0 and stack lw $s0,8($sp) addi $sp,$sp,16 jr $ra old $t0 old $ra old $a0 old $a1 m n saved $s0 saved $fp old $t0 old $ra old $a0 old $a1 Galen H. Sasaki EE 361 University of Hawaii 16 $fp No arguments or $ra saved since addumup doesn t call anything
Calling Convention Calling procedure to a function funct(arg0, arg1,..., argn) Pass parameters arg0,..., argn through $a0-$a3 and stack Save caller saved registers, i.e., $a0-$a3, $t0-$t9 that are being used jal funct Restore caller saved registers Load values from $v0-$v1 funct: Make room on stack for stack frame Save callee registers, i.e., $s0-$s7 Save $fp, and have the new $fp point to the old value Save $ra, if funct makes a function call Do the function operation using $fp to reference local variables in the stack Restore registers and balance the stack jr $ra Stack $a0 = arg0 $a1 = arg1 $a2 = arg2 $a3 = arg3 arg4 arg5 arg5 Galen H. Sasaki EE 361 University of Hawaii 17 MIPS Convention For Registers Register Name Number Usage $zero 0 constant 0 $at 1 reserved for assembler $v0-$v1 2-3 expression evaluation and results of a function a0-$a3 4-7 arguments 1-4 $t0-$t7 8-15 temporary (not preserved across call) $s0-$s7 16-23 saved temporary (preserved across call) $t8-$t9 24-25 temporary (not preserved across call) $k0-$k1 26-27 reserved for OS kernel $gp 28 pointer to global area $sp 29 stack pointer $fp 30 frame pointer $ra 31 return address Galen H. Sasaki EE 361 University of Hawaii 18
Memory Usage Reserved 0x400000 0x10000000 Text Segment Static Dynamic Data Segment Determined by OS (malloc) Stack Segment Galen H. Sasaki EE 361 University of Hawaii 19 Big Picture Compilers (very brief) Assemblers Odds and Ends CISC vs. RISC Arrays (and structures) Pointers Galen H. Sasaki EE 361 University of Hawaii 20
Big Picture -- Software C code: file.c high level language Compiler Assembly code: file.s Assembler Object file: file.o ISA Other object files libraries Linker machine code (executable) Loader computer (target machine) Galen H. Sasaki EE 361 University of Hawaii 21 What Does A Compiler Do? The parser: * Identifies keywords and symbols * Preprocessing (e.g., expanding macros ) * Outputs are tokens and symbol table Semantic analysis: The program is understood and a data structure is created that represents the program -- e.g., identifies statements, checks for proper syntax, adds info to symbol table. High level optimizations: optimization at C language level Code generation: C instruction --> template --> assembly code Low level optimizations: optimize at assembly lang. level file.c Compiler file.s Galen H. Sasaki EE 361 University of Hawaii 22
Templates Example: if (expr1 == expr2) statement 1; else statement 2; Evaluate expr1 and load into $r1 Evaluate expr2 and load into $r2 bne $r1,$r2,else Code for statement 1 j Skip Else: Code for statement 2 Skip: Galen H. Sasaki EE 361 University of Hawaii 23 What Does An Assembler Do? Converts assembly language programs into machine programs. Assembly language components: machine instructions pseudo instructions labels (or symbols) directives: not machine instructions, but instructions for the assembler on how to assemble.globl main.text main:.. addi $sp,$sp,-12 Instructions move $8,$9 # actually add $8,$0,$9. loop: skip: beq $0,$1,loop jr $ra.data char_data:.ascii2 The quick brown mongoose Data byte_data:.byte 0,1,2,3,7,9,11,12.byte 1,2,7,3,9,12,75,0 Galen H. Sasaki EE 361 University of Hawaii 24
Two-Pass Assembler main: loop: loop2:.text add $1,$2,$3 bne $1,$0,Skip addi $1,$2,3 or $3,$4,$5 slti $1,$3,11 jal max skip: addi $1,$1,1 mult $3,$12,$10 j loop max: jr $31.data array_words:.word 10,20,32 Pass 1: Scan program from top to bottom. Allocate space in memory for instructions and data. Build symbol table. add bne: Skip? addi or slt jal: max? addi mult j: loop? jr 10 20 32 Symbol Table Symbol Value main 0 Skip loop loop2 max array_words Pass 2: Determine machine code Galen H. Sasaki EE 361 University of Hawaii 25.macro max($arg1,$arg2,$arg3) move $arg1,$arg2 slt $1,$arg2,$arg3 beq $0,$1,Skip move $arg1,$arg3 j max_over Skip: move $arg1,$arg2 max_over:.end_macro Macros Macro Expansion main: Block of Code 1 move $4,$5 slt $1,$5,$6 beq $0,$1,Skip.1 move $4,$6 j max_over.1 Skip.1: move $4,$5 max_over.1: Block of Code 2 main: Block of Code 1 move $10,$11 slt $1,$11,$12 max($4,$5,$6) beq $0,$1,Skip.2 Block of Code 2 move $10,$12 max($10,$11,$12) j max_over.2 Skip.2: move $10,$11 Block of Code 3 max_over.2: Block of Code 3 Galen H. Sasaki EE 361 University of Hawaii 26
Linking and Loading Output of Assembler: Object File: Header Text Data Relocation Info. Symbol Table Debug Linking: file1.o Header1 Text1 Data1 Relocation1 Symbol Table1 Debug1 file2.o Header2 Text2 Data2 Relocation2 Symbol Table2 Debug2 Loading: Load code and execute Header Text Data Relocation Symbol Table Debug Galen H. Sasaki EE 361 University of Hawaii 27 Odds and Ends Alternatives to the MIPS architecture Fallacies and Pitfalls Design Principles Pointers Galen H. Sasaki EE 361 University of Hawaii 28
Alternatives to MIPS * MIPS is RISC-- reduced instruction set computer * CISC -- complicated instruction set computer. Philosophy: make instructions powerful to shorten programs. Hypothetical CISC instructions: Example: autoincrement and autodecrement lwt $8,Start($19) increments $19 after load Example: addm $16,$17,Astart($19) Example: increment-compare-and-branch too much information for one word ---> double word instructions. Irregularities are bad. Implements for-loop icb $19,$20,Loop increment $19 branch if $19 < $20 Galen H. Sasaki EE 361 University of Hawaii 29 Fallacies and Pitfalls Design Principles Fallacies and Pitfalls * More powerful instructions mean higher performance * Write in assembly language to obtain the highest performance * Word addresses, in byte addressable memory, differ by 1 Big Endian Address Memory 0 0 1 2 3 4 4 5 6 7 Design Principles Little Endian Address Memory 0 3 2 1 0 4 7 6 5 4 * Smaller is faster * Simplicity favors regularity * Good design demands compromise * Make the common fast Galen H. Sasaki EE 361 University of Hawaii 30
clear1(int array[], int size) int i; for (i=0; i < size; i++) array[i] = 0; Arrays vs. Pointers clear2(int *array, int size) int *p; for (p = &array[0]; p < &array[size]; p++) *p = 0; array[0] array[1].. array[size-1] array[size] clear1(int array[], int size) int i; i = 0; while (i < size) array[i] = 0; i++; clear2(int *array[], int size) int *p; p = &array[0]; while (p < &array[size]) *p = 0; p++ Galen H. Sasaki EE 361 University of Hawaii 31 Arrays clear1(int array[], int size) int i; i = 0; while (i < size) array[i] = 0; i++; # $4 points to array, $5 = size # i: $2 clear1: move $2,$0 # i = 0; while: slt $1,$2,$5 # while (i < size) beq $0,$1,Return add $3,$2,$2 # array[i] = 0; add $3,$3,$3 add $3,$3,$4 sw $0,0($3) addi $2,$2,1 # i++; Return: j jr while $ra Galen H. Sasaki EE 361 University of Hawaii 32
Pointers # $4 = *array, $5 = size # $2 = p clear2(int *array[], int size) int *p; p = &array[0]; while (p < &array[size]) *p = 0; p++; array[0] array[1].. array[size-1] array[size] clear2: move $2,$4 # p = &array[0] while: add $3,$5,$5 add $3,$3,$3 add $3,$3,$4 # $3 = size*4 + *array slt $1,$2,$3 beq $1,$0,Return sw $0,0($2) # *p = 0; addi $2,$2,4 # p++; j while Return: jr $ra Galen H. Sasaki EE 361 University of Hawaii 33