Máy tính hiểu mã lệnh như thế nào?

Mô hình CPU 8-bit trực quan. Nhấn từng bước để nhìn thấy mỗi byte di chuyển qua chu trình Nạp → Giải mã → Thực thi.

8-BIT · 16 BYTES RAM · CPU MÔ PHỎNG
Chọn chương trình
Sẵn sàng

Nhấn “Một bước” để chạy chậm từng nhịp, hoặc “Chạy” để tự động.

Số nhịp đã chạy: 0 · thủ công
Bảng mạch CPU
RAMMemory · 16×8-bit
Thanh ghi lệnh (IR)Instruction Reg.
Bộ đếm CT (PC)Program Counter
Trỏ tới ô: 0
Bộ điều khiểnControl Unit
Đang chờ…
Bus dữ liệu
Thanh ghi AAccumulator
0 · 00000000
Thanh ghi BOperand Reg.
0 · 00000000
ALUArithmetic Logic Unit
Bộ số học · cộng/trừ
ZERO = 0
CARRY = 0
Đèn kết quảOutput Register
= 0
RAM / địa chỉ Thanh ghi · bus Điều khiển A · B ALU Kết quả
Về mô hình này

Không cóBộ nhớ đệm (cache L1/L2/L3). CPU thật thêm cache để chạy nhanh hơn vì RAM tương đối chậm. Mô hình này cố tình bỏ cache để các em nhìn thấy rõ từng lần đọc RAM.

Xung nhịp (clock). Nút “Một bước” chính là một nhịp đồng hồ. Nút “Chạy” là xung nhịp tự động; thanh Tốc độ giống như thay đổi “GHz” của CPU.

Chương trình được nạp thế nào? Con người dịch hợp ngữ (ví dụ LDA 14) thành mã máy nhị phân (0001 1110), rồi đặt các byte đó vào RAM trước khi CPU chạy. Đó chính là “nạp chương trình”. Sáu ví dụ này được nạp sẵn — chưa có nhập liệu trực tiếp từ người dùng.

Giới hạnChỉ 8-bit. Thanh ghi A chỉ giữ được số 0–255. Nếu phép cộng vượt quá 255 hoặc phép trừ xuống dưới 0, máy sẽ báo TRÀN SỐ và dừng — đúng như giới hạn thật của phần cứng 8-bit. Tham số lệnh chỉ 0–15 (4 bit), bộ nhớ chỉ 16 ô.

Đây là mô hình đơn giản hóa để hiểu nguyên lý. CPU thật phức tạp hơn nhiều, nhưng chu trình Nạp – Giải mã – Thực thi thì vẫn vậy.

Nhật ký thực thi
Nhấn vào một dòng để tua lại và xem khối nào sáng ở bước đó. ● đang xem lại quá khứ
Chưa có bước nào. Nhấn “Một bước” hoặc “Chạy” để bắt đầu — mỗi nhịp sẽ ghi lại một dòng ở đây.
Tự viết chương trình
Mỗi dòng một lệnh. Lệnh: LDA ADD SUB STA LDI JMP JZ OUT HLT. Dùng tên: để đặt nhãn rồi JMP tên. DAT n đặt dữ liệu, ORG n đổi địa chỉ. Ghi chú sau dấu ;.
ÔMã máyHợp ngữ · ghi chú
Các khối của CPU

CPU gồm nhiều khối, mỗi khối một nhiệm vụ. Nhấn vào một khối trên bảng mạch phía trên (hoặc một thẻ bên dưới) để xem giải thích. Dữ liệu luôn chảy qua bus để đi từ khối này sang khối khác.

Giải thích từng lệnh

Toàn bộ CPU này chỉ hiểu 9 lệnh. Mỗi lệnh là một byte: 4 bit đầu là mã lệnh (opcode), 4 bit sau là tham số. Nhấn vào một thẻ để chèn ví dụ vào ô soạn thảo phía trên.

Chỉ thị cho trình dịch (không phải lệnh CPU)
Câu hỏi thường gặp
CPU này có giống CPU thật trong máy tính/điện thoại không?

Đây là mô hình đơn giản hoá tối đa để hiểu nguyên lý. CPU thật phức tạp hơn rất nhiều: 64-bit, nhiều nhân, có bộ nhớ đệm, chạy hàng tỉ nhịp mỗi giây. Nhưng nguyên lý cốt lõi thì giống nhau: vẫn là chu trình Nạp → Giải mã → Thực thi lặp lại theo từng nhịp xung.

Vì sao chỉ có 16 ô nhớ? Có vẻ quá ít.

Đúng là rất ít — và đó là cố ý. Địa chỉ trong lệnh chỉ dùng 4 bit nên chỉ trỏ được tới 16 ô (2⁴ = 16). Ít ô giúp ta hiện toàn bộ bộ nhớ lên màn hình cùng lúc, nhìn thấy mọi byte. Hệ quả thú vị: chương trình và dữ liệu phải chia nhau 16 ô đó, nên có những thuật toán (như phép nhân/chia có vòng lặp đầy đủ) không vừa — đó cũng là một bài học thật về giới hạn phần cứng.

Vì sao máy chỉ làm được tới số 255?

Thanh ghi A chỉ có 8 bit, mà 8 bit biểu diễn được các số từ 0 đến 255 (2⁸ = 256 giá trị). Nếu phép cộng vượt quá 255 hoặc phép trừ xuống dưới 0, máy báo TRÀN SỐ và dừng — đúng như giới hạn thật của một thanh ghi 8-bit. CPU 64-bit ngày nay đếm được tới con số khổng lồ vì có 64 bit.

Vì sao CPU không có lệnh NHÂN hay CHIA?

Vì phần cứng càng đơn giản càng dễ hiểu. CPU này chỉ biết cộng, trừ, và nhảy. Mọi phép phức tạp hơn đều được dựng từ ba phép đó: nhân = cộng nhiều lần, chia = trừ nhiều lần (xem ví dụ “Nhân 3×4” và “Tổng 1+…+N”). Đây chính là điều sâu sắc nhất của bài học — máy tính làm việc lớn bằng cách lặp lại việc nhỏ. Muốn biết phép cộng thực sự xảy ra thế nào trong silicon? Xem Cổng logic & Bộ cộng.

Làm sao chương trình “vào” được trong RAM?

Con người viết hợp ngữ (ví dụ LDA 14), trình dịch đổi nó thành mã máy nhị phân (0001 1110), rồi các byte đó được đặt sẵn vào RAM trước khi CPU chạy. Đó gọi là “nạp chương trình”. Bạn có thể tự làm điều này trong khu “Tự viết chương trình” và bấm “Nạp vào CPU”.

Nhãn (label) như lap: hoạt động thế nào?

Nhãn chỉ là một cái tên thay cho số địa chỉ, để bạn khỏi phải đếm thủ công. Khi dịch, JMP lap được đổi thành JMP tới đúng ô mà nhãn lap: đứng. Hãy để ý ở khu dịch: nhãn biến mất, chỉ còn lại con số địa chỉ.

“Một bước” và “Chạy” khác nhau ra sao?

“Một bước” chạy đúng một nhịp xung rồi dừng — để quan sát thật chậm. “Chạy” là xung nhịp tự động lặp lại, tốc độ chỉnh bằng thanh trượt (giống như đổi “GHz” của CPU). Muốn hiểu kỹ về xung nhịp, xem trang Xung nhịp & Thạch anh.

Nhật ký thực thi để làm gì?

Mỗi nhịp được ghi lại một dòng giải thích. Nhấn vào một dòng cũ để “tua lại” — toàn bộ bảng mạch quay về đúng trạng thái lúc đó, xem khối nào sáng. Rất hữu ích khi giáo viên muốn giảng lại một bước mà học sinh chưa hiểu.

Bài tập về nhà

6 bài để chắc chắn em hiểu sâu CPU chạy mã lệnh thế nào. Với các bài “viết chương trình”, hãy gõ vào ô “Tự viết chương trình” ở trên, bấm “Nạp vào CPU” rồi chạy thử. Mỗi bài có mục “✅ Hoàn thành khi” nêu rõ kết quả đúng; mở “Đáp án” chỉ sau khi đã tự làm.

1

Đọc chương trình

Cơ bản

Chương trình sau in ra số mấy ở “Đèn kết quả”?

LDI 6
OUT
HLT

✅ Hoàn thành khi: trả lời 6LDI 6 nạp thẳng số 6 vào thanh ghi A, OUT đưa A ra đèn.

2

Chạy nhẩm (dự đoán)

Vận dụng

Giả sử ô nhớ 14 chứa số 7 và ô 15 chứa số 5. Hãy chạy nhẩm chương trình: sau mỗi lệnh, thanh ghi A bằng bao nhiêu? Đèn kết quả hiện số mấy?

LDA 14
ADD 15
OUT
HLT

Muốn tự kiểm tra: gõ thêm ORG 14, DAT 7, DAT 5 vào cuối rồi nạp vào CPU.

✅ Hoàn thành khi: sau LDA 14 → A = 7; sau ADD 15 → A = 12; đèn hiện 12.

3

Viết: tính 9 − 4

Vận dụng

Viết một chương trình tính 9 − 4 rồi hiện kết quả ra đèn. Gợi ý: đặt số 4 vào một ô nhớ bằng ORG + DAT, dùng LDI 9 rồi SUB ô đó.

✅ Hoàn thành khi: bấm “Nạp vào CPU” không báo lỗi, chạy đến khi dừng, đèn hiện 5.

Đáp án mẫu
LDI 9
SUB 15     ; A ← A − ô 15 (= 4)
OUT
HLT
ORG 15
DAT 4
4

Viết: tính 3 + 4 + 5

Vận dụng

Viết chương trình tính tổng 3 + 4 + 5 và hiện kết quả. Gợi ý: bắt đầu bằng LDI 3, rồi ADD hai ô chứa 4 và 5.

✅ Hoàn thành khi: chạy đến khi dừng, đèn hiện 12.

Đáp án mẫu
LDI 3
ADD 14     ; + 4
ADD 15     ; + 5
OUT
HLT
ORG 14
DAT 4
DAT 5
5

Tìm lỗi

Nâng cao

Chương trình sau đáng lẽ hiện 8 (5 + 3) rồi dừng, nhưng nó chạy mãi không dừng. Tìm lỗi và sửa.

LDI 5
ADD 15
OUT
ORG 15
DAT 3

✅ Hoàn thành khi: thêm HLT ngay sau OUT; nạp lại → đèn hiện 8 và CPU dừng hẳn (không chạy lan vào vùng dữ liệu).

Đáp án
LDI 5
ADD 15
OUT
HLT        ; ← dòng còn thiếu
ORG 15
DAT 3

Thiếu HLT: sau khi OUT xong, PC đi tiếp và đọc ô dữ liệu như thể đó là lệnh → hành vi sai / chạy không dừng.

6

Giới hạn phần cứng

Nâng cao

(a) Nếu thanh ghi A đang là 200 mà em cộng thêm 100 thì điều gì xảy ra? Vì sao? (b) Vì sao không thể viết phép nhân tổng quát bằng vòng lặp mà gói gọn trong 16 ô nhớ?

✅ Hoàn thành khi: (a) nêu được 200 + 100 = 300 > 255 → máy báo TRÀN SỐdừng, cờ CARRY bật, vì thanh ghi 8-bit chỉ chứa được 0–255. (b) nhân-bằng-vòng-lặp cần khoảng 13 lệnh + vài ô dữ liệu → vượt quá 16 ô; hơn nữa chỉ có JZ (nhảy khi bằng 0), không có lệnh nhảy theo dấu/nhớ nên khó điều khiển vòng đếm. Đây là giới hạn thật của phần cứng nhỏ, không phải lỗi.