340 likes | 433 Views
CMPE 3 2 5 Computer Architecture II. Cem Erg ün Eastern Med iterranean University. Assembly Language (cont). Loop Example. Consider the code where array A is an integer array with 100 elements Loop: g = g + A[i] i = i + j; if (i != h) goto Loop: g: $s0 h: $s1 i: $s2 j: $s3 A: $s4.
E N D
CMPE 325 Computer Architecture II Cem Ergün Eastern Mediterranean University Assembly Language (cont)
Loop Example • Consider the code where array A is an integer array with 100 elements Loop: g = g + A[i] i = i + j; if (i != h) goto Loop: g: $s0 h: $s1 i: $s2 j: $s3 A: $s4 CMPE 325CH #3
Loop Solution • Use a conditional test Loop: add $t0, $s2, $s2 # $t0 = 2 * i add $t0, $t0, $t0 # $t0 = 4 * i add $t1, $t0, $s4 # $t1 = &(A[i]) lw $t2, 0($t1) # $t2 = A[i] add $s0, $s0, $t2 # g = g + A[i] add $s2, $s2, $s3 # i = i + j bne $s2, $s1, Loop # goto Loop if i!=h • This sequence is known as a basic block since it has one entrance and one exit CMPE 325CH #3
Loops in C • Consider a very similar case with while while (A[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 = &(A[i]) lw $t2, 0($t1) # $t2 = A[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 325CH #3
Loop Efficiency • Code uses two branches/iteration: • Better structure: Branch Cond? Branch Body of loop Branch Cond? Body of loop Exit Branch Exit CMPE 325CH #3
Improved Loop Solution • 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 = &(A[i]) lw $t2, 0($t1) # $t2 = A[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 325CH #3
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; • Solution slt $t0, $s0, $s1 # $t0 = 1 if $s0 < $s1 bne $t0, $zero, Less # Goto Less if $t0 != 0 CMPE 325CH #3
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 CMPE 325CH #3
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 325CH #3
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 325CH #3
Pseudoinstructions • Assembler expands pseudoinstructions move $t0, $t1 # Copy $t1 to $t0 add $t0, $zero, $t1 # Actual 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 CMPE 325CH #3
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 # Actual instruction • Example: Write a MIPS code to load 076543210h lui $s0, 07654 # $s0 is set to 076540000 h addi $s0, $s0,03210 # After addition 076543210 h CMPE 325CH #3
Logical Operators • Bitwise operators often useful for converting &&, ||, and ! symbols into assembly • Always operate unsigned (more later) CMPE 325CH #3
MIPS Logical Instructions Instruction Example Meaning Comments and and $1, $2, $3 $1 = $2 & $3 Logical AND 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 AND 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 325CH #3
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 • Arguments must be passed in and return values passed out • Execution must continue after the call CMPE 325CH #3
Procedure Steps • Place parameters in a place where the procedure can access them • Transfer control to the procedure • Acquire the storage resources needed for the procedure • Perform the desired task • Place the result value in a place where the calling program can access it • Return control to the point of origin CMPE 325CH #3
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 CMPE 325CH #3
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 325CH #3
Calling a Procedure • To jump to a procedure, use the jaljump-and-link 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 CMPE 325CH #3
jal and jrInstructions • jal Prod_Addr (J-Type) • first increments the program counter (PCPC+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, • PC$ra causes to jump back to the stored return address. CMPE 325CH #3
Who saves the register? • Caller save All 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. CMPE 325CH #3
Argument 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). • Any 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 325CH #3
Register SavingConventions • 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 . CMPE 325CH #3
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 Assembly. CMPE 325CH #3
Coding Example -swap • Allocate 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. 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 swap(int v[], int k) { int temp; temp = v[k]; v[k] = v[k+1]; v[k+1] = temp; } CMPE 325CH #3
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 325CH #3
Nested Calls A 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. CMPE 325CH #3
A A: CALL B A B: B CALL C A C: B RET C A B RET A Nested Stacks • The stack grows and shrinks downward CMPE 325CH #3
Coding Example: Procedures • Assume x[ ] starts from 10000 and y[ ] starts from 20000. Code the following program in MIPS Assembler • starting main from address 300, and f from 400. CMPE 325CH #3
Coding Example –Main Body • allocate registers • two arguments in f(), use $a0, $a1one 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 … Main pocedure . . . . . j=5 f(j,x); x[3]+=5; . . . . . CMPE 325CH #3
Coding Example -Procedure f() label of procedure f: addi $sp,$sp, -8 sw $a0, 0($sp) sw $ra, 4($sp) 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 6x[1] – x[0]; sw $t1,8($a1) # x[2] 6x[1] – x[0]; j ExitIf Else: li $a0,20000 jal g ExitIf: 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 Callee restores the registers $a0 is corrupted lw $a0, 0($sp) lw $ra, 4($sp) addi $sp,$sp, 8 return of procedure f() $ra is corrupted jr $ra CMPE 325CH #3
Coding Example – Procedure g() g: li $t0, 2 # $10= i 2 for loop Loop: slti $t1,$t0,12# if ( i < 12) then $t11 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)# $t3 y[2] addi $t3,$t3,–4#$t3 y[2] – 4 sw $t3, 8($a0)# y[2] y[2] – 4 jr $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. CMPE 325CH #3
Decimal Coding of a Program • coding starts from memory address 300ten. 100= 400/4 8= (392–360)/4 115= 460/4 119= 476/4 CMPE 325CH #3
Decimal Coding of a Program-2 • continuation of coding 7 =(516-488)/4 120 =480/4 CMPE 325CH #3