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

  1. Array A: Store 8 integers (words), one per digit of your Student ID (SID). So A has 8 elements: A[0] … A[7].
  2. Prompt: Ask the user to enter their SID as an ASCII string (e.g. "20210342").
  3. 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].
  4. 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 subtract 0x30).
  • 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, $zero then bne $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]: la base, then add base, base, i*4, or use sll to 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 $s0 keeps it across the loop; you could use a temporary if you prefer.
  • Character address: buffer + i is computed as la $t0, buffer then add $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, -48 gives the digit value 0–9 for valid input.
  • Check value < 0: slt $t3, $t2, $zero sets $t3=1 if $t2 < 0. bne $t3, $zero, step1_invalid jumps to invalid if so.
  • Check value > 9: slti $t3, $t2, 10 sets $t3=1 if $t2 < 10. So $t3=0 means $t2 ≥ 10. beq $t3, $zero, step1_invalid jumps to invalid.
  • Store in A[i]: Address of A[i] is A + i*4. sll $t5, $s0, 2 computes i×4; add $t4, $t4, $t5 gives the address; sw $t2, 0($t4) stores the digit.
  • Loop end: Increment i with addi $s0, $s0, 1. If $s0 != 8, branch back to step1_for; otherwise jump to step1_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_msg with syscall 4, then j 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 with li $s1, 0 and li $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 $s0 from 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 character a → 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 .asm file with the required naming (e.g. ICO_Lab4_CL01_YourName_StudentID.asm and .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.