Exercises based on the MIPS Assembly Instruction Set Reference. Each question includes the answer and explanation. Covers registers, instruction formats, arithmetic, logic, shifts, branches, jumps, load/store, functions, floating-point, pseudo instructions, and full programs.
Section A: Registers & Conventions (Q1–Q5)
Q1. Register Identification
What is stored in each of these registers by convention?
| Register | Your answer |
|---|---|
$zero |
? |
$ra |
? |
$sp |
? |
$v0 |
? |
$a0 |
? |
Answer
| Register | Purpose | |----------|---------| | `$zero` | Always holds the value 0 (hardwired) | | `$ra` | Return address — set by `jal` | | `$sp` | Stack pointer — points to top of stack | | `$v0` | Function return value / syscall service number | | `$a0` | First function argument / syscall argument |Q2. Caller-Saved vs Callee-Saved
Which of the following registers must a called function save and restore before modifying them?
$t0, $s0, $a0, $s3, $t5, $ra, $sp, $s7
Answer
**Callee-saved (must save/restore):** `$s0`, `$s3`, `$s7`, `$sp` **Caller-saved (no need to save in callee):** `$t0`, `$a0`, `$t5`, `$ra` Note: `$ra` is technically caller-saved — the callee saves it only if the callee itself calls another function (i.e., it's not a leaf function).Q3. HI and LO Registers
After executing the following code, what are the values of HI, LO, $t0, and $t1?
li $t2, 17
li $t3, 5
div $t2, $t3
mflo $t0
mfhi $t1
Answer
- `LO` = 3 (quotient: 17 ÷ 5 = 3) - `HI` = 2 (remainder: 17 mod 5 = 2) - `$t0` = 3 (from `mflo`) - `$t1` = 2 (from `mfhi`)Q4. Data Directives
Write the .data section to declare:
1. An integer array nums containing: 10, 20, 30, 40, 50
2. A null-terminated string msg containing: "Result: "
3. A buffer buf of 64 bytes
Answer
.data
nums: .word 10, 20, 30, 40, 50
msg: .asciiz "Result: "
buf: .space 64
Q5. Register Numbers
Convert these register names to their numeric equivalents (0–31):
| Name | Number |
|---|---|
$t0 |
? |
$s0 |
? |
$a2 |
? |
$ra |
? |
$sp |
? |
$t9 |
? |
Answer
| Name | Number | |------|--------| | `$t0` | 8 | | `$s0` | 16 | | `$a2` | 6 | | `$ra` | 31 | | `$sp` | 29 | | `$t9` | 25 |Section B: Instruction Formats & Encoding (Q6–Q10)
Q6. Identify the Format
For each instruction, state whether it is R-Type, I-Type, or J-Type:
| Instruction | Format? |
|---|---|
add $t0, $t1, $t2 |
? |
addi $t0, $t1, 100 |
? |
j LOOP |
? |
lw $t0, 0($sp) |
? |
sll $t1, $t0, 2 |
? |
jal FUNCTION |
? |
beq $t0, $t1, LABEL |
? |
jr $ra |
? |
Answer
| Instruction | Format | |-------------|--------| | `add $t0, $t1, $t2` | **R-Type** (op=0, funct=0x20) | | `addi $t0, $t1, 100` | **I-Type** (op=0x08) | | `j LOOP` | **J-Type** (op=0x02) | | `lw $t0, 0($sp)` | **I-Type** (op=0x23) | | `sll $t1, $t0, 2` | **R-Type** (op=0, funct=0x00) | | `jal FUNCTION` | **J-Type** (op=0x03) | | `beq $t0, $t1, LABEL` | **I-Type** (op=0x04) | | `jr $ra` | **R-Type** (op=0, funct=0x08) |Q7. Encode an R-Type Instruction
Encode add $t2, $t0, $t1 into 32-bit binary and hexadecimal.
Fields: op(6) | rs(5) | rt(5) | rd(5) | shamt(5) | funct(6)
Answer
| Field | Value | Binary | |-------|-------|--------| | op | 0 | `000000` | | rs ($t0) | 8 | `01000` | | rt ($t1) | 9 | `01001` | | rd ($t2) | 10 | `01010` | | shamt | 0 | `00000` | | funct (add) | 0x20 = 32 | `100000` | Binary: `000000 01000 01001 01010 00000 100000` Grouped into 4-bit nibbles: `0000 0001 0000 1001 0101 0000 0010 0000` **Hex: 0x01095020**Q8. Encode an I-Type Instruction
Encode lw $t0, 12($s0) into 32-bit binary and hexadecimal.
Fields: op(6) | rs(5) | rt(5) | immediate(16)
Answer
| Field | Value | Binary | |-------|-------|--------| | op (lw) | 0x23 = 35 | `100011` | | rs ($s0) | 16 | `10000` | | rt ($t0) | 8 | `01000` | | imm (12) | 12 | `0000000000001100` | Binary: `100011 10000 01000 0000000000001100` **Hex: 0x8E08000C**Q9. Decode a Machine Code
Decode the following machine code into a MIPS instruction: 0x01284822
Answer
Binary: `0000 0001 0010 1000 0100 1000 0010 0010` Fields (R-Type since op=000000): | Field | Binary | Decimal | |-------|--------|---------| | op | `000000` | 0 (R-Type) | | rs | `01001` | 9 = `$t1` | | rt | `01000` | 8 = `$t0` | | rd | `01001` | 9 = `$t1`... wait, let me recount | Let me split carefully: `000000 | 01001 | 00100 | 01001 | 00000 | 100010` | Field | Binary | Value | |-------|--------|-------| | op | `000000` | 0 | | rs | `01001` | 9 = `$t1` | | rt | `00100` | 4 = `$a0` | | rd | `01001` | 9 = `$t1` | | shamt | `00000` | 0 | | funct | `100010` | 0x22 = 34 = `sub` | **Instruction: `sub $t1, $t1, $a0`**Q10. Encoding Differences
Explain why andi uses zero-extension while addi uses sign-extension for their 16-bit immediates.
Answer
- **`addi` (sign-extension):** Used for arithmetic where the immediate can be negative (e.g., `addi $sp, $sp, -8`). Sign-extending preserves the sign: `0xFFF8` (−8) becomes `0xFFFFFFF8`. - **`andi` (zero-extension):** Used for bit masking where the immediate represents a bit pattern, not a number. Zero-extending preserves the mask: `0x00FF` becomes `0x000000FF`, not `0x000000FF` in both cases, but critically `0x8000` stays `0x00008000` rather than becoming `0xFFFF8000` (which would mask the wrong bits). Rule: **Arithmetic** immediates are sign-extended. **Logical** immediates (`andi`, `ori`, `xori`) are zero-extended.Section C: Arithmetic (Q11–Q18)
Q11. Basic Arithmetic
What is the value of $t2 after each sequence?
(a)
li $t0, 15
li $t1, 7
add $t2, $t0, $t1
(b)
li $t0, 100
addi $t2, $t0, -35
(c)
li $t0, 20
li $t1, 8
sub $t2, $t0, $t1
Answer
- **(a)** `$t2 = 15 + 7 = 22` - **(b)** `$t2 = 100 + (-35) = 65` - **(c)** `$t2 = 20 - 8 = 12`Q12. Multiplication
What are the values of $t0 and $t1 after:
li $s0, 100000
li $s1, 50000
mult $s0, $s1
mflo $t0
mfhi $t1
Answer
100000 × 50000 = 5,000,000,000 = 0x12A05F200 - `$t0 (LO)` = 0x2A05F200 (lower 32 bits) - `$t1 (HI)` = 0x00000001 (upper 32 bits) The product exceeds 32-bit range (> 2³¹ − 1 = 2,147,483,647), so `HI` is nonzero.Q13. Division
Write MIPS code to compute $s2 = $s0 / $s1 and $s3 = $s0 % $s1.
Answer
div $s0, $s1 # LO = quotient, HI = remainder
mflo $s2 # $s2 = $s0 / $s1
mfhi $s3 # $s3 = $s0 % $s1
Q14. add vs addu
What happens when you execute each of the following? Assume MARS default settings.
# (a)
li $t0, 0x7FFFFFFF # Max positive 32-bit signed integer
add $t1, $t0, $t0 # Will this cause an error?
# (b)
li $t0, 0x7FFFFFFF
addu $t1, $t0, $t0 # Will this cause an error?
Answer
- **(a) `add`:** Yes — **overflow exception**. 0x7FFFFFFF + 0x7FFFFFFF overflows the signed 32-bit range. `add` traps on overflow. - **(b) `addu`:** No error. `addu` silently wraps around. `$t1 = 0xFFFFFFFE` (which is −2 in signed, or 4,294,967,294 unsigned).Q15. Write C Expression in MIPS
Translate to MIPS: f = (g + h) - (i + j)
Use $s0=f, $s1=g, $s2=h, $s3=i, $s4=j. You may use $t0, $t1 as temporaries.
Answer
add $t0, $s1, $s2 # $t0 = g + h
add $t1, $s3, $s4 # $t1 = i + j
sub $s0, $t0, $t1 # f = (g + h) - (i + j)
Q16. Decrement Without subi
MIPS has no subi instruction. Write code to subtract 5 from $t0.
Answer
addi $t0, $t0, -5 # $t0 = $t0 - 5
Since there's no `subi`, use `addi` with a negative immediate.
Q17. Compute Average
Write MIPS code to compute the integer average of three values in $s0, $s1, $s2. Store the result in $s3.
Answer
add $s3, $s0, $s1 # $s3 = $s0 + $s1
add $s3, $s3, $s2 # $s3 = $s0 + $s1 + $s2
li $t0, 3
div $s3, $t0 # LO = sum / 3
mflo $s3 # $s3 = average (integer division)
Q18. Absolute Value
Write MIPS code to compute the absolute value of $s0 and store it in $s1 (without using pseudo-instructions).
Answer
bgez $s0, POSITIVE # if $s0 >= 0, skip negation
sub $s1, $zero, $s0 # $s1 = 0 - $s0 = -$s0
j DONE
POSITIVE:
move $s1, $s0 # $s1 = $s0 (already positive)
DONE:
Alternative without `move` (pure hardware instructions):
bgez $s0, POSITIVE
sub $s1, $zero, $s0
j DONE
POSITIVE:
addu $s1, $s0, $zero # $s1 = $s0 + 0
DONE:
Section D: Logical & Shift Operations (Q19–Q24)
Q19. Bit Masking
What is the value of $t2 after:
li $t0, 0xABCD1234
andi $t2, $t0, 0x00FF
Answer
`$t2 = 0x00000034` `andi` keeps only the lower 8 bits (0x00FF mask), zeroing everything else.Q20. Set Specific Bits
Starting with $t0 = 0xFFFF0000, use a single instruction to set the lower 4 bits to 1.
Answer
ori $t0, $t0, 0x000F # $t0 = 0xFFFF000F
`ori` sets bits to 1 wherever the mask has 1s, without affecting other bits.
Q21. Toggle Bits
What is $t1 after:
li $t0, 0xFF00FF00
xori $t1, $t0, 0xFFFF
Answer
`xori` zero-extends `0xFFFF` to `0x0000FFFF`. 0xFF00FF00 = 1111 1111 0000 0000 1111 1111 0000 0000
^ 0x0000FFFF = 0000 0000 0000 0000 1111 1111 1111 1111
= 0xFF0000FF = 1111 1111 0000 0000 0000 0000 1111 1111
`$t1 = 0xFF0000FF`
Q22. Bitwise NOT
MIPS has no NOT instruction. Write a single instruction to compute bitwise NOT of $t0, storing the result in $t1.
Answer
nor $t1, $t0, $zero # $t1 = NOT($t0 OR 0) = NOT($t0)
Since `$zero = 0`, `NOR(x, 0) = NOT(x OR 0) = NOT(x)`.
Q23. Shift as Multiplication/Division
What are the values of $t1 and $t2?
li $t0, 5
sll $t1, $t0, 3 # (a)
li $t0, 200
srl $t2, $t0, 2 # (b)
Answer
- **(a)** `$t1 = 5 << 3 = 5 × 8 = 40` - **(b)** `$t2 = 200 >> 2 = 200 ÷ 4 = 50` Shifting left by n = multiply by 2ⁿ. Shifting right by n = divide by 2ⁿ (unsigned).Q24. SRA vs SRL
What is $t1 after each?
li $t0, -16 # $t0 = 0xFFFFFFF0
# (a)
srl $t1, $t0, 2
# (b)
sra $t1, $t0, 2
Answer
- **(a) SRL:** `$t1 = 0x3FFFFFFC = 1,073,741,820` - Fills with 0s from the left. Treats the value as unsigned — gives a large positive number. - **(b) SRA:** `$t1 = 0xFFFFFFFC = -4` - Fills with the sign bit (1) from the left. Preserves the sign — gives −16 ÷ 4 = −4. **Rule:** Use `sra` for signed division by powers of 2. Use `srl` for unsigned or bit extraction.Section E: Comparison & Branching (Q25–Q32)
Q25. SLT — Set on Less Than
What is $t2 after each?
# (a)
li $t0, 5
li $t1, 10
slt $t2, $t0, $t1
# (b)
li $t0, 10
li $t1, 5
slt $t2, $t0, $t1
# (c)
li $t0, 7
li $t1, 7
slt $t2, $t0, $t1
Answer
- **(a)** `$t2 = 1` (5 < 10 is true) - **(b)** `$t2 = 0` (10 < 5 is false) - **(c)** `$t2 = 0` (7 < 7 is false — not strictly less than)Q26. SLT vs SLTU
What is $t2 after each? Assume $t0 = 0xFFFFFFFF, $t1 = 1.
# (a)
slt $t2, $t0, $t1
# (b)
sltu $t2, $t0, $t1
Answer
- **(a) slt:** `$t2 = 1`. As signed: 0xFFFFFFFF = −1. Since −1 < 1, result is 1. - **(b) sltu:** `$t2 = 0`. As unsigned: 0xFFFFFFFF = 4,294,967,295. Since 4B > 1, result is 0.Q27. Translate if-else
Translate to MIPS:
if (a == b)
c = a + b;
else
c = a - b;
Use $s0=a, $s1=b, $s2=c.
Answer
bne $s0, $s1, ELSE # if a != b, go to ELSE
add $s2, $s0, $s1 # c = a + b (the "if" body)
j END_IF
ELSE:
sub $s2, $s0, $s1 # c = a - b (the "else" body)
END_IF:
Q28. Translate while Loop
Translate to MIPS:
int sum = 0;
int i = 1;
while (i <= 100) {
sum += i;
i++;
}
Answer
li $s0, 0 # sum = 0
li $s1, 1 # i = 1
li $t0, 100 # limit = 100
WHILE:
bgt $s1, $t0, DONE # if i > 100, exit (pseudo-instruction)
add $s0, $s0, $s1 # sum += i
addi $s1, $s1, 1 # i++
j WHILE
DONE:
# $s0 = 5050
Without pseudo-instruction `bgt`:
WHILE:
slt $t1, $t0, $s1 # $t1 = (100 < i) ? 1 : 0
bne $t1, $zero, DONE # if 100 < i, exit
add $s0, $s0, $s1
addi $s1, $s1, 1
j WHILE
DONE:
Q29. Translate for Loop
Translate to MIPS:
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
// result = n!
Use $s0=result, $s1=i, $a0=n.
Answer
li $s0, 1 # result = 1
li $s1, 1 # i = 1
FOR_LOOP:
bgt $s1, $a0, FOR_DONE # if i > n, exit
mult $s0, $s1 # result × i
mflo $s0 # result = lower 32 bits
addi $s1, $s1, 1 # i++
j FOR_LOOP
FOR_DONE:
Q30. Compound Condition
Translate to MIPS:
if (a > 0 && b > 0)
c = 1;
else
c = 0;
Use $s0=a, $s1=b, $s2=c.
Answer
blez $s0, SET_ZERO # if a <= 0, skip to else
blez $s1, SET_ZERO # if b <= 0, skip to else
li $s2, 1 # c = 1 (both > 0)
j END
SET_ZERO:
li $s2, 0 # c = 0
END:
Short-circuit evaluation: if the first condition fails, skip immediately.
Q31. Branch Offset
If beq $t0, $t1, TARGET is at address 0x00400020 and TARGET is at address 0x00400030, what is the 16-bit offset field in the instruction?
Answer
Offset = (TARGET − (PC+4)) ÷ 4 - PC of `beq` = 0x00400020 - PC+4 = 0x00400024 - TARGET = 0x00400030 - Offset = (0x00400030 − 0x00400024) ÷ 4 = 0x0C ÷ 4 = **3** The 16-bit offset field = **0x0003**Q32. Pseudo-Branch Expansion
The pseudo-instruction blt $t0, $t1, LESS is not a real MIPS instruction. What does the assembler expand it into?
Answer
slt $at, $t0, $t1 # $at = ($t0 < $t1) ? 1 : 0
bne $at, $zero, LESS # if $at == 1, branch to LESS
The assembler uses `$at` (`$1`) as a temporary — this is why `$at` is reserved for the assembler.
Section F: Load, Store & Memory (Q33–Q38)
Q33. Array Access
Given:
.data
A: .word 10, 20, 30, 40, 50
Write MIPS code to load A[3] into $t0.
Answer
la $t1, A # $t1 = base address of A
lw $t0, 12($t1) # $t0 = A[3] = 40 (offset = 3 × 4 = 12)
Or using variable index in `$s0`:
la $t1, A
sll $t2, $s0, 2 # $t2 = index × 4
add $t1, $t1, $t2
lw $t0, 0($t1) # $t0 = A[$s0]
Q34. LB vs LBU
Memory at address $s0 contains the byte 0x80 (128 decimal). What is $t0 after each?
# (a)
lb $t0, 0($s0)
# (b)
lbu $t0, 0($s0)
Answer
- **(a) lb (sign-extend):** `$t0 = 0xFFFFFF80 = -128` - Bit 7 of 0x80 is 1, so sign-extension fills with 1s. - **(b) lbu (zero-extend):** `$t0 = 0x00000080 = 128` - Zero-extension fills with 0s. **Rule:** Use `lbu` for unsigned bytes (characters, pixel values). Use `lb` for signed bytes.Q35. LUI + ORI
What is $t0 after:
lui $t0, 0xABCD
ori $t0, $t0, 0x1234
Answer
1. `lui $t0, 0xABCD` → `$t0 = 0xABCD0000` 2. `ori $t0, $t0, 0x1234` → `$t0 = 0xABCD0000 | 0x00001234 = 0xABCD1234` This is how the assembler implements `li $t0, 0xABCD1234`.Q36. Store and Load Back
What is $t1 after this code?
li $t0, 0x12345678
sw $t0, 0($sp)
lhu $t1, 0($sp)
Answer
`sw` stores all 4 bytes. `lhu` loads only 2 bytes (a halfword) and zero-extends. MIPS is **big-endian** by default in MARS/SPIM, but MARS actually uses the host machine's endianness (usually little-endian on x86). - **Little-endian (MARS on x86):** Lower address has LSB. `lhu` at offset 0 loads `0x5678`. → `$t1 = 0x00005678` - **Big-endian:** Lower address has MSB. `lhu` at offset 0 loads `0x1234`. → `$t1 = 0x00001234` In MARS simulator: **`$t1 = 0x00005678`** (little-endian).Q37. Stack Operations
Write MIPS code to save $s0, $s1, and $ra to the stack, then restore them (in correct order).
Answer
# Save (prologue)
addi $sp, $sp, -12 # Allocate 12 bytes (3 words)
sw $ra, 8($sp) # Save return address
sw $s0, 4($sp) # Save $s0
sw $s1, 0($sp) # Save $s1
# ... function body ...
# Restore (epilogue)
lw $s1, 0($sp) # Restore $s1
lw $s0, 4($sp) # Restore $s0
lw $ra, 8($sp) # Restore return address
addi $sp, $sp, 12 # Deallocate stack frame
jr $ra # Return
Q38. Memory Alignment
Which of these will cause an alignment exception?
# (a)
lw $t0, 0($s0) # $s0 = 0x10000004
# (b)
lw $t0, 0($s0) # $s0 = 0x10000003
# (c)
lh $t0, 0($s0) # $s0 = 0x10000005
# (d)
lb $t0, 0($s0) # $s0 = 0x10000003
Answer
- **(a)** No exception — `0x10000004` is word-aligned (divisible by 4). - **(b)** **Exception** — `0x10000003` is NOT word-aligned. `lw` requires 4-byte alignment. - **(c)** **Exception** — `0x10000005` is NOT halfword-aligned. `lh` requires 2-byte alignment. - **(d)** No exception — `lb` has no alignment requirement (1-byte access). **Rules:** `lw`/`sw` → address must be divisible by 4. `lh`/`sh` → divisible by 2. `lb`/`sb` → any address.Section G: Functions & Calling Convention (Q39–Q43)
Q39. Leaf Function
Write a leaf function int max(int a, int b) that returns the larger of two integers.
Arguments in $a0 and $a1. Return value in $v0.
Answer
# int max(int a, int b)
max:
slt $t0, $a0, $a1 # $t0 = (a < b) ? 1 : 0
bne $t0, $zero, B_IS_BIGGER
move $v0, $a0 # return a
jr $ra
B_IS_BIGGER:
move $v0, $a1 # return b
jr $ra
No stack frame needed — this is a leaf function that doesn't call other functions or use `$s` registers.
Q40. Non-Leaf Function
Write a function int double_max(int a, int b) that calls max(a, b) from Q39 and returns the result multiplied by 2.
Answer
double_max:
addi $sp, $sp, -4 # Save $ra (non-leaf: calls max)
sw $ra, 0($sp)
jal max # $v0 = max(a, b)
# $a0, $a1 already set by caller
add $v0, $v0, $v0 # $v0 = result × 2 (or: sll $v0, $v0, 1)
lw $ra, 0($sp)
addi $sp, $sp, 4
jr $ra
Q41. Recursive Function
Write a recursive MIPS function for:
int sum_to(int n) {
if (n <= 0) return 0;
return n + sum_to(n - 1);
}
Answer
# int sum_to(int n) — $a0 = n, return in $v0
sum_to:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $a0, 0($sp) # Save n
blez $a0, BASE_CASE # if n <= 0, return 0
addi $a0, $a0, -1 # n - 1
jal sum_to # $v0 = sum_to(n - 1)
lw $a0, 0($sp) # Restore original n
add $v0, $a0, $v0 # return n + sum_to(n-1)
lw $ra, 4($sp)
addi $sp, $sp, 8
jr $ra
BASE_CASE:
li $v0, 0 # return 0
lw $ra, 4($sp)
addi $sp, $sp, 8
jr $ra
Q42. Stack Frame Bug
This function has a bug. Find and fix it.
buggy:
addi $sp, $sp, -8
sw $ra, 4($sp)
sw $s0, 0($sp)
move $s0, $a0
jal helper
add $v0, $v0, $s0
lw $ra, 4($sp)
addi $sp, $sp, 8 # Missing: lw $s0 not restored!
jr $ra
Answer
**Bug:** `$s0` is saved to the stack but **never restored**. This violates the callee-saved convention — the caller's `$s0` value is lost. **Fix:** Add `lw $s0, 0($sp)` before deallocating the stack: add $v0, $v0, $s0
lw $s0, 0($sp) # ← ADD THIS LINE
lw $ra, 4($sp)
addi $sp, $sp, 8
jr $ra
Q43. Calling Convention Violation
What is wrong with this code?
main:
li $s0, 42
li $a0, 10
jal some_function
# Expect $s0 to still be 42 here
move $a0, $s0
li $v0, 1
syscall # Should print 42
some_function:
move $s0, $a0 # $s0 = 10 (OVERWRITES caller's value!)
# ... do something ...
jr $ra
Answer
**Problem:** `some_function` modifies `$s0` without saving and restoring it. `$s0` is **callee-saved**, so `some_function` must preserve it. **Fix:**some_function:
addi $sp, $sp, -4
sw $s0, 0($sp) # Save $s0
move $s0, $a0
# ... do something ...
lw $s0, 0($sp) # Restore $s0
addi $sp, $sp, 4
jr $ra
Or better: use `$t0` instead of `$s0` since it's caller-saved and doesn't need saving.
Section H: Floating-Point (Q44–Q45)
Q44. Float Arithmetic
Write MIPS code to compute area = 3.14159 × radius × radius, where radius is stored in memory.
Answer
.data
pi: .float 3.14159
radius: .float 5.0
area: .float 0.0
.text
main:
l.s $f0, pi # $f0 = 3.14159
l.s $f2, radius # $f2 = 5.0
mul.s $f4, $f2, $f2 # $f4 = radius²
mul.s $f6, $f0, $f4 # $f6 = pi × radius²
s.s $f6, area # Store result
# Print result
mov.s $f12, $f6 # Argument for syscall 2
li $v0, 2 # Print float
syscall
li $v0, 10
syscall
Q45. Float Comparison
Write MIPS code for:
if (x > y)
print "X is larger"
else
print "Y is larger or equal"
Assume x is in $f0 and y is in $f2.
Answer
.data
msg_x: .asciiz "X is larger\n"
msg_y: .asciiz "Y is larger or equal\n"
.text
c.le.s $f0, $f2 # Set flag if x <= y
bc1t Y_BIGGER # If flag true (x <= y), branch
li $v0, 4
la $a0, msg_x
syscall
j FP_DONE
Y_BIGGER:
li $v0, 4
la $a0, msg_y
syscall
FP_DONE:
Note: There's no `c.gt.s`. To check `x > y`, we check `NOT(x <= y)` using `c.le.s` + `bc1f`, or equivalently `c.le.s` + `bc1t` to branch when false.
Section I: System Calls & I/O (Q46–Q47)
Q46. Read and Sum
Write a complete MIPS program that: 1. Prompts "Enter two integers: " 2. Reads two integers 3. Prints "Sum = " followed by the sum
Answer
.data
prompt: .asciiz "Enter two integers:\n"
result: .asciiz "Sum = "
.text
.globl main
main:
li $v0, 4
la $a0, prompt
syscall # Print prompt
li $v0, 5
syscall # Read first integer
move $t0, $v0
li $v0, 5
syscall # Read second integer
move $t1, $v0
add $t2, $t0, $t1 # Sum
li $v0, 4
la $a0, result
syscall # Print "Sum = "
li $v0, 1
move $a0, $t2
syscall # Print sum
li $v0, 10
syscall # Exit
Q47. Print Array
Write a MIPS program to print all elements of an array, one per line.
.data
arr: .word 5, 12, 8, 3, 17
Answer
.data
arr: .word 5, 12, 8, 3, 17
size: .word 5
newline:.asciiz "\n"
.text
.globl main
main:
la $s0, arr # $s0 = base address
lw $s1, size # $s1 = size
li $s2, 0 # $s2 = index i
PRINT_LOOP:
beq $s2, $s1, PRINT_DONE
sll $t0, $s2, 2 # $t0 = i × 4
add $t0, $s0, $t0 # $t0 = &arr[i]
lw $a0, 0($t0) # $a0 = arr[i]
li $v0, 1
syscall # Print integer
li $v0, 4
la $a0, newline
syscall # Print newline
addi $s2, $s2, 1 # i++
j PRINT_LOOP
PRINT_DONE:
li $v0, 10
syscall
Section J: Complete Programs (Q48–Q50)
Q48. Find Maximum in Array
Write a complete MIPS program that finds and prints the maximum value in an array.
.data
arr: .word 34, 7, 23, 89, 12, 56, 45
Answer
.data
arr: .word 34, 7, 23, 89, 12, 56, 45
size: .word 7
msg: .asciiz "Maximum value: "
.text
.globl main
main:
la $s0, arr
lw $s1, size # $s1 = 7
lw $s2, 0($s0) # $s2 = max = arr[0]
li $s3, 1 # $s3 = i = 1
FIND_MAX:
beq $s3, $s1, FOUND # if i == size, done
sll $t0, $s3, 2
add $t0, $s0, $t0
lw $t1, 0($t0) # $t1 = arr[i]
slt $t2, $s2, $t1 # if max < arr[i]
beq $t2, $zero, SKIP_UPDATE
move $s2, $t1 # max = arr[i]
SKIP_UPDATE:
addi $s3, $s3, 1
j FIND_MAX
FOUND:
li $v0, 4
la $a0, msg
syscall
li $v0, 1
move $a0, $s2
syscall # Print 89
li $v0, 10
syscall
Q49. String Reverse
Write a MIPS program that reverses a string in-place and prints it.
Answer
.data
str: .asciiz "Hello MIPS"
msg: .asciiz "Reversed: "
.text
.globl main
main:
# First, find string length
la $s0, str # $s0 = start pointer
move $t0, $s0
FIND_END:
lbu $t1, 0($t0)
beq $t1, $zero, FOUND_END
addi $t0, $t0, 1
j FIND_END
FOUND_END:
addi $t0, $t0, -1 # $t0 = pointer to last char
move $s1, $t0 # $s1 = end pointer
move $t2, $s0 # $t2 = left pointer
REVERSE:
bge $t2, $s1, REVERSE_DONE # if left >= right, done
lbu $t3, 0($t2) # temp1 = *left
lbu $t4, 0($s1) # temp2 = *right
sb $t4, 0($t2) # *left = temp2
sb $t3, 0($s1) # *right = temp1
addi $t2, $t2, 1 # left++
addi $s1, $s1, -1 # right--
j REVERSE
REVERSE_DONE:
li $v0, 4
la $a0, msg
syscall
li $v0, 4
la $a0, str
syscall # Prints "SPIM olleH"
li $v0, 10
syscall
Q50. GCD (Euclidean Algorithm)
Write a complete MIPS program that reads two positive integers and prints their GCD using the Euclidean algorithm.
// Reference C code:
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
Answer
.data
prompt_a: .asciiz "Enter first integer: "
prompt_b: .asciiz "Enter second integer: "
result: .asciiz "GCD = "
.text
.globl main
main:
# Read a
li $v0, 4
la $a0, prompt_a
syscall
li $v0, 5
syscall
move $s0, $v0 # $s0 = a
# Read b
li $v0, 4
la $a0, prompt_b
syscall
li $v0, 5
syscall
move $s1, $v0 # $s1 = b
# Call gcd
move $a0, $s0
move $a1, $s1
jal gcd
# Print result
move $s0, $v0 # Save result
li $v0, 4
la $a0, result
syscall
li $v0, 1
move $a0, $s0
syscall
li $v0, 10
syscall
# int gcd(int a, int b)
# $a0 = a, $a1 = b, returns $v0
gcd:
GCD_LOOP:
beq $a1, $zero, GCD_DONE # while (b != 0)
div $a0, $a1 # LO = a/b, HI = a%b
move $a0, $a1 # a = temp (old b)
mfhi $a1 # b = a % b
j GCD_LOOP
GCD_DONE:
move $v0, $a0 # return a
jr $ra
**Example run:**
Enter first integer: 48
Enter second integer: 18
GCD = 6
Trace: gcd(48, 18) → gcd(18, 12) → gcd(12, 6) → gcd(6, 0) → return 6
Summary: Topics Covered
| Section | Questions | Topics |
|---|---|---|
| A | Q1–Q5 | Registers, conventions, HI/LO, data directives |
| B | Q6–Q10 | Instruction formats, R/I/J encoding, decoding |
| C | Q11–Q18 | Arithmetic: add, sub, mult, div, addi, overflow, abs |
| D | Q19–Q24 | Logical: and, or, xor, nor, bit masks; Shifts: sll, srl, sra |
| E | Q25–Q32 | slt/sltu, beq/bne, if-else, while, for, compound conditions, branch offset, pseudo expansion |
| F | Q33–Q38 | lw, lb, lbu, lui+ori, arrays, stack, alignment |
| G | Q39–Q43 | Leaf/non-leaf functions, recursion, stack frames, calling convention bugs |
| H | Q44–Q45 | Floating-point arithmetic and comparison |
| I | Q46–Q47 | System calls, I/O, print arrays |
| J | Q48–Q50 | Complete programs: find max, reverse string, GCD |