CMPE 325 Computer rchitecture II Cem Ergün Eastern Mediterranean University ssembly Language (cont) Loop Example Consider the code where array is an integer array with 100 elements Loop: g = g + [i] i = i + j; if (i!= h) goto Loop: g: $s0 h: $s1 i: $s2 j: $s3 : $s4 CMPE 325 CH #3 Slide #2 Loop Solution Use a conditional test Loop: add $t0, $s2, $s2 add $t0, $t0, $t0 add $t1, $t0, $s4 lw $t2, 0($t1) add $s0, $s0, $t2 add $s2, $s2, $s3 bne $s2, $s1, Loop # $t0 = 2 * i # $t0 = 4 * i # $t1 = &([i]) # $t2 = [i] # g = g + [i] # i = i + j # goto Loop if i!=h This sequence is known as a basic block since it has one entrance and one exit Loops in C Consider a very similar case with while while ([i] == k) i = i + j; Use a similar loop as before Loop: add $t0, $s0, $s0 # $t0 = 2 * i add $t0, $t0, $t0 # $t0 = 4 * i add $t1, $t0, $s3 # $t1 = &([i]) lw $t2, 0($t1) # $t2 = [i] bne $t2, $s2, Exit # goto Exit if!= add $s0, $s0, $s1 # i = i + j j Loop # goto Loop Exit: What is wrong with this approach? CMPE 325 CH #3 Slide #3 CMPE 325 CH #3 Slide #4 Loop Efficiency Improved Loop Solution Code uses two branches/iteration: Cond? Body of loop Better structure: Body of loop Cond? Remove extra branch j Cond # goto Cond Loop: add $s0, $s0, $s1 # i = i + j Cond: add $t0, $s0, $s0 # $t0 = 2 * i add $t0, $t0, $t0 # $t0 = 4 * i add $t1, $t0, $s3 # $t1 = &([i]) lw $t2, 0($t1) # $t2 = [i] beq $t2, $s2, Loop # goto Loop if == Exit: Reduced loop from 7 to 6 instructions Even small improvements important if loop executes many times CMPE 325 CH #3 Slide #5 CMPE 325 CH #3 Slide #6 1
Other Comparisons Other conditional arithmetic operators are useful in evaluating conditional expressions using <, >, <=, >= Conditional expressions also useful in signed vs. unsigned integers (to be discussed later) Register is set to 1 when condition is met Consider the following code if (f < g) goto Less; MIPS Comparisons Instruction Example Meaning Comments set less than slt $1, $2, $3 $1 = ($2 < $3) comp less than signed set less than imm slti $1, $2, 100 $1 = ($2 < 100) comp w/const signed set less than uns sltu $1, $2, $3 $1 = ($2 < $3) comp < unsigned set l.t. imm. uns sltiu $1, $2, 100 $1 = ($2 < 100) comp < const unsigned Solution slt $t0, $s0, $s1 # $t0 = 1 if $s0 < $s1 bne $t0, $zero, Less # Goto Less if $t0!= 0 CMPE 325 CH #3 Slide #7 CMPE 325 CH #3 Slide #8 MIPS Jumps & Branches Instruction Example Meaning jump j L goto L jump register jr $1 goto value in $1 jump and link jal L goto L and set $ra jump and link register jalr $1 goto $1 and set $ra branch equal beq $1, $2, L if ($1 == $s2) goto L branch not eq bne $1, $2, L if ($1!= $2) goto L branch l.t. 0 bltz $1, L if ($1 < 0) goto L branch l.t./eq 0 blez $1, L if ($1 <= 0) goto L branch g.t. 0 bgtz $1, L if ($1 > 0) goto L branch g.t./eq 0 bgez $1, L if ($1 >= 0) goto L CMPE 325 CH #3 Slide #9 Simplicity Notice that there was no branch less than instruction for comparing two registers? The reason is that such an instruction would be too complicated and would force a longer clock cycle time Therefore, conditionals that are not comparing against zero take at least two instructions where the first is a set and the second is a conditional branch The MIPS assembler supports pseudoinstructions for such operators and automatically converts them to the appropriate sequence of MIPS instructions CMPE 325 CH #3 Slide #10 Pseudoinstructions ssembler expands pseudoinstructions move $t0, $t1 # Copy $t1 to $t0 add $t0, $zero, $t1 # ctual instruction Some pseudoinstructions need a temporary register Cannot use $t, $s, etc. since they may be in use The $at register is reserved for the assembler blt $t0, $t1, L1 # Goto L1 if $t0 < $t1 slt $at, $t0, $t1 # Set $at = 1 if $t0 < $t1 bne $at, $zero, L1 # Goto L1 if $at!= 0 Pseudoinstructions (cont) The pseudoinstruction load immediate (li) provides transfer of a 16-bit constant value to reg li $t0, imm # Copy 16bit imm. value to $t0 addi $t0, $zero, imm# ctual instruction Example: Write a MIPS code to load 0 76543210h lui $s0, 0 7654 # $s0 is set to 0 76540000 h addi $s0, $s0,0 3210 # fter addition 0 76543210 h CMPE 325 CH #3 Slide #11 CMPE 325 CH #3 Slide #12 2
Logical Operators Bitwise operators often useful for converting &&,, and! symbols into assembly lways operate unsigned (more later) MIPS Logical Instructions Instruction Example Meaning Comments and and $1, $2, $3 $1 = $2 & $3 Logical ND or or $1, $2, $3 $1 = $2 $3 Logical OR xor xor $1, $2, $3 $1 = $2 $3 Logical XOR nor nor $1, $2, $3 $1 = ~($2 $3) Logical NOR and immediate andi $1, $2, 10 $1 = $2 & 10 Logical ND w. constant or immediate ori $1, $2, 10 $1 = $2 10 Logical OR w. constant xor immediate xori $1, $2, 10 $1 = ~$2 & ~10 Logical XOR w. constant shift left log sll $1, $2, 10 $1 = $2 << 10 Shift left by constant shift right log srl $1, $2, 10 $1 = $2 >> 10 Shift right by constant shift right arith sra $1, $2, 10 $1 = $2 >> 10 Shift right (sign extend) shift left log var sllv $1, $2, $3 $1 = $2 << $3 Shift left by variable shift right log var srlv $1, $2, $3 $1 = $2 >> $3 Shift right by variable shift right arith srav $1, $2, $3 $1 = $2 >> $3 Shift right arith. by var load upper imm lui $1, 40 $1 = 40 << 16 Places imm in upper 16b CMPE 325 CH #3 Slide #13 CMPE 325 CH #3 Slide #14 Handling Procedures Procedures are useful for decomposing applications into smaller units Implementing procedures in assembly requires several things to be done Space must be set aside for local variables rguments must be passed in and return values passed out Execution must continue after the call Procedure Steps 1. Place parameters in a place where the procedure can access them 2. Transfer control to the procedure 3. cquire 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 CMPE 325 CH #3 Slide #15 CMPE 325 CH #3 Slide #16 Stacks Stacks are a natural way to temporarily store data for procedures (as well as call/return information) since they have a LIFO behavior Data is pushed onto the stack to store it and popped from the stack when not longer needed Implementation Common rules across procedures required Recent machines are set by software convention and earlier machines by hardware instructions Using Stacks Stacks can grown up or down Stack grows down in MIPS Entire stack frame is pushed and popped, rather than single elements CMPE 325 CH #3 Slide #17 CMPE 325 CH #3 Slide #18 3
Calling a Procedure To jump to a procedure, use the jal jump-andlink instruction jal tartget # Jump and link to label Saves the address of the next location into to register-31 and Jumps to the specified 26-bit local word address jal and jr Instructions jal Prod_ddr (J-Type) first increments the program counter (PC PC+4), 3 Prod_ddr/4 so that it points to the next location, then it stores that value into $ra (= $31). jr $ra (R-Type) copies $ra into PC, 0 31 0 0 0 8 PC $ra causes to jump back to the stored return address. CMPE 325 CH #3 Slide #19 CMPE 325 CH #3 Slide #20 Who saves the register? Caller save ll values that have to be kept must be saved before a procedure is called. Callee save Within the procedure all used registers are saved and afterwards restored. rgument Passing Convention Return value is transferred in $v0 $v1. ($v0 and $v1) corresponds to ($2 and $3) Integer arguments up to four are passed in registers $a0 $a3. (= $4 $7). ny higher data structure is passed by a pointer. If there are more than 4 parameters, first four parameters are passed in registers, the others are transferred in the stack CMPE 325 CH #3 Slide #21 CMPE 325 CH #3 Slide #22 Register Saving Conventions Save the registers saved-registers s0 s7, arguments a0 a3, and system registers $gp, $sp, $fp and $ra before they are corrupted in a call. Restore them before the start of calling code. Procedure Coding Example The C code for swap procedure is: swap(int v[ ], int k) int temp; temp = v[k]; v[k] = v[k+1]; v[k+1] = temp; Code it in MIPS ssembly. CMPE 325 CH #3 Slide #23 CMPE 325 CH #3 Slide #24 4
Coding Example -swap llocate registers to procedure variables. swap(int v[], int k) two arguments pointer v[ ] in $a0, integer k in $a1. $t0, $t1, for temp. values and addresses Write MIPS code for the procedure body. swap(int v[ ], int k) int temp; temp = v[k]; v[k] = v[k+1]; v[k+1] = temp; sll $t1, $a1, 2 # $t1 k 4 add $t1, $a0, $t1 # $t1 v+(k 4) lw $t0, 0($t1) # $t0 = v[k] lw $t2, 4($t1) # $t2 = v[k+1] sw $t2, 0($t1) # v[k] $t2 ( = v[k+1] ) sw $t0, 4($t1) # v[k+1] $t0 (= v[k] ) Nothing to save since only temp.regs corrupted. none of $s0 $s7, $a0 $a3, $sp, $ra is corrupted CMPE 325 CH #3 Slide #25 Swap in Final Form Final form of the procedure swap: sll $t1, $a1, 2 # $t1 k 4 add $t1, $a0, $t1 # $t1 v+(k 4) lw $t0, 0($t1) # $t0 = v[k] lw $t2, 4($t1) # $t2 = v[k+1] sw $t2, 0($t1) # v[k] $t2 ( = v[k+1] ) sw $t0, 4($t1) # v[k+1] $t0 (= v[k] ) jr $ra Label to call the procedure return to caller code CMPE 325 CH #3 Slide #26 Nested Calls call in another call corrupts $ra. $ra must be saved on the stack before the second call and then restored after the return from the inner call. Nested Stacks The stack grows and shrinks downward : CLL B B: CLL C C: RET RET B C B B CMPE 325 CH #3 Slide #27 CMPE 325 CH #3 Slide #28 Coding Example: Procedures ssume x[ ] starts from 10000 and y[ ] starts from 20000. Code the following program in MIPS ssembler starting main from address 300, and f from 400. Main pocedure j=5 f(j,x); x[3]+=5; f procedure void f(int j, int x[]) if (j= =7) x[2]=6*x[1] x[0]; else g(y); g procedure int g(int y[]) int i; for (i=2;i<12;i++) y[i]*=2; y[2] = 4; Coding Example Main Body Main pocedure j=5 f(j,x); x[3]+=5; allocate registers two arguments in f(), use $a0, $a1 one argument in g() use $a0 j and x are saved variables in g(), i is local, temporary variable. address calculations in temp.registers. Code for Main Main:... li $a0,5 li $a1,10000 jal f lw $t0,12($a1) # $t0 x[3] addi $t0,$t0,5 # $10 x[3] + 5 sw $t0,12($a1) # x[3] x[3] + 5 CMPE 325 CH #3 Slide #29 CMPE 325 CH #3 Slide #30 5
Coding Example - Procedure f() f procedure void f(int j, int x[]) if (j= =7) x[2]=6*x[1] x[0]; else g(y); 2-words = 8 bytes $a0 is corrupted $ra is corrupted f: addi $sp,$sp, -8 sw $a0, 0($sp) sw $ra, 4($sp) label of procedure Callee saves the registers li $t0,7 # if (j!=7 ) bne $a0, $t0, Else # go to Else. li $t1, 6 # $t1 6, lw $t2, 4($a1) # $t2 x[1] mult $t2, $t1 # LO 6 x[1] mflo $t2 # $t2 6 x[1] lw $t1, 0($a1) # $t1 x[0] sub $t1, $t2, $t1 # $t1 6 x[1] x[0]; sw $t1, 8($a1) # x[2] 6 x[1] x[0]; j ExitIf Else: li $a0, 20000 jal g ExitIf: Callee restores the registers lw $a0, 0($sp) lw $ra, 4($sp) addi $sp,$sp, 8 return of procedure f() jr $ra CMPE 325 CH #3 Slide #31 g() procedure void g(int y[]) int i; for (i=2;i<12;i++) y[i]*=2; y[2] = 4; Only temporary registers are used No registers need to be saved. Coding Example Procedure g() g: li $t0, 2 # $10= i 2 for loop Loop: slti $t1, $t0, 12 # if ( i < 12) then $t1 1 beq $t1,$0, ExitF # if ($t1=0) exit for-loop. sll $t2, $t0, 2 # $t2 4 i add $t2, $a0, $t2 # $t2 y[] + 4 i lw $t3, 0($t2) # $t3 y[i] add $t3, $t3,$t3 # $t3 2 y[i] sw $t3, 0($t2) # y[i] 2 y[i] addi $t0, $t0, 1 # $t0 = i i+1 j Loop # loop again ExitF: # end of for loop lw $t3, 8($a0) addi $t3, $t3, 4 # $t3 # $t3 y[2] y[2] 4 sw $t3, 8($a0) # y[2] y[2] 4 jr $31 CMPE 325 CH #3 Slide #32 Decimal Coding of a Program coding starts from memory address 300 ten. memory word contents (instruction fields) address assembly with assembly without opc rs rt rd sa fn pseudocode pseudocode 300: 8 0 4 5 li $a0,5 add $4,$0,5 304: 8 0 5 10000 li $a1,10000 add $5,$0,10000 308: 3 100 jal f jal f 312: 35 5 8 12 lw $t0,12($a1) lw $8,12($5) 316: 8 8 8 5 addi $t0,$t0,5 addi $8,$8,5 320: 43 5 8 12 sw $t0,12($a1) sw $8,12($5). F: 400: 8 29 29 8 addi $sp,$sp, 8 addi $29,$29, 8 404: 43 29 4 0 sw $a0,0($sp) sw $4,0($29) 408: 43 29 31 20 sw $ra,4($sp) sw $31,4($29) 412: 8 0 8 7 li $t0,7 addi $8,7 416: 5 4 8 8 bne $4,$t0,Else bne $4,$8,Else 420: 8 0 9 6 li $t1,6 addi $9,$0,6 424: 35 5 10 4 lw $t2,4($a1) lw $10,4($5) 428: 0 10 9 0 0 35 mult $t2,$t1 mult $10,$9 432: 0 0 0 10 0 18 mflo $t2 mflo $10 436: 35 5 9 0 lw $t1,0($a1) lw $9,0($5) 440: 0 10 9 9 0 34 sub $t1,$t2,$t1 sub $9,$10,$9 444: 43 5 9 8 sw $t1,8($a1) sw $9,8($5) 448: 2 115 j ExitIf j ExitIf Else: 452: 8 0 4 20000 li $a0,20000 addi $4,$0,20000 456: 3 119 jal G jal G ExitIf: 460: 35 29 4 0 lw $a0,0($sp) lw $4,0($29) 464: 35 29 31 4 lw $ra,4($sp) lw $31,4($29) 468: 8 29 29 8 addi $sp,$sp,8 addi $29,$29,24 472: 0 31 0 0 0 8 jr $ra jr $31 100= 400/4 8= (392 360)/4 115= 460/4 119= 476/4 CMPE 325 CH #3 Slide #33 Decimal Coding of a Program-2 continuation of coding memory word contents (instruction fields) address opc rs rt rd sa fn assembly with pseudocode g: 476: 8 0 8 2 li $t0,2 Loop: 480: 10 8 9 12 slti $t1,$t0,12 484: 4 0 9 7 beq $t1,$0, ExitF 488: 0 0 8 10 2 0 sll $t2,$t0,2 492: 0 10 4 10 0 32 add $t2,$t2,$a0 496: 35 12 11 0 lw $t3,0($t2) 500: 0 11 11 11 0 32 add $t3,$t3,$t3 504: 43 10 11 0 sw $t3,0($t2) 508: 8 8 8 1 addi $t0,$t0,1 512: 2 120 j Loop ExitF: 516: 35 4 13 8 lw $t3, 8($a0) 520: 8 11 11 4 addi $t3,$t3, 4 524: 43 4 11 8 sw $t3, 8($a0) 528: 0 31 0 0 0 8 jr $ra.................. assembly without pseudocode addi $8,$0, 2 slti $9,$8,12 beq $9,$0, ExitF sll $10,$8,2 add $t2,$t2,$4 lw $11,0($10) add $11,$11,$11 sw $11,0($10) addi $8,$8,1 j Loop lw $11, 8($4) addi $11,$11, 4 sw $11, 8($4) jr $31... 7 =(516-488)/4 120 =480/4 CMPE 325 CH #3 Slide #34 6