CMPUT Computer Organization and Architecture I1 CMPUT229 - Fall 2003 Topic5: Linking José Nelson Amaral
CMPUT Computer Organization and Architecture I2 Reading Assignment zChapter 3 of Hennessy and Patterson: ySections 3.6 to 3.8, A.5, and A.6.
Patt-Hen., pp. 156 COPYRIGHT 1998 MORGAN KAUFMANN PUBLISHERS, INC. ALL RIGHTS RESERVED
CMPUT Computer Organization and Architecture I4 MIPS Memory Allocation Patt-Hen., pp. 156 Patt-Hen., pp. A-20 COPYRIGHT 1998 MORGAN KAUFMANN PUBLISHERS, INC. ALL RIGHTS RESERVED
CMPUT Computer Organization and Architecture I5 Accessing a Program’s Data Notice that the program’s isntructions starts at address 0x , and the program’s data starts at 0x A typical data address cannot be expressed in the 16 bits allowed in most instructions. Thus if a program wants to load a word from address 0x into $v0, it has to use two instructions: lui$s0, 0x1000 # $s0 0x lw$v0, 0x0020($s0) # $v0 Mem[0x ] To avoid the frequent use of two instructions like this, the MIPS system keeps a dedicate register called global pointer ($gp) with an address in the static data segment (0x ). Patt-Hen., pp. A-21
CMPUT Computer Organization and Architecture I6 Accessing a Program’s Data With $gp = 0x , a program can load a word from address 0x into $v0, using a single instructions: lw$v0, 0x8020($gp) # $v0 Mem[0x ] Notice that: 0x xFFFF x With $gp = 0x , it is faster to access the memory locations in the interval from 0x to 0x1000 FFFF. Thus the MIPS compiler usually stores all global variables in this interval. Patt-Hen., pp. A-21
CMPUT Computer Organization and Architecture I7 Procedure Call Convention (more detailed) $at, $k0, $k1: reserved for assembler and operating system $a0-$a3: four argument registers in which to pass parameters $v0-$v1: two value registers in which to return values $ra: one return address register to return to the point of origin $t0-$t9: caller-saved temporary registers $s0-$s7: calle-saved registers for long-lived values $gp: global pointer pointing to the middrls of a 64K block of memory in the static data segment $sp: stack pointer $fp: frame pointer Patt-Hen., pp. A-22
CMPUT Computer Organization and Architecture I8 Layout of Stack Frame Patt-Hen., pp. A-25 COPYRIGHT 1998 MORGAN KAUFMANN PUBLISHERS, INC. ALL RIGHTS RESERVED
CMPUT Computer Organization and Architecture I9 A Complete Example: The sort procedure void sort ( int v[ ], int n ) { int i, j; for (i=0 ; i<n ; i=i+1) for(j=i-1; j>= 0 && v[j] > v[j+1]; j=j+1) swap(v,j); } void swap ( int v[ ], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+a] = temp; }
CMPUT Computer Organization and Architecture I10 A Complete Example: The sort procedure void sort ( int v[ ], int n ) { int i, j; for (i=0 ; i < n ; i=i+1) for(j=i-1; j>= 0 && v[j] > v[j+1]; j=j+1) swap(v,,j); } How much room do we need to make in the stack for the procedure sort? It will be easier to determine what we need to save into the stack if we write the code for the body of the procedure first
CMPUT Computer Organization and Architecture I11 A Complete Example: The sort procedure void sort ( int v[ ], int n ) { int i, j; for (i=0 ; i < n ; i=i+1) for(j=i-1; j >= 0 && v[j] > v[j+1]; j=j+1) swap(v,,j); } move$s0, $zero# i 0 slt$t0, $s0, $a1# if(i<n) $t0 1 else $t0 0 beq$t0, $zero, exit1# addi$s0, $s0, 1# i i+1 jfor1test# go back to test of outer loop exit1: for1test:
CMPUT Computer Organization and Architecture I12 A Complete Example: The sort procedure void sort ( int v[ ], int n ) { int i, j; for (i=0 ; i < n ; i=i+1) for(j=i-1; j >= 0 && v[j] > v[j+1]; j=j+1) swap(v,,j); } move$s0, $zero# i 0 for1test: slt$t0, $s0, $a1# if(i<n) $t0 1 else $t0 0 beq$t0, $zero, exit1# addi$s0, $s0, 1# i i+1 jfor1test# go back to test of outer loop exit1: addi$s1, $s0, -1# j i-1 slti$t0, $s1, 0# if(j<0) $t0 1 else $t0 0 bne$t0, $zero, exit2 add$t1, $s1, $s1# $t1 2*j add$t1, $t1, $t1# $t1 4*j add$t2, $a0, $t1# $t2 = Addr(v[j]) lw$t3, 0($t2)# $t3 v[j] lw$t4, 4($t2)# $t4 v[j+1] slt$t0, $t4, $t3# if (v[j+1]<v[j]) $t0 1 beq$t0, $zero, exit2 add$s1, $s1, 1# j j+1 jfor2test for2test: exit2:
CMPUT Computer Organization and Architecture I13 void sort (int v[ ], int n ) { int i, j; for (i=0 ; i < n ; i=i+1) for(j=i-1; j >= 0 && v[j] > v[j+1]; j=j+1) swap(v,,j); } move$s0, $zero# i 0 for1test: slt$t0, $s0, $a1# if(i<n) $t0 1 else $t0 0 beq$t0, $zero, exit1# addi$s1, $s0, -1# j i-1 for2test:slti$t0, $s1, 0# if(j<0) $t0 1 else $t0 0 bne$t0, $zero, exit2 add$t1, $s1, $s1# $t1 2*j add$t1, $t1, $t1# $t1 4*j add$t2, $a0, $t1# $t2 = Addr(v[j]) lw$t3, 0($t2)# $t3 v[j] lw$t4, 4($t2)# $t4 v[j+1] slt$t0, $t4, $t3# if (v[j+1]<v[j]) $t0 1 beq$t0, $zero, exit2 move$a1, $s1# $a1 j jalswap# add$s1, $s1, 1# j j+1 jfor2test exit2:addi$s0, $s0, 1# i i+1 jfor1test# go back to test of outer loop exit1: void swap (int v[ ], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+a] = temp; } A Complete Example: The sort procedure Conflicting use of $a1
CMPUT Computer Organization and Architecture I14 void sort (int v[ ], int n ) { int i, j; for (i=0 ; i < n ; i=i+1) for(j=i-1; j >= 0 && v[j] > v[j+1]; j=j+1) swap(v,,j); } move$s3, $a1# $s3 n move$s0, $zero# i 0 for1test: slt$t0, $s0, $s3# if(i<n) $t0 1 else $t0 0 beq$t0, $zero, exit1# addi$s1, $s0, -1# j i-1 for2test:slti$t0, $s1, 0# if(j<0) $t0 1 else $t0 0 bne$t0, $zero, exit2 add$t1, $s1, $s1# $t1 2*j add$t1, $t1, $t1# $t1 4*j add$t2, $a0, $t1# $t2 = Addr(v[j]) lw$t3, 0($t2)# $t3 v[j] lw$t4, 4($t2)# $t4 v[j+1] slt$t0, $t4, $t3# if (v[j+1]<v[j]) $t0 1 beq$t0, $zero, exit2 move$a1, $s1# $a1 j jalswap# add$s1, $s1, 1# j j+1 jfor2test exit2:addi$s0, $s0, 1# i i+1 jfor1test# go back to test of outer loop exit1: void swap (int v[ ], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+a] = temp; } A Complete Example: The sort procedure $a0 is a caller-saved register. It might not be preserved by swap!
CMPUT Computer Organization and Architecture I15 void sort (int v[ ], int n ) { int i, j; for (i=0 ; i < n ; i=i+1) for(j=i-1; j >= 0 && v[j] > v[j+1]; j=j+1) swap(v,,j); } move$s2, $a0 move$s3, $a1# $s3 n move$s0, $zero# i 0 for1test: slt$t0, $s0, $s3# if(i<n) $t0 1 else $t0 0 beq$t0, $zero, exit1# addi$s1, $s0, -1# j i-1 for2test:slti$t0, $s1, 0# if(j<0) $t0 1 else $t0 0 bne$t0, $zero, exit2 add$t1, $s1, $s1# $t1 2*j add$t1, $t1, $t1# $t1 4*j add$t2, $s2, $t1# $t2 = Addr(v[j]) lw$t3, 0($t2)# $t3 v[j] lw$t4, 4($t2)# $t4 v[j+1] slt$t0, $t4, $t3# if (v[j+1]<v[j]) $t0 1 beq$t0, $zero, exit2 move$a1, $s1# $a1 j jalswap# add$s1, $s1, 1# j j+1 jfor2test exit2:addi$s0, $s0, 1# i i+1 jfor1test# go back to test of outer loop exit1: void swap (int v[ ], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+a] = temp; } A Complete Example: The sort procedure What must be saved in the stack? Have to save $ra
CMPUT Computer Organization and Architecture I16 void sort (int v[ ], int n ) { int i, j; for (i=0 ; i < n ; i=i+1) for(j=i-1; j >= 0 && v[j] > v[j+1]; j=j+1) swap(v,,j); } void swap (int v[ ], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+a] = temp; } A Complete Example: The sort procedure sort:addi$sp, $sp, -20# make room for 4 items sw$ra, 16($sp)# save $ra sw$s3, 12($sp)# save $s3 sw$s2, 8($sp)# save $s2 sw$s1, 4($sp)# save $s1 sw$s0, 0($sp)# save $s0 move$s3, $a1# $s3 n move$s0, $zero# i 0 for1test: slt$t0, $s0, $s3# if(i<n) $t0 1 else $t0 0 beq$t0, $zero, exit1# addi$s1, $s0, -1# j i-1 for2test:slti$t0, $s1, 0# if(j<0) $t0 1 else $t0 0 bne$t0, $zero, exit2 … # load v[j] and v[j+1] slt$t0, $t4, $t3# if (v[j+1]<v[j]) $t0 1 beq$t0, $zero, exit2 move$a1, $s2# $a1 j jalswap# add$s1, $s1, 1# j j+1 jfor2test addi$s0, $s0, 1# i i+1 jfor1test# go back to test of outer loop exit2:addi$s0, $s0, 1# i i+1 jfor1test# go back to test of outer loop exit1:lw$s0, 0($sp)# save $s0 lw$s1, 4($sp)# save $s1 lw$s2, 8($sp)# save $s2 sw$s3, 12($sp)# save $s3 sw$ra, 16($sp)# save $ra addi$sp, $sp, 20# restore stack pointer jr$ra
CMPUT Computer Organization and Architecture I17 void sort (int v[ ], int n ) { int i, j; for (i=0 ; i < n ; i=i+1) for(j=i-1; j >= 0 && v[j] > v[j+1]; j=j+1) swap(v,,j); } void swap (int v[ ], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+a] = temp; } A Complete Example: The sort procedure swap:… add$t1, $a1, $a1# $t1 2*k add$t1, $t1, $t1# $t1 4*k add$t1, $a0, $t1# $t1 Addr(v[k]) lw$t0, 0($t1)# $t0 v[k] lw$t2, 4($t1)# $t2 v[k+1] sw$t2, 0($t1)# v[k] $t2 sw$t0, 4($t1)# v[k+1] $t0... jr$ra What do I need to save/restore in the stack for the swap procedure?
CMPUT Computer Organization and Architecture I18 void sort (int v[ ], int n ) { int i, j; for (i=0 ; i < n ; i=i+1) for(j=i-1; j >= 0 && v[j] > v[j+1]; j=j+1) swap(v,,j); } void swap (int v[ ], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+a] = temp; } A Complete Example: The sort procedure swap:add$t1, $a1, $a1# $t1 2*k add$t1, $t1, $t1# $t1 4*k add$t1, $a0, $t1# $t1 = Addr(v[k]) lw$t0, 0($t1)# $t0 v[k] lw$t2, 4($t1)# $t2 v[k+1] sw$t2, 0($t1)# v[k] $t2 sw$t0, 4($t1)# v[k+1] $t0 jr$ra What do I need to save/restore in the stack for the swap procedure? Nothing!
CMPUT Computer Organization and Architecture I19 Tail Recursion int sum (int n, int acc ) { if ( n>0 ) return sum(n-1, acc+n); else return acc; } sum(3,0) sum(2,3)sum(1,5)sum(0,6) 666
CMPUT Computer Organization and Architecture I20 Tail Recursion int sum (int n, int acc ) { if ( n>0 ) return sum(n-1, acc+n); else return acc; } MIPS assembly (tail recursion): sum: ble $a0, $zero, sum_exit # if n 0, goto sum_exit add $a1, $a1, $a0# acc acc + n addi $a0, $a0, -1# n n-1 j sum# goto sum sum_exit:move $v0, $a1# return acc jr $ra# return to caller MIPS assembly (standard recursion code): sum: subi $sp, $sp, 4 # Make room in stack for 1 more items sw $ra, 4($sp)# save the return address ble $a0, $zero, L1# if n 0, go to L1 add $a1, $a1, $a0# $a1 acc+n addi $a0, $a0, -1# $a0 n-1 jal sum# call sum(n-1,acc+n) L1: move $v0, $a1# return acc lw $ra, 4($sp)# restore the return address addi $sp, $sp, 4# pop a word from the stack jr $ra# return to caller