Giữa kỳ 2024-2025

Kiến Trúc Máy Tính

Ôn thi Chương 1 & 2 • IT006 • ĐH Công nghệ Thông tin

Tổng hợp kiến thức, bài tập MIPS Assembly, và đề thi mẫu. Bao gồm trình mô phỏng MIPS code trực tiếp trên trình duyệt.

2
Chương
217
Slides
36
Câu hỏi
MIPS Lab
CPU
ALU
CU
REG
MEM

Cấu trúc đề thi

40%
Trắc nghiệm
18 câu × 0.5đ = 9 điểm
60%
Tự luận
Chuyển đổi C → MIPS, Mã máy

Các dạng thường gặp:

C → MIPS Assembly ASM → Mã máy (Hex) Mã máy → ASM Hiệu suất CPU Bù 2 / Signed-Unsigned Logic: AND, OR, SLL, SRL Vòng lặp / Rẽ nhánh Bộ nhớ: lw/sw

Chương 1: Các khái niệm và công nghệ máy tính

Tổng quan, lịch sử, phân loại, và hiệu suất máy tính

1. Lịch sử phát triển máy tính

0

Thế hệ 0: Máy cơ học

Máy sai phân No.2 (1849) - Charles Babbage. Tính toán dựa trên bảng tra.

1

Thế hệ 1 (1945-1955): Đèn chân không

EDVAC (1949): 2500 đèn chân không, 45m², 7.8 tấn, $500,000. Phép toán: +, -, ×, /

2

Thế hệ 2 (1955-1965): Transistor

IBM 7094 (1962): 32K word (16 bit), chu kỳ 2µs, $3 triệu. FORTRAN, COBOL ra đời.

3

Thế hệ 3 (1965-1980): Mạch tích hợp (IC)

IBM System/360 (1971): chu kỳ 0.75µs, 680kg. Hệ điều hành phát triển (Multics).

4

Thế hệ 4 (1980-nay): VLSI

Siêu máy tính Frontier: 8,730,112 lõi, 1.1 exaflops. MacBook Pro M2: CPU 8 lõi, GPU 10 lõi.

LoạiTênNămTransistor
SSISmall-Scale19641-10
MSIMedium-Scale196810-500
LSILarge-Scale1971500-20,000
VLSIVery Large-Scale198020,000-1,000,000
ULSIUltra Large-Scale19841,000,000+

2. Phân loại máy tính

Máy tính cá nhân (PC)

Nhỏ gọn, đa dụng. Tốc độ lên đến 238,310 MIPS ở 3.0 GHz. Văn phòng, học tập, giải trí.

Máy chủ (Server)

Kích thước lớn. Tốc độ lên đến 1102 petaflops (Frontier). Tính toán siêu nhanh, lưu trữ cực lớn.

Máy tính nhúng (Embedded)

Tích hợp trong thiết bị khác (ô tô, đồ gia dụng). Phổ biến nhất hiện nay. Giới hạn về năng lượng, chi phí.

3. Kiến trúc vs Tổ chức máy tính

Kiến trúc máy tính (Architecture) Tổ chức máy tính (Organization)
Thuộc tính & hành vi theo góc nhìn lập trình viên Các đơn vị hoạt động & kết nối của chúng
ISA, chế độ địa chỉ, kiểu dữ liệu Tín hiệu điều khiển, công nghệ bộ nhớ
Ví dụ: x86 ISA Ví dụ: Intel vs AMD triển khai x86 khác nhau

Một kiến trúc (VD: x86) có thể được triển khai bởi nhiều tổ chức khác nhau (Intel Core i7 vs AMD Ryzen).

4. Kiến trúc Von Neumann & Các thành phần

Kiến trúc Von Neumann

Mô hình kiến trúc Von Neumann: CPU (ALU + CU), Memory, I/O

CPU (Bộ xử lý)

CU
Điều khiển
ALU
Số học & Logic

Bộ nhớ (Memory)

Lưu cả dữ liệu & chương trình (Stored Program)

Nhập / Xuất (I/O)

Chu trình thực thi: Fetch (Nạp lệnh) → Decode (Giải mã) → Execute (Thực thi)

Phân cấp bộ nhớ (nhanh → chậm):

Phân cấp bộ nhớ

Phân cấp bộ nhớ: Tốc độ tỉ lệ nghịch với dung lượng

Register Nhanh nhất, nhỏ nhất (~1ns)
Cache (SRAM) Nhanh, đắt (~5ns)
RAM (DRAM) Chậm hơn, rẻ hơn (~100ns)
Disk / SSD Chậm nhất, non-volatile (~10ms)

Định luật Moore: Số lượng transistor trên chip tăng gấp đôi mỗi 18-24 tháng.

Quá trình chuyển đổi chương trình:

Compilation Pipeline

Quy trình: C Program → Compiler → Assembler → Linker → Loader → Memory

C/C++
Compiler
Assembly
Assembler
Object
Linker
Executable
Loader
Memory

Thứ tự đúng: Compiler → Assembler → Linker → Loader

Câu hỏi ôn tập: Phân cấp bộ nhớ & Biên dịch

Câu hỏi 1: Trong quá trình chuyển đổi một chương trình C sang dạng mà máy tính có thể thực thi được, trình tự nào sau đây là đúng?

  1. Trình biên dịch (Compiler) -> Trình biên dịch hợp ngữ (Assembler) -> Trình liên kết (Linker) -> Trình nạp (Loader)
  2. Trình biên dịch hợp ngữ (Assembler) -> Trình biên dịch (Compiler) -> Trình liên kết (Linker) -> Trình nạp (Loader)
  3. Trình biên dịch (Compiler) -> Trình liên kết (Linker) -> Trình biên dịch hợp ngữ (Assembler) -> Trình nạp (Loader)
  4. Trình biên dịch (Compiler) -> Trình nạp (Loader) -> Trình liên kết (Linker) -> Trình biên dịch hợp ngữ (Assembler)

Câu hỏi 2: Hãy sắp xếp các bộ nhớ sau theo thứ tự CÓ TỐC ĐỘ truy xuất GIẢM DẦN?

  1. Registers -> Cache -> Main Memory -> Magnetic Disk
  2. Magnetic Disk -> Main Memory -> Cache -> Registers
  3. Registers -> Main Memory -> Cache -> Magnetic Disk
  4. Cache -> Registers -> Main Memory -> Magnetic Disk
Xem đáp án

Đáp án Câu 1: A. Đây là quy trình chuẩn: Mã C (.c) → Compiler → File ASM (.s) → Assembler → Object (.o) → Linker nối các thư viện → Executable → Loader nạp lên RAM.

Đáp án Câu 2: A. Tốc độ giảm dần (nhanh nhất đến chậm nhất) cũng tương ứng với dung lượng tăng dần và giá thành rẻ dần: Thanh ghi (nhanh nhất) → Cache → RAM (Main Memory) → Ổ cứng Disk (chậm nhất).

5. Hiệu suất máy tính ⭐ QUAN TRỌNG

Bảng Đổi Đơn Vị Quan Trọng (Chú ý khi tính toán)

Thời gian (Time)

1 s (giây) = 10³ ms (milli)

1 ms = 10³ μs (micro)

1 μs = 10³ ns (nano)

1 ns = 10³ ps (pico)


Luôn nhớ: Từ ns ra giây (s) phải nhân với 10⁻⁹.

Tần số (Clock Rate)

1 Hz = 1 chu kỳ / 1 giây

1 KHz = 10³ Hz

1 MHz = 10⁶ Hz

1 GHz = 10⁹ Hz


Quan hệ: f = 1 / T. VD: Chu kỳ 1ns ↔ Tần số 1GHz

Dữ liệu & Bộ nhớ

1 Byte (B) = 8 bits

1 KB = 2¹⁰ B ≈ 10³ B

1 MB = 2²⁰ B ≈ 10⁶ B

1 GB = 2³⁰ B ≈ 10⁹ B

1 TB = 2⁴⁰ B ≈ 10¹² B

Hiệu suất cơ bản

Performance = 1 / Execution Time

A nhanh hơn B n lần: Performance_A / Performance_B = Time_B / Time_A = n

Thời gian CPU

CPU Time = Clock Cycles × Clock Cycle Time
CPU Time = Clock Cycles / Clock Rate

Chu kỳ clock

Clock Cycles = IC × CPI

IC = Instruction Count (Tổng số lệnh)

CPI = Cycles Per Instruction (Chu kỳ/lệnh)

Công thức tổng hợp ⭐

CPU Time = IC × CPI × Clock Cycle Time
CPU Time = (IC × CPI) / Clock Rate

CPI trung bình (nhiều nhóm lệnh)

CPI = Σ(CPIᵢ × Số_lệnh_nhóm_i) / Tổng_số_lệnh
Clock Cycles = Σ(CPIᵢ × Số_lệnh_nhóm_i)

MIPS

MIPS = IC / (Execution_Time × 10⁶)
MIPS = Clock_Rate / (CPI × 10⁶)

IPS / IPC

IPS = Clock_Rate / CPI
IPC = 1 / CPI

Công suất động

P = ½ × C × V² × f

C: Capacitive Load, V: Voltage, f: tần số

Ví dụ tính toán:

Quiz: So sánh hiệu suất

Máy A: Chu kỳ clock = 250ps, CPI = 2.0

Máy B: Chu kỳ clock = 500ps, CPI = 1.2

Cùng ISA → Máy nào nhanh hơn?

Giải:
Time_A = IC × 2.0 × 250 = 500×IC (ps)
Time_B = IC × 1.2 × 500 = 600×IC (ps)

Speedup = Time_B / Time_A = 600/500 = 1.2
Máy A nhanh hơn 1.2 lần
Quiz: Tính thời gian thực thi

Bộ xử lý 2 GHz. 500 lệnh toán (CPI=1), 100 lệnh nạp (CPI=5), 50 lệnh ghi (CPI=5), 50 lệnh rẽ nhánh (CPI=2).

Giải:
Clock Cycles = 500×1 + 100×5 + 50×5 + 50×2 = 500+500+250+100 = 1350
CPU Time = 1350 / (2×10⁹) = 675 × 10⁻⁹ s = 675 ns
Câu hỏi ôn tập: Tính toán hiệu suất (Có trong đề thi)

Câu hỏi 1: Xét một bộ xử lý giả định với chu kỳ xung nhịp là 1.5ns, bộ xử lý này thực thi một đoạn chương trình dài 3x10³ câu lệnh MIPS, với chỉ số CPI là 0.8. Vậy thời gian thực thi của đoạn chương trình trên là bao nhiêu?

  1. 3.6 μs
  2. 3.6 ms
  3. 2.4 ns
  4. 7.2 ns

Câu hỏi 2: Cho một bộ xử lý hoạt động với tần số f = 3GHz, giả sử cần thời gian là 15ns để thực thi xong một chương trình gồm 30 câu lệnh. Tích số CPI cho chương trình vừa thực thi là bao nhiêu?

  1. 1.5
  2. 1.0
  3. 2.0
  4. 0.5
Xem đáp án & Giải thích chi tiết

Đáp án Câu 1: A
Áp dụng công thức: CPU Time = IC × CPI × Clock_Cycle_Time
CPU Time = (3 × 10³) × 0.8 × (1.5 × 10⁻⁹) = 3.6 × 10⁻⁶ giây = 3.6 μs


Đáp án Câu 2: A
Áp dụng công thức: CPU Time = (IC × CPI) / Clock_Rate
Suy ra: CPI = (CPU Time × Clock_Rate) / IC
CPI = (15 × 10⁻⁹ × 3 × 10⁹) / 30 = 45 / 30 = 1.5

Chương 2: Kiến trúc tập lệnh MIPS

Tập lệnh, toán hạng, định dạng lệnh, lệnh điều khiển

1. Các nhóm lệnh MIPS

Nhóm lệnh số học và luận lý

Thao tácLệnhFormatÝ nghĩaMẹo & Ứng dụng
Cộngadd $d, $s, $tR$d = $s + $tTính toán tổng 2 thanh ghi (có xét tràn).
Cộng tức thìaddi $t, $s, immI$t = $s + immCộng hằng số. Vd: addi $t0,$t0,1 (i++). imm là số có dấu bù 2 nên có thể thế lệnh trừ hằng số (vd: -12).
Trừsub $d, $s, $tR$d = $s - $tTrừ 2 thanh ghi. Không có subi, dùng addi số âm thay thế.
So sánh nhỏ hơnslt $d, $s, $tR$d = ($s < $t) ? 1 : 0Lệnh nòng cốt tạo đk if. Đi kèm beq/bne để tạo if(x < y), if(x >= y).
So sánh nhỏ hơn (tức thì)slti $t, $s, immI$t = ($s < imm) ? 1 : 0Tương tự slt nhưng ss với hằng số (VD: so sánh i < 10 trong vòng lặp for).
Dịch tráisll $d, $t, shamtR$d = $t << shamtMẹo tính cực nhanh thay cho phép nhân 2ⁿ. Thường dùng nhân 4 (sll $t, $s, 2) để tính độ dời offset của mảng A[i].
Dịch phảisrl $d, $t, shamtR$d = $t >> shamtPhép chia nguyên cho 2ⁿ (chỉ đúng cho số không dấu unsigned).
ANDand $d, $s, $tR$d = $s & $tPhép Masking. Dùng để che/trích xuất các bit quan tâm thành 0.
AND tức thìandi $t, $s, immI$t = $s & ZeroExt(imm)Kiểm tra bit thứ 0 để xem số chẵn hay lẻ (andi $t0, $s1, 1).
ORor $d, $s, $tR$d = $s | $tBật một số bit nhất định lên 1 mà không ảnh hưởng bit khác.
OR tức thìori $t, $s, immI$t = $s | ZeroExt(imm)Thường dùng cùng lui để tạo hằng số 32-bit lớn hơn 16-bit.
NORnor $d, $s, $tR$d = ~($s | $t)Tại sao MIPS ko có lệnh NOT? Vì nor $d, $s, $zero chính là NOT $s.

Nhóm lệnh truyền dữ liệu

Thao tácLệnhFormatÝ nghĩaMẹo & Ứng dụng
Nạp wordlw $t, offset($s)I$t = Mem[$s + offset]Load 32-bit (4 byte) từ RAM. Địa chỉ bắt buộc phải chia hết cho 4. VD: Đọc phần tử mảng A[i].
Lưu wordsw $t, offset($s)IMem[$s + offset] = $tGhi 32-bit (4 byte) xuống RAM. Địa chỉ cũng phải chia hết cho 4. VD: Gán A[i] = x.
Nạp bytelbu $t, offset($s)I$t = Mem[$s + offset] (1 byte)Lấy đúng 1 ký tự (char) hoặc 1 byte từ mảng byte. Có đệm thêm 24 bit 0 (ZeroExt).
Lưu bytesb $t, offset($s)IMem[$s + offset] = $t (1 byte)Cất 1 byte thấp nhất của thanh ghi xuống RAM. Hay dùng khi xử lý chuỗi (String).
Nạp nửa caolui $t, immI$t = imm << 16Gắn giá trị 16 bit thẳng vào phần Nửa Cao (Upper Half). Lệnh kinh điển tạo hằng số bự (đi kèm ori).

Nhóm lệnh điều khiển

Thao tácLệnhFormatÝ nghĩaMẹo & Ứng dụng
Nhảy nếu bằngbeq $s, $t, labelIif ($s==$t) goto labelKết hợp slt để làm if-else nâng cao. Đề thi bắt tính Offset của Label kiểu gì cũng dính lệnh này.
Nhảy nếu khácbne $s, $t, labelIif ($s!=$t) goto labelLogic rẽ nhánh phủ định. Là "công thức" chuẩn để triển khai vòng lặp while hoặc for.
Nhảyj labelJgoto labelLệnh Jump vô điều kiện. Dùng để kết thúc vòng lặp quay về đầu, hoặc thoát If-Else.
Nhảy thanh ghijr $raRgoto $raVô cùng phổ biến trong Gọi hàm. jr $ra tương đương lệnh return; trong C/C++.
Nhảy và liên kếtjal labelJ$ra = PC+4; goto labelGọi 1 hàm/Chương trình con. Máy sẽ lưu địa chỉ PC kế tiếp vào $ra để return về. Định lý gọi hàm!

2. Thanh ghi MIPS (32 thanh ghi × 32 bit)

SốTênMục đích
0$zeroHằng số 0 (luôn = 0)
1$atAssembler temporary
2-3$v0-$v1Giá trị trả về hàm
4-7$a0-$a3Tham số hàm
8-15$t0-$t7Biến tạm (temporary) ⭐
16-23$s0-$s7Biến lưu trữ (saved) ⭐
24-25$t8-$t9Biến tạm (thêm)
26-27$k0-$k1Kernel (OS)
28$gpGlobal pointer
29$spStack pointer
30$fpFrame pointer
31$raReturn address

Quan trọng cho thi: $t0=$8, $t1=$9, ..., $t7=$15, $t8=$24, $t9=$25. $s0=$16, $s1=$17, ..., $s7=$23. Phải nhớ số hiệu thanh ghi khi chuyển mã máy!

3. Toán hạng & Bộ nhớ

Toán hạng thanh ghi

Dữ liệu nằm trong thanh ghi. VD: add $t0, $s1, $s2

Toán hạng bộ nhớ

Dữ liệu nằm trong bộ nhớ. VD: lw $t0, -8($s2)

Địa chỉ phải là bội của 4. 1 word = 4 bytes.

Toán hạng tức thời

Giá trị hằng số ngay trong lệnh. VD: addi $s3, $s2, 4

$zero luôn = 0. Copy: add $t2, $t1, $zero

Truy cập mảng: A[i] → cần tính offset = i × 4 (vì mỗi word = 4 bytes).
VD: sll $t1, $s3, 2 (nhân i cho 4), rồi add $t1, $t1, $s6 (cộng base), rồi lw $t0, 0($t1)

Big-Endian vs Little-Endian:

Big-Endian vs Little-Endian

MIPS sử dụng Big-Endian: MSB lưu ở địa chỉ thấp nhất

Ví dụ: Lưu 0x12345678 tại địa chỉ 0x0000

Big-Endian (MIPS)

0x0000 → 0x12 (MSB trước)

0x0001 → 0x34

0x0002 → 0x56

0x0003 → 0x78 (LSB)

Little-Endian (x86)

0x0000 → 0x78 (LSB trước)

0x0001 → 0x56

0x0002 → 0x34

0x0003 → 0x12 (MSB)

Đề thi thường hỏi: lw nạp 4 bytes liên tiếp thành 1 word. sw ghi 1 word ra 4 bytes liên tiếp. Địa chỉ word phải chia hết cho 4 (word-aligned).

Câu hỏi ôn tập: Định chỉ bộ nhớ

Câu hỏi: Trong đoạn mã assembly bên dưới, giá trị offset trong lệnh `lw` là bao nhiêu để lấy được phần tử i trong mảng biết địa chỉ bắt đầu của mảng được lưu trữ trong $s0, giá trị của i được lưu trữ ở $s1? Giả sử mỗi phần tử là 1 số nguyên (4 byte).

sll $t0, $s1, 2
add $t0, $s0, $t0
lw $s2, ___($t0)
  1. (Trống)
  2. 0
  3. 4
  4. i * 4
Xem đáp án

Đáp án: B (0)

Giải thích: Thanh ghi $t0 đã tính toán xong địa chỉ bộ nhớ chính xác của phần tử A[i] (bằng base address + i * 4). Do đó quá trình nạp (lw) từ địa chỉ $t0 không cần cộng thêm offset nào nữa. Offset là 0.

4. Số có dấu & không dấu (Bù 2)

Biểu diễn bù 2 (Two's Complement)

Số = -b₃₁ × 2³¹ + b₃₀ × 2³⁰ + ... + b₁ × 2¹ + b₀ × 2⁰

MSB = 0 → số dương | MSB = 1 → số âm

32 bit: phạm vi [-2,147,483,648 đến 2,147,483,647]

Chuyển số âm sang bù 2:

1. Viết dạng nhị phân của giá trị tuyệt đối

2. Đảo tất cả bit (NOT)

3. Cộng thêm 1


VD: -1000 (16 bit)

1000 = 0000 0011 1110 1000

Đảo: 1111 1100 0001 0111

+1: 1111 1100 0001 1000 = 0xFC18

Mở rộng: Sign-extend (lặp bit dấu) cho signed. Zero-extend (thêm 0) cho unsigned.

⚠️ Sign-extend vs Zero-extend (Hay hỏi thi!)
LệnhImmediate mở rộng kiểuLý do
addi, slti, lw, sw, beq, bneSign-extend (lặp bit dấu)Cần xử lý số âm
andi, oriZero-extend (thêm 0)Phép logic trên bit pattern
luiKhông mở rộng (đặt trực tiếp)imm << 16, 16 bit dưới = 0
VD Sign-extend: 16 bit 1111 1111 0110 1110 (-146)
→ 32 bit: 1111 1111 1111 1111 1111 1111 0110 1110

VD Zero-extend: 16 bit 1111 1111 0110 1110 (0xFF6E)
→ 32 bit: 0000 0000 0000 0000 1111 1111 0110 1110
VD thêm: -2024 (16 bit)

2024 = 0x07E8 = 0000 0111 1110 1000

Đảo: 1111 1000 0001 0111

+1: 1111 1000 0001 1000 = 0xF818

Câu hỏi ôn tập: Bù 2 & Sign Extension

Câu hỏi: Cho lệnh addi $t0, $s1, -12. Khi bộ xử lý chuyển lệnh này xuống dạng mã máy, giá trị -12 (hệ thập phân) sẽ được lưu trong vùng immediate (16 bit) dưới dạng nhị phân là gì?

  1. 1111 1111 1111 0100
  2. 1000 0000 0000 1100
  3. 0000 0000 0000 1100
  4. 1111 1111 1111 0011
Xem đáp án

Đáp án: A

Giải thích cách tính bù 2 của -12 trên 16 bit:
12 hệ cơ số 10 = 0000 0000 0000 1100 (nhị phân)
Bước 1 - Đảo bit (Not): 1111 1111 1111 0011
Bước 2 - Cộng 1: 1111 1111 1111 0011 + 1 = 1111 1111 1111 0100

5. Định dạng lệnh (R, I, J) ⭐ QUAN TRỌNG

Hướng dẫn đọc Bảng Mã MIPS (MIPS Green Card)

Khi được đem bảng tra vào phòng thi, bạn KHÔNG CẦN học thuộc chính xác các số opcode hay funct, mà chỉ cần biết cách tra cứu 4 cột quan trọng nhất:

  • Cột FORMAT: Ký hiệu R, I, J. Nhìn cột này để biết ngay phải điền giá trị theo cấu trúc vẽ khung nào.
  • Cột OPERATION: Minh họa công thức toán. VD lệnh lw ghi R[rt] = M[R[rs] + SignExtImm]. Nhìn vào đây bạn xác định luôn được ai là thanh ghi nguồn (rs), đích (rt).
  • Cột OPCODE (Hex): Quy luật là "Opcode / Funct".
    • Lệnh I-type, J-type: Bảng chỉ ghi 1 số (vd 8 cho lệnh addi, 23 cho lệnh lw). Đây chính là Opcode (nhớ chuyển số hex này ra 6 bit nhị phân).
    • Lệnh R-type: Bảng ghi dạng 0 / 20 (lệnh add) hay 0 / 22 (sub). Số 0 phía trước là Opcode luôn = 000000. Số phía sau dấu / là Funct (vd 20 hex = 100000 nhị phân).

Mẹo dịch Assembly ➔ Mã Máy siêu tốc: Xác định Format ➔ Kẻ đúng số khung bit (6-5-5-16 đối với I, 6-5-5-5-5-6 đối với R) ➔ Tra Green Card điền Opcode/Funct ➔ Điền giá trị các Register (vd $t0=8) ➔ Gom 4 bit một để ra Hex vòng cuối.

R-type Instruction Format

Định dạng lệnh R-type với ví dụ add $t0, $s1, $s2

R-type (Register)

op
6 bit
rs
5 bit
rt
5 bit
rd
5 bit
shamt
5 bit
funct
6 bit

op = 000000 cho tất cả lệnh R-type. Phân biệt bằng funct.

Lệnhfunct (hex)funct (bin)
add0x20100000
sub0x22100010
and0x24100100
or0x25100101
nor0x27100111
slt0x2A101010
sll0x00000000
srl0x02000010
jr0x08001000
VD: add $t0, $s1, $s2

op=000000 | rs=$s1=10001 | rt=$s2=10010 | rd=$t0=01000 | shamt=00000 | funct=100000

= 000000 10001 10010 01000 00000 100000 = 0x02324020

I-type (Immediate)

op
6 bit
rs
5 bit
rt
5 bit
immediate
16 bit
Lệnhopcode (hex)opcode (bin)Ghi chú
addi0x08001000rt = rs + imm
andi0x0C001100rt = rs & ZeroExt(imm)
ori0x0D001101rt = rs | ZeroExt(imm)
slti0x0A001010rt = (rs < imm) ? 1 : 0
lw0x23100011rt = Mem[rs + imm]
sw0x2B101011Mem[rs + imm] = rt
beq0x04000100if(rs==rt) PC+=imm<<2
bne0x05000101if(rs!=rt) PC+=imm<<2
lbu0x24100100rt = Mem[rs + imm] (byte)
sb0x28101000Mem[rs + imm] = rt (byte)
lui0x0F001111rt = imm << 16
VD: addi $13, $t5, -146 (Chính xác câu Tự luận!)

op(addi)=001000 | rs=$t5($13)=01101 | rt=$13=01101 | imm=-146

-146 bù 2 (16 bit): 146 = 0000 0000 1001 0010 → đảo: 1111 1111 0110 1101 → +1: 1111 1111 0110 1110

= 001000 01101 01101 1111111101101110

= 0010 0001 1010 1101 1111 1111 0110 1110 = 0x21ADFF6E

J-type (Jump)

op
6 bit
address
26 bit

j: op = 000010 (0x02) | jal: op = 000011 (0x03)

Địa chỉ nhảy = {PC+4[31:28], address, 00}

Lưu ý sll/srl: rs = 00000, rt = thanh ghi nguồn, rd = thanh ghi đích, shamt = lượng dịch.

⚠️ Tính offset cho beq/bne (Hay hỏi thi!)

Công thức: Target = PC + 4 + SignExt(imm) × 4

Hay: imm = (Target - (PC + 4)) / 4

VD: beq tại 0x400000, nhảy đến PASS tại 0x40000C
imm = (0x40000C - 0x400004) / 4 = 0x8 / 4 = 2
→ immediate = 0000000000000010
🔄 Quy trình chuyển ASM → Mã máy (4 bước)

Bước 1: Tra bảng MIPS → xác định format (R/I/J)

Bước 2: Tra opcode (và funct nếu R-type)

Bước 3: Tra số hiệu thanh ghi (rs, rt, rd)

Bước 4: Điền shamt/immediate → ghép thành 32 bit → chuyển hex

🔄 Quy trình chuyển Mã máy → ASM (ngược lại)

Bước 1: Chuyển hex → nhị phân 32 bit

Bước 2: Lấy 6 bit đầu (opcode). Nếu = 000000 → R-type, tra 6 bit cuối (funct)

Bước 3: Chia các trường theo format, tra tên thanh ghi

Bước 4: Hoàn thành lệnh ASM

Câu hỏi ôn tập: Dịch mã máy (Có trong đề thi)

Câu hỏi Tự luận: Hãy tìm mã máy biểu diễn dưới dạng thập lục phân cho lệnh sau: addi $13, $t5, -146

Xem đáp án chi tiết

Bước 1: Phân tích lệnh
Lệnh addi là lệnh I-type.
Cấu trúc: op(6) | rs(5) | rt(5) | immediate(16)

Bước 2: Tìm giá trị các trường
• Lệnh addi có opcode là 8 (hệ thập phân) = 001000 (nhị phân)
• rs là thanh ghi nguồn $t5 (số hiệu là 13) = 01101 (nhị phân)
• rt là thanh ghi đích $13 (chính là $t5, số hiệu 13) = 01101 (nhị phân)
• immediate là -146.

Bước 3: Chuyển -146 sang bù 2 (16 bit)
146 (hệ 10) = 0000 0000 1001 0010 (nhị phân)
Đảo bit = 1111 1111 0110 1101
Cộng 1 = 1111 1111 0110 1110 (nhị phân)

Bước 4: Ghép 32 bit
001000 | 01101 | 01101 | 1111 1111 0110 1110
= 0010 0001 1010 1101 1111 1111 0110 1110 (nhị phân)
Chuyển nhóm 4 bit sang Hex:
= 0x21ADFF6E

6. Chuyển đổi C → MIPS Assembly ⭐ TỰ LUẬN

VD1: if-then-else
// C code:
if (i == j) f = g + h;
else f = g - h;

// f=$s0, g=$s1, h=$s2, i=$s3, j=$s4
      bne  $s3, $s4, Else   # if i != j, goto Else
      add  $s0, $s1, $s2    # f = g + h
      j    Exit
Else: sub  $s0, $s1, $s2    # f = g - h
Exit:
VD2: Vòng lặp while
// C code:
while (save[i] == k)
    i += 1;

// i=$s3, k=$s5, base(save)=$s6
Loop: sll   $t1, $s3, 2      # $t1 = 4 * i
      add   $t1, $t1, $s6    # $t1 = addr of save[i]
      lw    $t0, 0($t1)      # $t0 = save[i]
      bne   $t0, $s5, Exit   # if save[i]!=k, exit
      addi  $s3, $s3, 1      # i++
      j     Loop
Exit:
VD3: Vòng lặp for (Dạng đề thi!) ⭐
// C code:
sum = 0;
for(i = 0; i < 8; i++)
    sum = sum + A[i];
avg = sum / 8;

// i=$s0, sum=$s1, avg=$s2, base(A)=$s3
      addi  $s1, $zero, 0     # sum = 0
      addi  $s0, $zero, 0     # i = 0
Loop: slti  $t0, $s0, 8       # $t0 = (i < 8) ? 1 : 0
      beq   $t0, $zero, Done  # if i >= 8, exit
      sll   $t1, $s0, 2       # $t1 = i * 4
      add   $t1, $t1, $s3     # $t1 = &A[i]
      lw    $t2, 0($t1)       # $t2 = A[i]
      add   $s1, $s1, $t2     # sum += A[i]
      addi  $s0, $s0, 1       # i++
      j     Loop
Done: srl   $s2, $s1, 3       # avg = sum / 8
VD4: if-else với mảng
// C code:
if (i > j) { A[i] = A[3] + 1; }
else { A[i+1] = 10; }
i++;

// i=$s0, j=$s1, base(A)=$s3
      slt   $t0, $s1, $s0        # $t0 = (j < i) = (i > j)
      beq   $t0, $zero, Else     # if NOT(i>j), goto Else
      lw    $t1, 12($s3)         # $t1 = A[3]
      addi  $t1, $t1, 1          # $t1 = A[3] + 1
      sll   $t2, $s0, 2          # $t2 = i * 4
      add   $t2, $t2, $s3        # $t2 = &A[i]
      sw    $t1, 0($t2)          # A[i] = A[3]+1
      j     Exit
Else: addi  $t3, $zero, 10       # $t3 = 10
      addi  $t4, $s0, 1          # $t4 = i+1
      sll   $t4, $t4, 2          # $t4 = (i+1)*4
      add   $t4, $t4, $s3        # $t4 = &A[i+1]
      sw    $t3, 0($t4)          # A[i+1] = 10
Exit: addi  $s0, $s0, 1          # i++

Mẹo so sánh:
• if (a >= b): slt $t0,$a,$b + beq $t0,$zero,LABEL
• if (a < b): slt $t0,$a,$b + bne $t0,$zero,LABEL
• if (a > b): slt $t0,$b,$a + bne $t0,$zero,LABEL
• if (a <= b): slt $t0,$b,$a + beq $t0,$zero,LABEL

7. Lập trình ASM trên MARS 4.5

Cấu trúc chương trình ASM:
# Chú thích bằng ký tự #
.data             # Khai báo dữ liệu
    var1: .word   3           # biến nguyên 1 word
    arr1: .byte   'a', 'k'   # mảng byte
    arr2: .space  40          # 40 byte liên tục
    str1: .asciiz "ahihi"    # chuỗi kết thúc null

.text             # Viết chương trình
main:             # Nhãn bắt đầu
    # Code ở đây

Các kiểu dữ liệu:

DirectiveMô tảVí dụ
.wordSố nguyên 32 bit (4 bytes)var: .word 3, 5, 7
.byteKý tự / số 8 bit (1 byte)arr: .byte 'a', 'k'
.spaceCấp phát N byte liên tụcbuf: .space 40
.asciizChuỗi kết thúc bằng nullstr: .asciiz "hello"
.asciiChuỗi KHÔNG có null cuốistr: .ascii "hi"

Hệ số: Thập phân (17), Hex thêm tiền tố 0x (0x17). Ký tự trong nháy đơn ('c'), chuỗi trong nháy kép ("IT006").

Đề thi ASM (đề 2): Chuyển chữ thường → hoa: trừ 32 (vì 'a' - 'A' = 97 - 65 = 32). Dùng lbu nạp 1 byte, sb ghi 1 byte. Kiểm tra range [97, 122] ('a' đến 'z').

MIPS Lab - Trình mô phỏng

Viết và chạy code MIPS Assembly trực tiếp, xem thanh ghi & bộ nhớ thay đổi

Editor

1
Bài mẫu:

Console

🚀 MIPS Simulator sẵn sàng. Viết code và nhấn Assemble!

Thanh ghi

Mã máy (Hex)

Nhấn Assemble để xem mã máy

Luyện Đề Thi

Đề thi giữa kỳ mẫu - Tự động xoay đề & Chấm điểm

Đề số: ---
--:--
Trắc nghiệm: 12 câu × 0.5đ = 6đ (60%) Tự luận: 2 câu × 2đ = 4đ (40%)

Câu 1 (2đ): Chuyển C → MIPS Assembly

Câu 2 (2đ): Tính toán hiệu suất CPU

Bảng tổng hợp công thức & Cheat Sheet

Tất cả công thức cần nhớ cho kỳ thi

🕐 Hiệu suất CPU

CPU Time = IC × CPI / Clock Rate
CPU Time = IC × CPI × Cycle Time
Performance = 1 / CPU Time
Speedup = Time_old / Time_new

📊 CPI & IPS

CPI_avg = Σ(CPIᵢ × countᵢ) / Σcountᵢ
MIPS = IC / (Time × 10⁶)
IPS = Clock_Rate / CPI
IPC = 1 / CPI

⚡ Công suất

P = ½ × C × V² × f

🔢 Bù 2 (Two's Complement)

-N = NOT(N) + 1

16 bit: [-32768, 32767]

32 bit: [-2³¹, 2³¹-1]

📐 Đơn vị

1 GHz = 10⁹ Hz

1 ns = 10⁻⁹ s

1 ps = 10⁻¹² s

1 word = 4 bytes = 32 bits

1 MB = 10⁶ bytes (network) hoặc 2²⁰ bytes

🔧 R-type Format

| op(6) | rs(5) | rt(5) | rd(5) | shamt(5) | funct(6) |

add: funct=0x20, sub: 0x22, and: 0x24, or: 0x25

slt: 0x2A, sll: 0x00, srl: 0x02, jr: 0x08

📝 I-type Format

| op(6) | rs(5) | rt(5) | immediate(16) |

addi: 0x08, andi: 0x0C, ori: 0x0D, slti: 0x0A

lw: 0x23, sw: 0x2B, beq: 0x04, bne: 0x05

lbu: 0x24, sb: 0x28, lui: 0x0F

🔀 Thanh ghi (Số hiệu)

$t0-$t7 = Reg 8-15

$s0-$s7 = Reg 16-23

$t8-$t9 = Reg 24-25

$a0-$a3 = Reg 4-7

$v0-$v1 = Reg 2-3

$zero=Reg 0, $ra=Reg 31, $sp=Reg 29

💡 Mẹo so sánh (không có bgt/blt)

a ≥ b: slt $t0,$a,$b + beq $t0,$zero,L

a < b: slt $t0,$a,$b + bne $t0,$zero,L

a > b: slt $t0,$b,$a + bne $t0,$zero,L

a ≤ b: slt $t0,$b,$a + beq $t0,$zero,L

🔄 Truy cập mảng A[i]

sll  $t1, $s0, 2      # offset = i * 4
add  $t1, $t1, $s3     # addr = base + offset
lw   $t2, 0($t1)       # val = A[i]
sw   $t2, 0($t1)       # A[i] = val

📦 Compilation Pipeline

Compiler → Assembler → Linker → Loader

C → Assembly → Object → Executable → Memory

🗄️ Bộ nhớ (Cache)

Cache hoạt động là bộ đệm giữa CPU và RAM

Nhanh→Chậm: Register > Cache > RAM > SSD/HDD

Dung lượng: Register < Cache < RAM < SSD/HDD

Stack: LIFO (Last-In-First-Out)