MIPS - Conditional Statements - stud ver PDF

Title MIPS - Conditional Statements - stud ver
Author Anis Sabrina
Course Computer Architecture And Organization
Institution Universiti Teknikal Malaysia Melaka
Pages 16
File Size 261 KB
File Type PDF
Total Downloads 5
Total Views 146

Summary

In this project we are required to create a program to be run in QTSPIM
which is allowed user to input 10 random numbers. After user entered
the numbers, this program should be able to display:
• Numbers that have been SORTED from descending order
• SUM of the entered numbers...


Description

Example code to input string from console #readString.asm .data array1: .space 64 char

#allocate 64 bytes or 64 element

.text .globl main main: li $v0,8 #load syscall 8 for read string la $a0, array1 #set buffer array1 to $a0 li $a1, 64 #length is 64 space syscall

jr $ra 



Run the code above on QtSPIM and type any string (e.g. your name) but make sure it does not exceed 63 character including space between words once the console is pop out on the monitor. Once you have finish run the code, look into your User Data Segment. You will find strings that you have type stored in the buffer. Use this code for your mini project.

Conditional Statements Introduction We're going to translate some easy conditional statements. if ( i == j ) i++ ; j-- ;

Translating conditional statements is interesting. In C, for example, when the condition is true, you execute the body. This is the fall-through case. That is, you execute the next statement. When the condition is false, you don't execute the body, you jump over it. This is the jump case. Therefore, you jump when the condition is false. In ISA programming, you jump when the condition is true. Thus, we often need to negate the condition.

Here's the translation of the above if-statement, assuming $r1 stores i and $r2 stores j. bne $r1, $r2, L1 addi $r1, $r1, 1 L1: addi $r2, $r2, -1

# branch if ! ( i == j ) # i++ # j--

The label L1 has the same address as the instruction immediately following the colon. Thus, the above code is the same as: bne $r1, $r2, L1 addi $r1, $r1, 1

# branch if ! ( i == j ) # i++

addi $r2, $r2, -1

# j--

L1:

Even though it appears that label L1 has an empty instruction, it doesn't. It is still associated with the second addi instruction.

Translating if-else Let's translate if ( i == j ) i++ ; else j-- ; j += i ;

Let's think about what happens. As before, if the condition is false, we want to jump. This time, we want to jump to the else. Thus, we write the code like: bne $r1, $r2, ELSE addi $r1, $r1, 1 ELSE: addi $r2, $r2, -1

# branch if ! ( i == j ) # i++ # j--

This code is wrong however. Why? The if-body contains i++. Once we're done with that, we need to jump over the else-body. This jump is unconditional, so we use j instruction to jump over the else-body. bne $r1, $r2, ELSE addi $r1, $r1, 1 j L1 ELSE: addi $r2, $r2, -1 L1: add $r2, $r2, $r1

# # # # #

branch if ! ( i == j ) i++ jump over else (ADD THIS!!!) j-j += i

Translating if-else with && Translating && is interesting because there's short-circuiting involved. To see how this works, let's translate:

if ( i == j && i == k ) i++ ; // if-body else j-- ; // else-body j = i + k ;

To make this easier to read, let stand for i == j and stand for i == k. if ( && ) i++ ; // if-body else // else-body j-- ; j = i + k ;

Short-circuiting occurs when evaluates to false. The control-flow then jumps over (that is, is not evaluated), and continues executing in the else-body. If evaluates to true, we want to fall-through and check . If evaluates false, we again jump, this time over the if-body, and to the else-body. If is true, we fall-through to the if-body. Notice that we jump when the condition evaluates to false for both cases, so we'll be interested in jumping on negations of conditions. Here's the translated code, assuming $r3 stores k. # cond1: branch if ! ( i == j ) bne $r1, $r2, ELSE bne $r1, $r3, ELSE # cond2: branch if ! ( i == k ) addi $r1, $r1, 1 # if-body: i++ j L1 # jump over else ELSE: addi $r2, $r2, -1 # else-body: j-L1: add $r2, $r1, $r3 # j = i + k Usually, it's good to comment each line of assembly code. We've commented a little more than usual (by adding cond1, cond2, if-body, else-body) to make it easier to understand. Assembly language code is often much harder to read, so commenting every line is not unusual. The idea is to comment it with C code, whenever possible.

Translating if-else with || Translating && is interesting because there's short-circuiting involved, and the short-circuiting for || is even more interesting than for &&. Let's translate

if ( i == i++ ; else j-- ; j = i + k

j || i == k ) // if-body // else-body ;

Again, let's use to stand for i == j and to stand for i == k. if ( || )

i++ ; // if-body else j-- ; // else-body j = i + k ;

Short-circuiting occurs when evaluates to true. That is, we want to jump over checking the second condition and into the if-body. Notice that we go to the if-body when the condition evaluates to true. When the operator was &&, we jumped to the else-body when evaluated to false. If is false, we want to fall-through and check . If is false, we now jump to the else-body. If is true, we fall-through to the if-body. Notice that we jump when evaluates to true (to the if-body) and when evaluates to false (to the else-body). Here's the translated code: beq $r1, $r2, IF bne $r1, $r3, ELSE IF: addi $r1, $r1, 1 j L1 ELSE: addi $r2, $r2, -1 L1: add $r2, $r1, $r3

# # # # # #

cond1: branch if ( i == j ) cond2: branch if ! ( i == k ) if-body: i++ jump over else else-body: j-j = i + k

switch statements switch statements are interesting. One should note that false, we now jump to the elsebodyswitch works on a very limited number of types (int and char, primarily). It doesn't work on strings (even if students wish they did). switch evaluates case-by-case. When one condition fails, the next is checked. When a condition is true, the code associated with that condition is run. However, if you don't put break the code for the next condition will also run. Unfortunately, most people expect a break to occur when the condition is done. They don't expect a fall-through case. Here's an example of a switch.

switch( i ) { case 1: i++ ; // falls through case 2: i += 2 ; break;

case 3: i += 3 ; } Here's the translated code.

C2_COND: C3_COND: C1_BODY: C2_BODY: C3_BODY: EXIT:

addi $r4, $r0, 1 bne $r1, $r4, C2_COND j C1_BODY addi $r4, $r0, 2 bne $r1, $r4, C3_COND j C2_BODY addi $r4, $r0, 3 bne $r1, $r4, EXIT j C3_BODY addi $r1, $r1, 1 addi $r1, $r1, 2 j EXIT addi $r1, $r1, 3

# # # # # # # # # # # # #

set temp to 1 case 1 false: branch to case 2 cond case 1 true: branch to case 1 set temp to 2 case 2 false: branch to case 2 cond case 2 true: branch to case 2 body set temp to 3 case 3 false: branch to exit case 3 true: branch to case 3 body case 1 body: i++ case 2 body: i += 2 break case 3 body: i += 3

Notice that EXIT, the last label, doesn't have an instruction after it. That's OK. The assembler can still figure out the address of EXIT (by pretending there is an instruction there). Translating switch, at least as I've done it, involves a large prelude. The first half of the code determines where to jump to. The second half is pretty much the code itself. The real problem is the fall-through cases. When case 1 is true, you want to run i++, then i += 2. You don't want to test for case 2, because that's now how the semantics of switch works.

bge, bgt, blt, ble bge, bgt, blt, ble are all pseudo-instructions. That is, there is no corresponding machine code to these instructions. Nevertheless, you can use them in assembly language programs because most assemblers support these pseudo-instructions. They translate them to real instructions. Let's see an example of how the assembler might translate bge. The key is to use slt which means "set on less than". Here is the syntax of slt.

slt $r1, $r2, $r3 1 : 0

# R[1] = R[2] < R[3] ?

The semantics are shown in the comments: if R[2] < R[3] false, we now jump to the elsebodythen R[1] = 1, otherwise it's assigned to 0. Here is the syntax and semantics of bge:

bge $r1, $r2, LABEL R[1] >= R[2]

# jump to LABEL if

If R[1] >= R[2] we know that this is equivalent to !( R[1] < R[2]). Thus, if we check R[1] < R[2] using slt, we expect it to be false. Here's the translation of bge.

# check if R[1] <

slt $r3, $r1, $r2 R[2] beq $r3, $r0, LABEL condition is false

# branch if previous

Loops in MIPS while (){

loop: if





}

j loop

#jump to loop

Example: while (i < j){

loop: if

(i < j){

k++;

k++;

i = i * 2;

i = i * 2;

}

goto loop; }

In MIPS: loop: bge $8, $9, DONE

#branch if !(i < j)

addiu $10, $10, 1

#

k++;

add $8, $8, $8

#

i = i * 2;

#

-> increase counter i

j loop DONE:

#jump to loop #out of loop body

Notice that DONE is outside of while loop body as an exit of the loop if the condition is met. Write the while loop condition so that the loop will stop or exit the loop

Loops: for for ( ; ; ) {

} Equivalent while loop: ; ; while ( ) { L1: if ( ) { } goto L1 ; } DONE:

Array: C++ Problem: Given an array of int, calculate the sum of: all the elements in the array all the positive elements in the array all the negative elements in the array main () { int i, size = 10, sum, pos, neg; int arr[10] = {12, -1, 8, 0, 6, 85, -74, 23, 99, -30}; sum = 0; pos = 0; neg = 0; for (i = 0; i < size; i++) { sum += arr[i]; if (arr[i] > 0)

pos += arr[i]; if (arr[i] < 0) neg += arr[i]; } return 0; }

Array: assembler # initialize data .data size: .word 10 arr: .word 12, -1, 8, 0, 6, 85, -74, 23, 99, -30 .text .globl main main: la $s0, size lw $s1, 0($s0) ori $s2, $0, 0 ori $s3, $0, 0 ori $s4, $0, 0 # ori $s5, $0, 0 la $s6, arr

# # # # #

initialize registers $s1 = size $s2 = sum $s3 = pos $s4 = neg

# $s5 = i = 0 # $s6 = &arr

# if () L1: bge $s5, $s1, DONE # -> operation inside for loop lw $s7, 0($s6) # $s7 = arr[i] addu $s2, $s2, $s7 # sum += arr[i] blez $s7, NEG # if ! (arr[i] > 0) addu $s3, $s3, $s7 # pos += arr[i]; j UPDATE # goto UPDATE

NEG: bgez $s7, UPDATE addu $s4, $s4, $s7

# if ! (arr[i] < 0) # neg += arr[i];

UPDATE: # ->increase counter and array address addi $s5, $s5, 1 # i++ addi $s6, $s6, 4 # move array pointer j L1 # goto L1 DONE: li $v0,10 Syscall

####################################################### ## ###### BUBBLE SORT ### ####################################################### ## .data .align 4 Table: .space 24 msg1: .asciiz "Please insert an integer: " msg2: .asciiz " " msg3: .asciiz "\nVector contents: " .text .globl main main: addi $s0,$0,5 addi $t0,$0,0

#s0 = 5 (size array - 1) #t0 = 0

in: li $v0,4 la $a0,msg1 syscall integer:" li $v0,5 syscall

#load msg1 into $a0 #cout...


Similar Free PDFs