Introduction to Computer Organization (CCIT4026)
Lab 04: Decision Making and Loops (SID Validation, Even/Odd Count)
This document provides answers to all lab tasks and very detailed explanations for every part of the solution.
1. Understanding the Lab
1.1 What You Must Do
- Array A: Store 8 integers (words), one per digit of your Student ID (SID). So A has 8 elements: A[0] … A[7].
- Prompt: Ask the user to enter their SID as an ASCII string (e.g.
"20210342"). - Validation with loops:
- Use a for loop over index i = 0..7.
- For each character, convert it from ASCII to a decimal digit (e.g.
'0'→ 0,'9'→ 9). - Use a while-style check: the digit must be in the range 0 ≤ A[i] ≤ 9. If any character is invalid (not'0'–'9'), print an invalid message and ask for the SID again (go back to Step 1). Otherwise store the digit in A[i]. - Second for loop:
- Print"Your input SID is ["then each digit A[0]…A[7], then"]".
- Count how many digits are even and how many are odd.
- Print those two counts in the format shown in the sample.
1.2 Example
If the user enters the SID string "20210342":
- Array A: A = [2, 0, 2, 1, 0, 3, 4, 2].
- Even digits: 2, 0, 2, 0, 4, 2 → 6.
- Odd digits: 1, 3 → 2.
So output should include: even count = 6, odd count = 2.
1.3 Invalid Input Examples (Required in Report)
The lab asks you to show at least two invalid input cases, for example:
- "2!210342" — character
'!'is not between'0'and'9'. - "202a0342" — character
'a'is not a digit.
In both cases the program should print an invalid message and prompt again for the SID.
2. Key Concepts (Detailed)
2.1 ASCII and Decimal Conversion
- Characters
'0'to'9'have ASCII codes 48 to 57. - To get the decimal value of a digit character:
decimal_value = ASCII_code − 48 (or subtract0x30). - So:
'0'(48) → 0,'1'(49) → 1, …,'9'(57) → 9.
In MIPS: After loading the byte (e.g. with lb), subtract 48: addi $t, $t, -48.
2.2 Valid Range Check
- A valid digit satisfies 0 ≤ value ≤ 9.
- Invalid if:
- value < 0 (e.g. character like
'!'= 33 → 33−48 = −15), or - value > 9 (e.g.
'a'= 97 → 97−48 = 49).
MIPS has no single “branch if less than” instruction; we use:
- value < 0:
slt $t, value, $zerothenbne $t, $zero, invalid. - value > 9:
slti $t, value, 10→ 1 if value < 10. So if result is 0, value ≥ 10 → invalid:beq $t, $zero, invalid.
2.3 Even vs Odd
- Even numbers have the lowest bit 0; odd have the lowest bit 1.
- andi digit, digit, 1 gives 0 for even and 1 for odd.
- If result is 0 → increment even count; else → increment odd count.
2.4 Reading a String in MARS (Syscall 8)
- Syscall 8 = read string.
- $a0 = address of buffer where the string will be stored.
- $a1 = maximum number of characters to read (buffer size). MARS stores a null terminator and may include the newline, so for 8 digits use at least 10 (e.g. 8 digits + newline + null).
After the syscall, the buffer holds the string byte by byte. To get the character at index i, load the byte at address (buffer + i) with lb.
2.5 Array Layout in Memory
- A is an array of words (4 bytes each). So A[i] is at address A + i×4.
- Address of A[i]:
labase, thenadd base, base, i*4, or usesllto compute i×4 then add to base.
3. Pseudo-Code (Lab’s Steps) Mapped to Logic
| Lab step | Meaning |
|---|---|
| Initialization | Reserve a buffer for the SID string and 8 words for array A. |
| Step 1.1 | Print prompt, read SID string into buffer. |
| Step 1.2 | For loop: i = 0 to 7 (or 0 to “number of digits” − 1; here 8 digits). |
| Step 1.3–1.4 | Inside the loop: load character at position i, convert ASCII to decimal. |
| Step 1.5 | Check if 0 ≤ value ≤ 9. |
| Step 1.6 | If invalid: print invalid message, then jump back to Step 1 (re-read SID). |
| Step 1.7 | If valid: store value in A[i], then continue the for loop. |
| Step 2.1 | Set evencount = 0, oddcount = 0. |
| Step 2.2 | Print "Your input SID is [". |
| Step 2.3–2.5 | For i = 0..7: read A[i], print the digit. |
| Step 2.6–2.7 | If A[i] is even, evencount++; else oddcount++. |
| Step 2.8–2.9 | End of loop, then print "]". |
| Step 3.1–3.3 | Print even count and odd count, print author message, exit. |
4. Complete MIPS Solution
The program below follows the lab’s pseudo-code and uses only instructions from the course (syscalls 1, 4, 8, 10; add, addi, sub, andi, lb, sw, lw, sll, slt, slti, beq, bne, j, li, la).
# ICO Lab 04 - Decision Making and Loops (SID validation, even/odd count)
# Array A has 8 elements (one per SID digit). Valid digits: 0-9.
.data
prompt: .asciiz "Please enter your Student ID (8 digits): "
invalid_msg: .asciiz "Invalid input. Each character must be a digit 0-9.\n"
sid_open: .asciiz "Your input SID is ["
sid_close: .asciiz "]\n"
even_str: .asciiz "even count = "
odd_str: .asciiz "odd count = "
newline: .asciiz "\n"
author: .asciiz "[Your Name, Class, Student ID]\n"
buffer: .space 12 # SID string: 8 digits + newline + null; 12 safe
A: .word 0, 0, 0, 0, 0, 0, 0, 0 # 8 words for digits
evencount: .word 0
oddcount: .word 0
.text
.globl main
main:
# ========== Initialization ==========
# Reserve an ASCIIZ string to use the SID input and 8 words in data segment to store the array A.
# (Done in .data: buffer, A)
# ========== Step 1 ==========
step1_start:
# Step 1.1 Display the SID input string prompt, read in the SID input and store to a ASCIIZ string buffer.
li $v0, 4
la $a0, prompt
syscall
li $v0, 8
la $a0, buffer
li $a1, 12
syscall
# Step 1.2 Setup a "for" loop such as: "for i in (0, No of digits in your SID, 1):".
li $s0, 0 # i = 0
step1_for:
# Step 1.3 Inside the "for" loop body, setup a while loop.
# Step 1.4 Inside the while loop body, load one character from the input SID string to a register and convert the ASCII character in the register to decimal equivalent value.
la $t0, buffer
add $t0, $t0, $s0 # address of buffer[i]
lb $t1, 0($t0) # $t1 = character (byte) '2'
addi $t2, $t1, -48 # $t2 = decimal value (ASCII - 48) '2' -> 2
# Step 1.5 Check the decimal equivalent valid whether it is within the valid range, i.e., 0<=input_value<=9
slt $t3, $t2, $zero # $t3 = 1 if value < 0
bne $t3, $zero, step1_invalid
slti $t3, $t2, 10 # $t3 = 1 if value < 10 (i.e. value <= 9)
beq $t3, $zero, step1_invalid
# Step 1.7 Otherwise store the input value to the array element A[i] and continue the "for" loop until end of loop.
la $t4, A
sll $t5, $s0, 2 # i * 4
add $t4, $t4, $t5 # address of A[i]
sw $t2, 0($t4) # A[i] = decimal value
addi $s0, $s0, 1 # i++
li $t6, 8
bne $s0, $t6, step1_for # if i != 8, continue for loop
j step1_done
step1_invalid:
# Step 1.6 If the input value is out of range, display the invalid message, exit the while loop and go back to Step 1.
li $v0, 4
la $a0, invalid_msg
syscall
j step1_start
step1_done:
# ========== Step 2 ==========
# Step 2.1 Use two registers to associate with two counters, evencount and oddcount and clear them to zero.
li $s1, 0 # evencount = 0
li $s2, 0 # oddcount = 0
# Step 2.2 Echo the entered SID by display the message "Your input SID is ["
li $v0, 4
la $a0, sid_open
syscall
# Step 2.3 Setup another "for" loop such as: "for i in (0, No of digits in your SID, 1):".
li $s0, 0 # i = 0
step2_for:
# Step 2.4 Inside the "for" loop body, read out the array elements A[i].
la $t0, A
sll $t1, $s0, 2 # * 4
add $t0, $t0, $t1
lw $t2, 0($t0) # $t2 = A[i]
# Step 2.5 Display the digit value.
li $v0, 1
move $a0, $t2
syscall
# Step 2.6 If the element A[i] is an even number, increment the "evencount" by 1.
# Step 2.7 Otherwise increment the "oddcount" by 1
andi $t3, $t2, 1 # $t3 = 0 if even, 1 if odd
bne $t3, $zero, step2_odd
addi $s1, $s1, 1 # evencount++
j step2_next
step2_odd:
addi $s2, $s2, 1 # oddcount++
step2_next:
# Step 2.8 Continue the "for" loop in Step 2.4 until end of loop.
addi $s0, $s0, 1
li $t4, 8
bne $s0, $t4, step2_for
# Step 2.9 Display the message "]".
li $v0, 4
la $a0, sid_close
syscall
# Store counts to memory for later use (optional; we can print from $s1, $s2)
sw $s1, evencount
sw $s2, oddcount
# ========== Step 3 ==========
# Step 3.1 Print the two count values stored in "evencount" and "oddcount" as shown in the sample output.
li $v0, 4
la $a0, even_str
syscall
li $v0, 1
move $a0, $s1
syscall
li $v0, 4
la $a0, newline
syscall
li $v0, 4
la $a0, odd_str
syscall
li $v0, 1
move $a0, $s2
syscall
li $v0, 4
la $a0, newline
syscall
# Step 3.2 Display your author message.
li $v0, 4
la $a0, author
syscall
# Step 3.3 Exit program.
li $v0, 10
syscall
Important: Replace [Your Name, Class, Student ID] in the author string with your own details. The prompt string can be adjusted to match exactly what the lab asks (e.g. “Please enter your SID in ASCII string” if required).
5. Detailed Explanation of Every Part
5.1 Data Section
| Label | Purpose |
|---|---|
prompt |
Message asking user to enter SID (e.g. “Please enter your Student ID (8 digits): ”). |
invalid_msg |
Shown when any character is not '0'–'9'. After this, execution goes back to Step 1. |
sid_open |
Literal "Your input SID is [" before echoing digits. |
sid_close |
Literal "]" plus newline after the digits. |
even_str / odd_str |
Labels for “even count = ” and “odd count = ”. |
buffer |
Space for the SID string. .space 12 gives 12 bytes: 8 digits + newline + null. |
A |
Eight words for the digits A[0]…A[7]. |
evencount / oddcount |
Words holding the two counts (optional; we also keep them in $s1, $s2). |
5.2 Step 1.1 — Prompt and Read SID
- Print prompt:
li $v0, 4,la $a0, prompt,syscall(syscall 4 = print string). - Read string:
li $v0, 8,la $a0, buffer,li $a1, 12,syscall.
MARS reads at most 11 characters (plus null). So “20210342” plus Enter fits; the buffer will contain the 8 digits and typically a newline and null.
5.3 Step 1.2–1.7 — For Loop and Validation
- Loop variable:
$s0= i (0 to 7). Using$s0keeps it across the loop; you could use a temporary if you prefer. - Character address:
buffer + iis computed asla $t0, bufferthenadd $t0, $t0, $s0. - Load byte:
lb $t1, 0($t0)loads the character at position i. lb sign-extends; for digits 48–57 the sign extension does not affect the next step. - ASCII to decimal:
addi $t2, $t1, -48gives the digit value 0–9 for valid input. - Check value < 0:
slt $t3, $t2, $zerosets $t3=1 if $t2 < 0.bne $t3, $zero, step1_invalidjumps to invalid if so. - Check value > 9:
slti $t3, $t2, 10sets $t3=1 if $t2 < 10. So $t3=0 means $t2 ≥ 10.beq $t3, $zero, step1_invalidjumps to invalid. - Store in A[i]: Address of A[i] is
A + i*4.sll $t5, $s0, 2computes i×4;add $t4, $t4, $t5gives the address;sw $t2, 0($t4)stores the digit. - Loop end: Increment i with
addi $s0, $s0, 1. If$s0 != 8, branch back tostep1_for; otherwise jump tostep1_done.
So the “while” in the lab is implemented by: for each i, do one check; if invalid, show message and jump back to step1_start (re-read entire SID); if valid, store and continue the for loop.
5.4 Step 1.6 — Invalid Path
- Print
invalid_msgwith syscall 4, thenj step1_start. That restarts from the prompt and reads a new SID string.
5.5 Step 2.1 — Counters
$s1= evencount,$s2= oddcount; both set to 0 withli $s1, 0andli $s2, 0.
5.6 Step 2.2 and 2.9 — Brackets Around SID
- Print
sid_open(“Your input SID is [”) before the loop. - After the loop, print
sid_close(“]\n”).
5.7 Step 2.3–2.8 — Second For Loop (Echo and Even/Odd)
- Again i in
$s0from 0 to 7. - Load A[i]:
la $t0, A,sll $t1, $s0, 2,add $t0, $t0, $t1,lw $t2, 0($t0). - Print digit: syscall 1 with
move $a0, $t2. - Even/odd:
andi $t3, $t2, 1. If $t3 == 0, digit is even →addi $s1, $s1, 1. If $t3 == 1, digit is odd →addi $s2, $s2, 1. - Loop until i reaches 8, then print
"]".
5.8 Step 3 — Counts, Author, Exit
- Print “even count = ” (syscall 4), then the integer in $s1 (syscall 1), then newline.
- Same for “odd count = ” and $s2.
- Print author string (syscall 4).
- Exit with
li $v0, 10,syscall.
6. Sample Run (Conceptual)
Valid input
- Input:
20210342 - A = [2,0,2,1,0,3,4,2].
- Output includes:
Your input SID is [20210342],even count = 6,odd count = 2.
Invalid inputs (for report)
- Input:
2!210342→ invalid character!→ program prints invalid message and asks again. - Input:
202a0342→ invalid charactera→ same behavior.
7. Submission Checklist
- [ ] Use only instructions from the course; no uncited extra instructions.
- [ ] Each instruction has a suitable comment; pseudo-code steps appear as comments.
- [ ] Replace the author string with your name, class, student ID.
- [ ] Run and single-step in MARS to verify valid and invalid cases.
- [ ] Lab report (PDF) includes: source listing, assembled machine code (Text Segment), Run I/O with at least two invalid cases and one valid case, and program termination message.
- [ ] Submit both the PDF and the
.asmfile with the required naming (e.g.ICO_Lab4_CL01_YourName_StudentID.asmand.pdf). - [ ] Manual calculations: fill SID and A=[…], even count, odd count as in the sample.
8. Summary Table: Instructions and Syscalls Used
| Task | MIPS usage |
|---|---|
| Print string | li $v0, 4, la $a0, label, syscall |
| Read string | li $v0, 8, la $a0, buffer, li $a1, 12, syscall |
| Load byte | lb reg, 0(addr) (character from buffer) |
| Arithmetic | add, addi (e.g. −48 for ASCII→decimal) |
| Compare | slt, slti (for < 0 and ≥ 10) |
| Branch | beq, bne, j (loops and invalid path) |
| Array index | sll for i×4, add for A + i×4 |
| Store/load word | sw, lw (A[i], counters) |
| Even/odd | andi digit, digit, 1 then branch |
| Print integer | li $v0, 1, move $a0, value, syscall |
| Exit | li $v0, 10, syscall |
This gives you a complete, step-by-step answer to Lab 04 with detailed explanations for every part of the solution.