# CMPE 325 Computer Architecture II Cem Ergün Eastern Mediterranean University Assembly Language (cont)

## Presentation on theme: "CMPE 325 Computer Architecture II Cem Ergün Eastern Mediterranean University Assembly Language (cont)"— Presentation transcript:

CMPE 325 Computer Architecture II Cem Ergün Eastern Mediterranean University Assembly Language (cont)

CMPE 325 CH #3Slide #2 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 325 CH #3Slide #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 325 CH #3Slide #4 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 325 CH #3Slide #5 Loop Efficiency Code uses two branches/iteration: Better structure: Cond? Body of loop Cond? Body of loop

CMPE 325 CH #3Slide #6 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 325 CH #3Slide #7 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 325 CH #3Slide #8 MIPS Comparisons InstructionExampleMeaningComments set less thanslt \$1, \$2, \$3\$1 = (\$2 < \$3) comp less than signed set less than immslti \$1, \$2, 100\$1 = (\$2 < 100) comp w/const signed set less than unssltu \$1, \$2, \$3\$1 = (\$2 < \$3) comp < unsigned set l.t. imm. unssltiu \$1, \$2, 100\$1 = (\$2 < 100) comp < const unsigned

CMPE 325 CH #3Slide #9 MIPS Jumps & Branches InstructionExampleMeaning jumpj Lgoto L jump registerjr \$1goto value in \$1 jump and linkjal Lgoto L and set \$ra jump and link registerjalr \$1goto \$1 and set \$ra branch equalbeq \$1, \$2, Lif (\$1 == \$s2) goto L branch not eqbne \$1, \$2, Lif (\$1 != \$2) goto L branch l.t. 0bltz \$1, Lif (\$1 < 0) goto L branch l.t./eq 0blez \$1, Lif (\$1 <= 0) goto L branch g.t. 0bgtz \$1, Lif (\$1 > 0) goto L branch g.t./eq 0bgez \$1, Lif (\$1 >= 0) goto L

CMPE 325 CH #3Slide #10 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 #3Slide #11 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 325 CH #3Slide #12 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 076543210h lui \$s0, 0  7654 # \$s0 is set to 0  76540000 h addi \$s0, \$s0,0  3210 # After addition 0  76543210 h

CMPE 325 CH #3Slide #13 Logical Operators Bitwise operators often useful for converting &&, ||, and ! symbols into assembly Always operate unsigned (more later)

CMPE 325 CH #3Slide #14 MIPS Logical Instructions InstructionExampleMeaningComments and and \$1, \$2, \$3\$1 = \$2 & \$3Logical AND oror \$1, \$2, \$3\$1 = \$2 | \$3Logical OR xorxor \$1, \$2, \$3\$1 = \$2 \$3Logical XOR nornor \$1, \$2, \$3\$1 = ~(\$2 | \$3)Logical NOR and immediateandi \$1, \$2, 10\$1 = \$2 & 10Logical AND w. constant or immediateori \$1, \$2, 10\$1 = \$2 | 10Logical OR w. constant xor immediate xori \$1, \$2, 10 \$1 = ~\$2 & ~10Logical XOR w. constant shift left logsll \$1, \$2, 10\$1 = \$2 << 10Shift left by constant shift right logsrl \$1, \$2, 10\$1 = \$2 >> 10Shift right by constant shift right arithsra \$1, \$2, 10\$1 = \$2 >> 10Shift right (sign extend) shift left log varsllv \$1, \$2, \$3\$1 = \$2 << \$3 Shift left by variable shift right log varsrlv \$1, \$2, \$3 \$1 = \$2 >> \$3 Shift right by variable shift right arithsrav \$1, \$2, \$3 \$1 = \$2 >> \$3 Shift right arith. by var load upper imm lui \$1, 40 \$1 = 40 << 16Places imm in upper 16b

CMPE 325 CH #3Slide #15 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 325 CH #3Slide #16 Procedure Steps 1. Place parameters in a place where the procedure can access them 2. Transfer control to the procedure 3. Acquire 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 #3Slide #17 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 325 CH #3Slide #18 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 #3Slide #19 Calling a Procedure To jump to a procedure, use the jal jump-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 325 CH #3Slide #20 jal and jr Instructions jal Prod_Addr (J-Type) first increments the program counter (PCPC+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. 3Prod_Addr/4 0310008

CMPE 325 CH #3Slide #21 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 325 CH #3Slide #22 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 325 CH #3Slide #23 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.

CMPE 325 CH #3Slide #24 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 325 CH #3Slide #25 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 325 CH #3Slide #26 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 #3Slide #27 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 325 CH #3Slide #28 Nested Stacks The stack grows and shrinks downward A: A CALL B B: A B CALL C A B C C: RET A B A

CMPE 325 CH #3Slide #29 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. 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; }

CMPE 325 CH #3Slide #30 Coding Example –Main Body 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;..... 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.

CMPE 325 CH #3Slide #31 Coding Example - Procedure f() 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: f procedure void f(int j, int x[]) { if (j= =7) x[2]=6*x[1]–x[0]; else g(y); } \$a0 is corrupted \$ra is corrupted Callee saves the registers Callee restores the registers jr \$ra return of procedure f() 2-words = 8 bytes f: label of procedure addi \$sp,\$sp, -8 sw \$a0, 0(\$sp) sw \$ra, 4(\$sp) lw \$a0, 0(\$sp) lw \$ra, 4(\$sp) addi \$sp,\$sp, 8

CMPE 325 CH #3Slide #32 Coding Example – Procedure g() g() procedure void g(int y[]) { int i; for (i=2;i<12;i++) y[i]*=2; y[2] – = 4; } 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)# \$t3  y[2] addi \$t3, \$t3,–4# \$t3  y[2] – 4 sw \$t3, 8(\$a0)# y[2]  y[2] – 4 jr \$31 Only temporary registers are used No registers need to be saved.