Back to COMP1521 返回 COMP1521

Week 3 — MIPS Control & Data Flow 第 3 周 — MIPS 控制与数据流

Branching templates, memory access patterns, syscall I/O, and lab-grade loop strategies 分支模板、内存访问模式、系统调用 I/O 与实验级循环策略

🎯 Learning Objectives学习目标

🧩 Exam Alignment与考试练习的对应关系

Coverage Targets 覆盖目标

Log ≥5 branch templates (if/else, cascading `else if`, early exit, min/max, guard) and ≥3 loop skeletons (counted, sentinel, bidirectional). Align each with at least one past exam ID. 记录 ≥5 个分支模板(if/else、级联分支、提前返回、取 min/max、守卫)与 ≥3 个循环骨架(计数型、哨兵型、双向遍历),并与至少一个往年试题编号对齐。

📚 Core Concepts核心概念

Structured Branch Patterns 结构化分支模式

Combine `slt`/`slti` with conditional branches to emulate `<`, `<=`, `>=`, while preserving fall-through blocks. Use guard labels `done`/`fail` to avoid spaghetti jumps. 通过 `slt`/`slti` 与条件跳转组合实现 `<`、`<=`、`>=`,保持落空块顺序,并用 `done`/`fail` 等守卫标签避免“面条式”跳转。

Template: compute flag → branch → handle true-case → jump to epilogue. Reuse for `max`, `min`, range checks. 模板:计算布尔标志 → 分支跳转 → 处理真分支 → 跳转到尾声。可复用于 `max`、`min`、区间判断等场景。

Base+Offset Addressing 基址 + 偏移寻址

Anchor struct or array base in `$t0/$s0`, scale index via shifts (`sll index, index, 2`) for words, or use successive `addi` for byte walks. Remember halfword loads sign-extend. 将结构体或数组基址保存在 `$t0/$s0`,通过移位(如 `sll index, index, 2`)扩展索引实现字访存,或使用连续 `addi` 逐字节遍历。注意半字加载会符号扩展。

When swapping or comparing, stage temporaries in `$t` registers; update memory only after ensuring both loads succeeded. 交换或比较时,先在 `$t` 寄存器保存临时值,确认读取正确后再回写内存。

Loop Skeletons 循环骨架

Counted loop: init counter → `loop:` body → `addi` → compare (`blt`, `bge`, via `slt`) → `bne` to loop. Sentinel loop: load element → check sentinel → break. 计数循环:初始化计数器 → `loop:` 循环体 → `addi` 更新 → 比较(借 `slt` 实现 `blt`、`bge`)→ `bne` 返回。哨兵循环:加载元素 → 检查哨兵值 → 满足即退出。

Two-pointer pattern (Lab03 `unordered.s`): maintain `lo`/`hi`, move indices inward until cross-over, tracking swap count. 双指针模式(Lab03 `unordered.s`):维护 `lo`/`hi`,向内推进直至交叉,同时记录交换次数。

Syscall Toolkit 系统调用工具箱

Store string labels in `.data`, use `la $a0, msg` + `li $v0, 4` to print, or `li $v0, 5` to read ints. Immediately move input to saved register to avoid overwriting by later syscalls. 在 `.data` 存储字符串,使用 `la $a0, msg` + `li $v0, 4` 打印,或 `li $v0, 5` 读入整数。读入后立刻将结果保存到 `$s` 寄存器,避免之后系统调用覆盖。

Wrap sequences in reusable macros (pseudo-code comments) so exam responses cite the same steps consistently. 将调用顺序封装为可复用注释模板,确保考试答题时步骤统一。

🧪 Worked Examples例题与讲解

Example 1 — Two-Number Max (Lab03 `print_bigger.s`) 例 1 — 两数取大(Lab03 `print_bigger.s`)

Goal: read two signed ints, print the larger. Key steps: syscall read → store → compare via `slt` → branch to label `A_is_bigger` or fall-through to `B`. Use outer label `done` for exit. 目标:读入两个有符号整数并输出较大者。关键步骤:系统调用读入 → 保存寄存器 → 通过 `slt` 比较 → 跳转到 `A_is_bigger` 或执行 `B` 分支,最后通过 `done` 标签退出。

# template snippet li $v0, 5 syscall move $t0, $v0 li $v0, 5 syscall move $t1, $v0 slt $t2, $t1, $t0 # if b < a beq $t2, $zero, use_b use_a: move $a0, $t0 j done use_b: move $a0, $t1 done: li $v0, 1 syscall # 模板片段 li $v0, 5 syscall move $t0, $v0 li $v0, 5 syscall move $t1, $v0 slt $t2, $t1, $t0 # 判断 b < a beq $t2, $zero, use_b use_a: move $a0, $t0 j done use_b: move $a0, $t1 done: li $v0, 1 syscall
Exam tip: label jump after printing ensures only one `syscall` path executes, preventing double prints (common deduction). 考试提示:打印后跳转到公共尾声,可防止重复 `syscall`,避免常见扣分。

Example 2 — Bubble Sort Trace (Lab03 Challenge) 例 2 — 冒泡排序追踪(Lab03 挑战)

Focus on outer count vs. inner pointer. Outer loop decrements `n-1`, inner loop compares adjacent words via offset addressing, swapping with 3 temp registers. Branch ordering: compare → no swap path first. 关注外层次数与内层指针。外循环从 `n-1` 递减,内循环通过偏移访问相邻字并使用 3 个临时寄存器交换。分支顺序:先处理无需交换的路径。

During exams, annotate invariants (“prefix [0..i) sorted”). This matches 20T3 Q7 marking notes. 考试中建议写出不变式(如“前缀 [0..i) 已排序”),与 20T3 Q7 评分说明一致。

Example 3 — Byte Swap Routine 例 3 — 字节交换例程

Tutorial03 Q9 asks for reversing four bytes. Strategy: load base pointer, compute offsets 0 and 3, load bytes with `lb`, store swapped via `sb`. Extend to structure fields by adjusting stride. 教程 03 第 9 题需要反转四个字节。策略:载入基址,计算 0 与 3 的偏移,用 `lb` 读出,用 `sb` 交换回写。通过调整跨度可扩展到结构体字段。

⚠️ Common Pitfalls易错点提醒

🛠️ Practice Task实践任务

Implement `grade_stats.s`: read `n` (≤50) scores, track max/min/average, output summary sentence in English and Chinese via two syscalls. Reuse max/min template, sentinel loop for accumulation, and maintain total in `$s1`. Include guard against `n <= 0` with early exit label. 实现 `grade_stats.s`:读入 `n` (≤50) 个分数,统计最大值/最小值/平均值,并使用两次系统调用输出中英文总结。复用取最大/最小模板,使用哨兵循环累加,总分存放 `$s1`,并在 `n <= 0` 时提前退出。

OptionalOptional: extend to median by adapting bubble-sort inner loop (counts for portfolio credit but ≤10% of study time). 可选Optional:借助冒泡排序内循环求中位数(计入学习档案但投入时间不超过 10%)。

🧪 Tutorial & Lab Mapping教程与实验映射

Tutorial 03 Highlights Tutorial 03 重点

  • Q1–Q3 convert C conditionals/loops into register-level MIPS; align with Exam 22T3 Q6. 第 1–3 题将 C 条件与循环转为寄存器级 MIPS,对齐 22T3 试卷第 6 题。
  • Q4 covers syscall ordering and register usage — rehearse before lab demo. 第 4 题复习系统调用顺序与寄存器使用,在实验演示前先熟悉。
  • Rapid-fire debugging prompts (Q7–Q10) expose hidden off-by-one and misaligned loads. 快问快答(第 7–10 题)聚焦越界与对齐错误,提前识别隐藏扣分点。

Lab 03 Programming Tasks Lab 03 编程任务

  • `print_bigger.s`: apply branch template to produce single output syscall. `print_bigger.s`:运用分支模板只保留一次输出调用。
  • `unordered.s`: detect out-of-order pair in array; emphasise pointer arithmetic and sentinel exit. `unordered.s`:检测数组中无序对,强调指针运算与哨兵退出。
  • `swap_numbers.s`: practise load/store ordering, prepping for struct operations midterm. `swap_numbers.s`:练习读写顺序,为期中结构体操作做准备。
  • `bubblesort.s` (challenge): combine nested loops and swap macro — reference for advanced quiz tier. `bubblesort.s`(挑战):结合双层循环与交换宏,为高级测验题提供模板。

📝 Study Log — Week 3学习记录 — 第 3 周

Premium Quiz — 40 Questions Ready Premium 测验 — 40 题全覆盖

28 basic (branches, syscalls), 8 intermediate (array loops, pointer math), 4 advanced (bubblesort trace, nested guards). Unlock with membership to start. 基础 28 题(分支、系统调用),中级 8 题(数组循环、指针运算),高级 4 题(冒泡排序、嵌套守卫)。会员解锁后即可开始。

Go to Week 3 Quiz 进入第 3 周测验

🔭 Next Week Preview下周预告

Week 4 deep-dives into `.data` directives, procedure calls, and recursion-ready stack frames. Review Tutorial 04 Q11 directive list and Lab04 `lookup.s` before class. 第 4 周将深入 `.data` 伪指令、过程调用与支持递归的栈帧。课前先复习教程 04 第 11 题的伪指令清单以及 Lab04 `lookup.s`。

📎 Resources & Checklist资源与清单