230 likes | 355 Views
MIPS Programming. Arrays Writing Procedures: Calling Convention. Memory Setup in C/Java. C++: int *intarray = new int[10]; Java: int[] intarray = new int[10]; What does this do? What does the memory look like? Where is intarray[5] located? intarray + 20
E N D
MIPS Programming Arrays Writing Procedures: Calling Convention
Memory Setup in C/Java • C++: int *intarray = new int[10]; • Java: int[] intarray = new int[10]; • What does this do? What does the memory look like? • Where is intarray[5] located? intarray + 20 • Where is intarray[i] located? intarray + 4*i intarray intarray &(intarray[0]) intarray + 20 &(intarray[0]) + 20
Declaring & InitializingGlobal Arrays in HLL int GlobalA = 3; int GlobalB[] = {0x20040002, 0x20080001, 0x200b0001, 0x8b502a, 0x15400003, 0x01084020, 0x20840000, 0x800fffa, 0x10010200, 0x00000000}; int main(int argc, char *argv[]) { } public class MyClass{ public static int GlobalA = 3; public static int GlobalB[] = {0x20040002, 0x20080001, 0x200b0001, 0x8b502a, 0x15400003, 0x01084020, 0x20840000, 0x800fffa, 0x10010200, 0x00000000}; };
Declaring & Initializing Global Arrays in MIPS .data GlobalA: .word 0x03; GlobalB: .word 0x20040002 0x20080001 0x200b0001 0x8b502a .word 0x15400003 0x01084020 0x20840000 0x800fffa .word 0x10010200 0x00000000 .text main:
Declaring & InitializingLocal Arrays int main(int argc, char *argv[]) { int LocalA = 5; int LocalB[] = {1,2,3}; } Not possible in Java!!!!! In Java, arrays are references to Array objects. add $sp, $sp, -(24 + x + 4 + 12) # where x is space for preserved regs addi $t0, $0, 5 sw $t0, 12($sp) addi $t0, $0, 1 sw $t0, 0($sp) addi $t0, $0, 2 sw $t1, 4($sp) addi $t0, $0, 3 sw $t1, 8($sp) // and so forth
Declaring & InitializingHeap Arrays in HLL int main(int argc, char *argv[]) { int *LocalA = (int *)malloc(4); *LocalA = 5; int *LocalB = (int *)malloc(12); LocalB[0] = 1; LocalB[1] = 2; LocalB[2] = 3; } public class MyClass{ public static void main(int argc, String argv) { int LocalA[] = new int[1]; LocalA[0] = 5; int LocalB[] = new int[3]; LocalB[0] = 1; LocalB[1] = 2; LocalB[2] = 3; } };
Declaring & InitializingHeap Arrays in MIPS add $sp, $sp, -(24 + x + 8) # where x is space for preserved regs addi $a0, $0, 4 jal malloc sw $v0, 4($sp) // store the reference into the stack addi $t0, $0, 5 sw $t0, 0($v0) // initialize first elements as 5 (*LocalA = 5) addi $a0, $0, 12 jal malloc sw $v0, 0($sp) // store the reference into the stack addi $t0, $0, 1 sw $t0, 0($v0) // LocalB[0] = 1 addi $t0, $0, 2 sw $t0, 4($v0) // LocalB[1] = 2 addi $t0, $0, 3 sw $t0, 8($v0) // LocalB[2] = 3
MIPS Example 5 Assumptions: A & B are global c is in the stack, 6 bytes from $sp Translate int A[100]; // ints are 4 bytes in C/Java char B[100]; // chars are 1 byte in C char c = B[50]; A[1] = A[5] + 7; Use LoadByte, not LoadWord, because char (in C) is 1 byte la $s1, B lb $t1, 50($s1) # $t1 = B[50]; sb $t1, 6($sp) # c = B[50]; la $s0, A lw $t0, 5 ($s0) ; x = A[5]; lw $t0, 20 ($s0) # $t0 = A[5]; addi $t0, $t0, 7 # $t0 = A[5] + 7; sw $t0, 4 ($s0) # A[1] = A[5] + 7;
MIPS Example 6 Assumptions: &(A[0]) is in $s0, x is in $t0 i is in $s1 Translate int A[100]; int i; … x = A[i]; sll $t1, $s1, 2 # $t1 = i<<2 or i * 4 add $t1, $s0, $t1 # $t1 = (i*4+&A[0]) or &(A[i]) lw $t0, 0($t1) # $t0 = A[i];
Procedure Calls Main Procedure • Procedure must work the same from any call • Procedure uses regs that main was using • We need a convention to • pass arguments • preserve registers, stack • pass return values Call Procedure Call Procedure
MIPS-specific info Page 140, Figure 3.13
MIPS-specific info – who cares? • Preserved – Value is same after call • Caller – excellent! no worries! • Procedure – may not destroy value • must store at beginning and restore at end to use • Not preserved – No guarantees • Caller – loses value in register • most store before call and restore after call • Procedure – may use without worries
Steps for caller 0. Store any temp regs whose values we need • Pass function parameters to procedure • Transfer control to procedure • (then procedure executes) • Get return value • Restore any temp regs we saved away
Steps for procedure • Allocate stack space • Store preserved regs we may use • Perform task • Place result in proper location for caller • Restore preserved regs we may have used • Transfer control back to caller
Caller: 4. Restore regs int MyFunc(int g, int h) { return (g + h);} Caller: sw $t0, 0($sp) add $a0, $s2, $zero add $a1, $s3, $zero jal MyFunc add $s0, $v0, $zero lw $t0, 0($sp) Callee: Load from same location in the stack Assume: g,h are in $s2,$s3. We want return value in $s0. Caller wants to preserve $t0 across function call.
Definitions • Leaf function • Makes no function calls • You need not store $ra into the stack • Non-leaf function • Contains a function call • You MUST store $ra in the stack and restore before returning to caller
Allocating stack space Stack space for this function $sp $sp Minimum allocation: 24 bytes $sp Only allocate once per function!!!! $sp contains address of bottom of stack. What operation on $sp allocates space?
Callee: 7. Return to caller int MyFunc(int g, int h) { return (g + h);} Caller: sw $t0, 0($sp) add $a0, $s2, $zero add $a1, $s3, $zero jal MyFunc add $s0, $v0, $zero lw $t0, 0($sp) Callee: addi $sp, $sp, -32 sw $s0, 0 ($sp) add $s0, $a0, $a1 add $v0, $s0, $zero lw $s0, 0 ($sp) addi $sp, $sp, 32 jr $ra Assume: g,h are in $s2,$s3. We want return value in $s0. Caller wants to preserve $t0 across function call.
What actually goes in stack Extra Arguments $sp before call $fp during call $ra $fp P*4 bytes for preserved regs ($s0-$s7) preserved registers (and $a0-$a3) padding local data L*4 bytes for local data Extra outgoing arguments A*4 bytes for outgoing args $sp during call
Assume it needs 2 saved registers Example Local 256-byte array int foo(int arg1, int arg2) { int myarray[64]; myarray[3] = 5; … bar(a1, a2, a3, a4, a5); … return (myarray[3]); } Non-leaf function
Caller’s Stack Minimum Allocation addi $sp, $sp, - (1+64+1+2+6)*4 sw $ra, 73*4($sp) sw $fp, 72*4($sp) sw $s1, 67*4($sp) sw $s0, 66*4($sp) addi $t0, $zero,5 # $t0 = 5 sw $t0, (1+3)*4 ($sp)# myarray[3] = 5 … lw $ra, 73*4($sp) lw $fp, 72*4($sp) lw $s1, 67*4($sp) lw $s0, 66*4($sp) addi $sp, $sp, (1+64+1+2+6)*4 jr $ra $ra $sp before call $fp $a0 $a1 $a2 $a3 $s1 $s0 padding myarray $sp during call outgoing arg 5
SumToN: add $v0, $0, $0 loop: slt $t0, $0, $a0 beq $t0, $0, end add $v0, $v0, $a0 addi $a0, $a0, -1 j loop end: jr $ra Another Example: int SumToN(int N) { int sum = 0; while (N > 0) { sum += N; N--; } return sum; }
SumToNtotheM: add $sp, $sp, -32 sw $ra, 14($sp) add $t0, $0, $0 loop: slt $t0, $0, $a0 beq $t0, $0, end sw $a0, 28($sp) sw $a1, 24($sp) sw $t0, 0($sp) jal power lw $t0, 0($sp) lw $a0, 28($sp) lw $a1, 24($sp) add $t0, $v0, $t0 addi $a0, $a0, -1 j loop end: add $v0, $t0, $0 lw $ra, 14($sp) add $sp, $sp, 32 jr $ra Third Example: int SumNtotheM(int N, int M) { int sum = 0; while (N > 0) { sum += power(N,M); N--; } return sum; }