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.
Cấu trúc đề thi
Các dạng thường gặp:
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
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.
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: +, -, ×, /
Thế hệ 2 (1955-1965): Transistor
IBM 7094 (1962): 32K word (16 bit), chu kỳ 2µs, $3 triệu. FORTRAN, COBOL ra đời.
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).
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ại | Tên | Năm | Transistor |
|---|---|---|---|
| SSI | Small-Scale | 1964 | 1-10 |
| MSI | Medium-Scale | 1968 | 10-500 |
| LSI | Large-Scale | 1971 | 500-20,000 |
| VLSI | Very Large-Scale | 1980 | 20,000-1,000,000 |
| ULSI | Ultra Large-Scale | 1984 | 1,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
Mô hình kiến trúc Von Neumann: CPU (ALU + CU), Memory, I/O
CPU (Bộ xử lý)
Điều khiển
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ớ: Tốc độ tỉ lệ nghịch với dung lượng
Đị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:
Quy trình: C Program → Compiler → Assembler → Linker → 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?
- 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)
- 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)
- 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)
- 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?
- Registers -> Cache -> Main Memory -> Magnetic Disk
- Magnetic Disk -> Main Memory -> Cache -> Registers
- Registers -> Main Memory -> Cache -> Magnetic Disk
- 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
A nhanh hơn B n lần: Performance_A / Performance_B = Time_B / Time_A = n
Thời gian CPU
Chu kỳ clock
IC = Instruction Count (Tổng số lệnh)
CPI = Cycles Per Instruction (Chu kỳ/lệnh)
Công thức tổng hợp ⭐
CPI trung bình (nhiều nhóm lệnh)
MIPS
IPS / IPC
Công suất động
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?
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).
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?
- 3.6 μs
- 3.6 ms
- 2.4 ns
- 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.5
- 1.0
- 2.0
- 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ác | Lệnh | Format | Ý nghĩa | Mẹo & Ứng dụng |
|---|---|---|---|---|
| Cộng | add $d, $s, $t | R | $d = $s + $t | Tính toán tổng 2 thanh ghi (có xét tràn). |
| Cộng tức thì | addi $t, $s, imm | I | $t = $s + imm | Cộ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, $t | R | $d = $s - $t | Trừ 2 thanh ghi. Không có subi, dùng addi số âm thay thế. |
| So sánh nhỏ hơn | slt $d, $s, $t | R | $d = ($s < $t) ? 1 : 0 | Lệ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, imm | I | $t = ($s < imm) ? 1 : 0 | Tươ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ái | sll $d, $t, shamt | R | $d = $t << shamt | Mẹ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ải | srl $d, $t, shamt | R | $d = $t >> shamt | Phép chia nguyên cho 2ⁿ (chỉ đúng cho số không dấu unsigned). |
| AND | and $d, $s, $t | R | $d = $s & $t | Phé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, imm | I | $t = $s & ZeroExt(imm) | Kiểm tra bit thứ 0 để xem số chẵn hay lẻ (andi $t0, $s1, 1). |
| OR | or $d, $s, $t | R | $d = $s | $t | Bậ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, imm | I | $t = $s | ZeroExt(imm) | Thường dùng cùng lui để tạo hằng số 32-bit lớn hơn 16-bit. |
| NOR | nor $d, $s, $t | R | $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ác | Lệnh | Format | Ý nghĩa | Mẹo & Ứng dụng |
|---|---|---|---|---|
| Nạp word | lw $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 word | sw $t, offset($s) | I | Mem[$s + offset] = $t | Ghi 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 byte | lbu $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 byte | sb $t, offset($s) | I | Mem[$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 cao | lui $t, imm | I | $t = imm << 16 | Gắ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ác | Lệnh | Format | Ý nghĩa | Mẹo & Ứng dụng |
|---|---|---|---|---|
| Nhảy nếu bằng | beq $s, $t, label | I | if ($s==$t) goto label | Kế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ác | bne $s, $t, label | I | if ($s!=$t) goto label | Logic rẽ nhánh phủ định. Là "công thức" chuẩn để triển khai vòng lặp while hoặc for. |
| Nhảy | j label | J | goto label | Lệ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 ghi | jr $ra | R | goto $ra | Vô 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ết | jal label | J | $ra = PC+4; goto label | Gọ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ên | Mục đích |
|---|---|---|
| 0 | $zero | Hằng số 0 (luôn = 0) |
| 1 | $at | Assembler temporary |
| 2-3 | $v0-$v1 | Giá trị trả về hàm |
| 4-7 | $a0-$a3 | Tham số hàm |
| 8-15 | $t0-$t7 | Biến tạm (temporary) ⭐ |
| 16-23 | $s0-$s7 | Biến lưu trữ (saved) ⭐ |
| 24-25 | $t8-$t9 | Biến tạm (thêm) |
| 26-27 | $k0-$k1 | Kernel (OS) |
| 28 | $gp | Global pointer |
| 29 | $sp | Stack pointer |
| 30 | $fp | Frame pointer |
| 31 | $ra | Return 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:
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)
- (Trống)
- 0
- 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)
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ệnh | Immediate mở rộng kiểu | Lý do |
|---|---|---|
addi, slti, lw, sw, beq, bne | Sign-extend (lặp bit dấu) | Cần xử lý số âm |
andi, ori | Zero-extend (thêm 0) | Phép logic trên bit pattern |
lui | Không mở rộng (đặt trực tiếp) | imm << 16, 16 bit dưới = 0 |
→ 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ì?
- 1111 1111 1111 0100
- 1000 0000 0000 1100
- 0000 0000 0000 1100
- 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
lwghiR[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
8cho lệnh addi,23cho 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) hay0 / 22(sub). Số0phía trước là Opcode luôn = 000000. Số phía sau dấu / là Funct (vd 20 hex = 100000 nhị phân).
- Lệnh I-type, J-type: Bảng chỉ ghi 1 số (vd
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.
Định dạng lệnh R-type với ví dụ add $t0, $s1, $s2
R-type (Register)
6 bit
5 bit
5 bit
5 bit
5 bit
6 bit
op = 000000 cho tất cả lệnh R-type. Phân biệt bằng funct.
| Lệnh | funct (hex) | funct (bin) |
|---|---|---|
| add | 0x20 | 100000 |
| sub | 0x22 | 100010 |
| and | 0x24 | 100100 |
| or | 0x25 | 100101 |
| nor | 0x27 | 100111 |
| slt | 0x2A | 101010 |
| sll | 0x00 | 000000 |
| srl | 0x02 | 000010 |
| jr | 0x08 | 001000 |
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)
6 bit
5 bit
5 bit
16 bit
| Lệnh | opcode (hex) | opcode (bin) | Ghi chú |
|---|---|---|---|
| addi | 0x08 | 001000 | rt = rs + imm |
| andi | 0x0C | 001100 | rt = rs & ZeroExt(imm) |
| ori | 0x0D | 001101 | rt = rs | ZeroExt(imm) |
| slti | 0x0A | 001010 | rt = (rs < imm) ? 1 : 0 |
| lw | 0x23 | 100011 | rt = Mem[rs + imm] |
| sw | 0x2B | 101011 | Mem[rs + imm] = rt |
| beq | 0x04 | 000100 | if(rs==rt) PC+=imm<<2 |
| bne | 0x05 | 000101 | if(rs!=rt) PC+=imm<<2 |
| lbu | 0x24 | 100100 | rt = Mem[rs + imm] (byte) |
| sb | 0x28 | 101000 | Mem[rs + imm] = rt (byte) |
| lui | 0x0F | 001111 | rt = 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)
6 bit
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
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:
| Directive | Mô tả | Ví dụ |
|---|---|---|
.word | Số nguyên 32 bit (4 bytes) | var: .word 3, 5, 7 |
.byte | Ký tự / số 8 bit (1 byte) | arr: .byte 'a', 'k' |
.space | Cấp phát N byte liên tục | buf: .space 40 |
.asciiz | Chuỗi kết thúc bằng null | str: .asciiz "hello" |
.ascii | Chuỗi KHÔNG có null cuối | str: .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
Console
Thanh ghi
Mã máy (Hex)
Luyện Đề Thi
Đề thi giữa kỳ mẫu - Tự động xoay đề & Chấm điểm
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
📊 CPI & IPS
⚡ Công suất
🔢 Bù 2 (Two's Complement)
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
add: funct=0x20, sub: 0x22, and: 0x24, or: 0x25
slt: 0x2A, sll: 0x00, srl: 0x02, jr: 0x08
📝 I-type Format
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)