* I will use FORTRAN IV (which had no such thing as blocks) as an example of the programming style we want, rather than low-level C. In FORTRAN IV, there was exactly one statement associated with an IF (as in C), but no blocks and no else statement. The only way to not execute a block of code was to jump around it to a labeled statement using the GOTO command. * In all the examples below, assume that variables a, b, c, diff, max, and temp have been defined. C FORTRAN - ------- /* compute diff = c - max(a, b) */ max = a; MAX = A if ( b > a ) IF ( B .GT. A ) MAX = B max = b; DIFF = C - MAX diff = c - max; if ( a > b ) IF ( A .LE. B ) GOTO ENDIF { temp = a; TEMP = A a = b; A = B b = temp; B = TEMP } ENDIF: DIFF = C - B diff = c - b; if ( a > b ) IF ( A .LE. B ) GOTO ELSE max = a; MAX = A else GOTO ENDIF max = b; ELSE: MAX = B diff = c - max; ENDIF: DIFF = C - MAX /* compute temp = avg(a, b) + c */ if ( a != b ) Note that code for #1 above temp = (a+b)/2; is shorter/simpler than code else for #3, so let's do it that temp = a; way instead. temp += c; temp = a; TEMP = A if ( a != b ) IF (A .EQ. B) GOTO ENDIF temp = (a+b)/2; TEMP = (A+B)/2 temp += c; ENDIF: TEMP = TEMP + C * Let's do this in MIPS using the beq (branch if equal) instruction and the move pseudo-instruction: beq reg1, reg2, label move destReg, srcReg Assume that $s0 = a, $s1 = b, $s2 = c, $t0 = temp move $t0, $s0 # temp = a beq $s0, $s1, ENDIF # if ( a == b ) goto endif add $t0, $t0, $s1 # temp += b, i.e., temp = a + b srl $t0, $t0, 1 # temp /= 2 (shift right logical) ENDIF: add $t0, $t0, $s2 # temp += c * There is also a bne (branch if not equal) instruction and a j (jump) instruction. The jump instruction means branch no matter what. bne reg1, reg2, label j label /* compute temp = avg(a, b) + c */ if ( a == b ) IF ( A .NE. B ) GOTO ELSE temp = a; TEMP = A else GOTO ENDIF temp = (a+b)/2; ELSE: TEMP = (A + B) / 2 temp += c; ENDIF: TEMP = TEMP + C bne $s0, $s1, ELSE # if ( a != b ) goto else move $t0, $s0 # temp = a j ENDIF # goto ENDIF ELSE: add $t0, $s0, $s1 # temp = a + b srl $t0, $t0, 1 # temp /= 2 (shift right logical) ENDIF: add $t0, $t0, $s2 # temp += c * NOTE: Labels must be unique, so we frequently see L1, L2, etc. I haven't found the naming rules for labels yet, so I don't know how long they may be. It's possible that ENDIF above is an illegal label name. Book uses LOOP, so presumably at least 4 letters are allowed. * There is no branch-on-less-than (or greater than, etc) in MIPS, but there is a set-on-less-than (slt). This instruction sets the destination register to 1 if the first source register is less than the second source register, and to 0 otherwise: slt destReg, srcReg1, srcReg2 Since it is easier to compare to 0 ($zero) than to 1, we have bne destReg, $zero # branch if srcReg1 < srcReg2 (destReg is 1) beq destReg, $zero # branch if ! srcReg1 < srcReg2 Assume that $s0 = a, $s1 = b, $s2 = c, $s3 = diff, $s7 = max /* compute diff = c - max(a, b) */ max = a; if ( a < b ) max = b; diff = c - max; move $s7, $s0 # max = a slt $t0, $s0, $s1 # t0 is 1 if a < b; 0 if a >= b beq $t0, $zero, ENDIF # if a >= b goto ENDIF move $s7, $s1 # max = b ENDIF: sub $s3, $s2, $s7 # diff = c - max * Loops: Use beq, bne, and j, just as for if statements. Assume that $s0 = i, $s1 = n, $s2 = A, $s3 = sum, A is an array of int sum = 0; SUM = 0 i = 0; I = 0 while ( i < n ) LOOP: IF ( I .GE. N ) GOTO END { sum += A[i]; SUM = SUM + A[I] i++; I = I + 1 } GOTO LOOP END: ... move $s3, $zero # sum = 0 move $s0, $zero # i = 0 LOOP: slt $t0, $s0, $s1 # t0 is 1 if i < n; 0 if i >= n beq $t0, $zero, END # goto END if i >= n add $t0, $s0, $s0 # t0 = i * 2 add $t0, $t0, $t0 # t0 = i * 4 add $t0, $t0, $s2 # t0 is address of A[i] lw $t1, 0 ($t0) # t1 = A[i] add $s3, $s3, $t1 # sum += A[i] addi $s0, $s0, 1 # i += 1 (or i++) j LOOP END: ...