← Máy tính hoạt động thế nào?

Bài 3 · Vận dụng · 18 phút· Cập nhật 11/06/2026

Hệ nhị phân

Biên soạn bởi Nguyễn Anh Tuấn

Hệ nhị phân (binary), bát phân, thập lục phân (hex) - cách máy & người viết cùng một con số; đổi qua lại rồi nạp vào RAM cho CPU chạy.

Ở tầng thấp nhất, máy tính không “hiểu” chữ số 7 hay chữ A. Nó chỉ có hàng tỉ công tắc tí hon (transistor) ở một trong hai trạng thái: bật/tắt, tương ứng điện áp cao/thấp - đúng kiểu xung nhịp lên/xuống ở Bài 1. Mỗi công tắc lưu một bit: 0 hoặc 1.

Ghép nhiều bit lại, ta đếm được mọi con số - giống như hệ thập phân ghép các chữ số 0-9, chỉ khác là ở đây mỗi cột chỉ có hai lựa chọn. Đó là hệ nhị phân (binary) - hệ cơ số 2.

  • Bit = đơn vị nhỏ nhất: 0 hoặc 1.
  • 8 bit = 1 byte - vừa đủ một ô nhớ trong mô hình CPU.
  • Máy dùng nhị phân vì công tắc chỉ có hai trạng thái - dễ làm, chống nhiễu.

Trong hệ thập phân, “235” = 2×100 + 3×10 + 5×1 - mỗi cột là một luỹ thừa của 10. Nhị phân y hệt, chỉ là luỹ thừa của 2: các cột có giá trị 128 64 32 16 8 4 2 1. Một số nhị phân = tổng các giá trị vị trí đang bật. Bật/tắt thử từng bit:

128064032016081412011bật: 8 + 4 + 1 = 13mỗi bit "bật" thì cộng giá trị vị trí của nó
Mỗi bit là một “bóng đèn” mang giá trị vị trí; bật bit nào thì cộng giá trị đó. Đây là 13.
Nhị phân: 0000 1101 Hex: 0x0D Thập phân: 13

Mỗi ô là một bit; số phía trên là giá trị vị trí (luỹ thừa của 2). Số = tổng các vị trí đang bật. Bấm vào ô để bật/tắt, hoặc kéo thanh trượt.

Đọc nhanh

1011 0010 = 128 + 32 + 16 + 2 = 178. Cứ cộng giá trị các cột có bit 1 là xong - không cần học thuộc gì cả.

Chiều ngược lại có một mẹo gọn: chia liên tiếp cho 2, ghi lại số dư mỗi lần (0 hoặc 1), tới khi thương bằng 0. Đọc các số dư từ dưới lên ra dãy nhị phân.

Ví dụ: 13 → nhị phân

13 ÷ 2 = 6 dư 1
6 ÷ 2 = 3 dư 0
3 ÷ 2 = 1 dư 1
1 ÷ 2 = 0 dư 1

Đọc ngược: 1101 → tức 0000 1101 (8-bit). Thử lại bằng công cụ Bước 2 với số 13.
  • Thập phân → nhị phân: chia 2 lấy dư, đọc ngược.
  • Nhị phân → thập phân: cộng các giá trị vị trí đang bật.
  • Hai chiều luôn khớp nhau - chỉ là hai cách viết của cùng một con số.

Mọi hệ đếm đều có một cơ số (base) - số chữ số dùng cho mỗi cột. Thập phân cơ số 10 (0-9), nhị phân cơ số 2 (0-1). Hai hệ nữa rất hay gặp khi làm việc với máy: bát phân (cơ số 8) và thập lục phân (cơ số 16). Cùng một con số, bốn cách viết - kéo thử:

Hệ đếmCơ sốChữ số dùngGiá trị
Nhị phân20–10010 1010
Bát phân80–752
Thập phân100–942
Thập lục phân160–9, A–F2A

Cùng một con số, bốn cách viết. Kéo thanh trượt để thấy cả bốn hệ đổi cùng lúc - chỉ khác nhau ở cơ số (mỗi cột đáng giá bao nhiêu).

  • Bát phân (cơ số 8): mỗi chữ số 0-7 = đúng 3 bit. Gặp ở quyền tệp Unix, vd chmod 755.
  • Thập lục phân (cơ số 16): mỗi chữ số 0-9, A-F = đúng 4 bit (1 nibble). 1 byte = 2 chữ hex.
  • Hex hợp với byte hơn bát phân: 8 chia hết cho 4 (byte = 2 hex) nhưng không chia hết cho 3.

Bảng quy đổi 0-16 - để ý bát phân “nhảy bậc” ở 8, thập lục phân ở 16:

Thập phânNhị phânBát phânHex
00000000
10000111
20001022
30001133
40010044
50010155
60011066
70011177
801000108
901001119
100101012A
110101113B
120110014C
130110115D
140111016E
150111117F
16100002010

Vì sao 8 và 16 “đẹp” với máy, còn 10 thì không?

Vì 8 = 2³ và 16 = 2⁴ đều là luỹ thừa của 2 - mỗi chữ số bát phân/thập lục phân ứng đúng một nhóm 3/4 bit, gom nhóm là xong, đổi qua lại tức thì. Còn 10 không phải luỹ thừa của 2, nên thập phân ↔ nhị phân phải tính toán (chia 2 lấy dư) chứ không gom nhóm được.

Mỗi ô nhớ trong mô hình CPU giữ đúng một byte = 8 bit. Cùng một byte có thể là dữ liệu (một con số 0-255) hoặc là lệnh. Khi là lệnh, CPU tách byte làm hai nửa: nibble cao = opcode (làm gì) và nibble thấp = toán hạng (với ô nhớ nào). Kéo thử:

nibble cao → opcode (làm gì)
0010
= 2 = 0x2
nibble thấp → toán hạng (ô nào)
1110
= 14 = 0xE
Byte: 0x2E Thập phân: 46 CPU đọc thành lệnh: ADD 14

Cùng một byte 8 bit: nửa trái cho CPU biết làm gì (opcode), nửa phải cho biết với ô nhớ nào (toán hạng). Đây đúng là mã máy ở bài “Mô hình CPU 8-bit”.

Cùng dãy bit, hai cách hiểu

0x2E là số 46 nếu coi là dữ liệu, nhưng là lệnh ADD 14 nếu CPU coi nó là mã lệnh. Cái quyết định là con trỏ lệnh (PC) đang chỉ vào đâu - không có phép màu nào cả.

Khi bạn bấm “Chạy” trong mô hình CPU, đây là vòng đời của các bit:

  • 1. NẠP: chương trình của bạn được dịch sang các byte nhị phân, xếp vào RAM.
  • 2. ĐỌC LỆNH (fetch): CPU lấy byte mà PC trỏ tới - một dãy 8 bit.
  • 3. GIẢI MÃ (decode): tách opcode + toán hạng từ hai nibble.
  • 4. THỰC THI (execute): ALU (bộ cộng ở Bài 2) tính, kết quả là 8 bit mới trong thanh ghi A.
  • 5. TRẢ KẾT QUẢ: lệnh OUT đổi 8 bit trong A ngược lại thành số thập phân để con người đọc.

Khép vòng tròn

Từ đầu đến cuối chỉ là bit bật/tắt: từ con số thập phân bạn gõ → nhị phân trong RAM → cổng logic xử lý → nhị phân kết quả → đổi lại thành thập phân để hiển thị. Tới Bài 6 - Mô hình CPU 8-bit - cho bạn xem tận mắt từng bước này chạy trên bảng mạch.

Câu hỏi thường gặp

Vì linh kiện điện tử (transistor) chỉ có hai trạng thái ổn định và dễ phân biệt: bật/tắt, điện áp cao/thấp - đúng như xung nhịp ở Bài 1. Hai mức thì chống nhiễu rất tốt. Nếu phải phân biệt 10 mức điện áp cho hệ thập phân, mạch sẽ rất dễ đọc sai.

Hex là để CHO CON NGƯỜI đọc cho gọn. Mỗi chữ hex ứng với đúng 4 bit, nên 1 byte = 2 chữ hex. Viết 0xFA dễ hơn nhiều so với 1111 1010, mà vẫn dịch ngược lại được chính xác. Bên trong, máy vẫn chạy thuần nhị phân.

Bát phân (cơ số 8) gom mỗi 3 bit thành một chữ số 0-7. Thời máy tính cũ nó rất phổ biến; nay vẫn hay gặp ở quyền truy cập tệp Unix/Linux - vd “chmod 755” chính là ba nhóm 3 bit (rwx cho chủ/nhóm/người khác). Với byte 8 bit thì hex tiện hơn vì 8 chia hết cho 4 (byte = 2 chữ hex), còn 8 không chia hết cho 3 nên byte ra 3 chữ bát phân hơi “lẻ”.

2⁸ = 256 giá trị, từ 0 đến 255. Đó cũng chính là lý do thanh ghi A trong mô hình CPU chỉ giữ được 0-255, và cộng quá 255 thì “Tràn số”.

Bản thân byte không “tự biết” - cùng một dãy bit có thể là lệnh hoặc số. CPU coi byte mà con trỏ lệnh (PC) đang trỏ tới là LỆNH, còn các ô khác là DỮ LIỆU. Nếu sắp xếp sai, CPU sẽ “thực thi nhầm dữ liệu” - bạn sẽ thấy rõ điều này ở bài Mô hình CPU 8-bit.

Số âm dùng “số bù hai” - đã học ở Bài Cổng logic & Bộ cộng. Số lẻ (vd 3,14) dùng dấu phẩy động (floating-point), nằm ngoài phạm vi mô hình 8-bit này nhưng cũng chỉ là một quy ước sắp xếp bit khác.

Bài Cổng logic & Bộ cộng - số bù hai →

Vì lần chia đầu tiên cho ra bit thấp nhất (hàng đơn vị), còn lần chia cuối cho ra bit cao nhất. Đọc các số dư từ dưới lên chính là xếp từ bit cao xuống bit thấp.

Tick những điều em tự tin làm được. Càng lên cao, em càng hiểu sâu.

Tick những điều em tự tin làm được sau khi học bài này. 0/6

Trả lời vài câu để chắc rằng em đã nắm bài.

Câu 1/3 Điểm: 0

Vì sao máy tính dùng hệ nhị phân thay vì hệ thập phân?

  1. 1

    Thập phân → nhị phân

    Dùng cách “chia 2 lấy dư” để đổi số 13 sang nhị phân. Viết lại các số dư và kết quả 8-bit.

    Hoàn thành khi: 13 = 1101; viết đủ 8 bit là 0000 1101. Kiểm tra bằng công cụ ở Bước 2 (đặt số = 13).

  2. 2

    Nhị phân → thập phân

    Đọc số nhị phân 1011 0010 sang thập phân bằng cách cộng các giá trị vị trí đang bật.

    Hoàn thành khi: 128 + 32 + 16 + 2 = 178.

  3. 3

    Một byte → hex

    Đổi 1111 1010 sang hệ thập lục phân. Tách thành hai nibble trước.

    Hoàn thành khi: 1111 = F, 1010 = A → 0xFA.

  4. 4

    Một byte → bát phân

    Đổi 1111 1010 sang bát phân bằng cách gom 3 bit từ phải sang trái.

    Hoàn thành khi: 11 111 010 → 3 7 2 → 372₈ (= 250 = 0xFA). Đối chiếu bằng công cụ ở Bước 4.

  5. 5

    Một số, bốn hệ đếm

    Viết số 42 ở cả bốn hệ: nhị phân, bát phân, thập phân, thập lục phân.

    Hoàn thành khi: 0010 1010 (nhị phân) · 52 (bát phân) · 42 (thập phân) · 2A (hex).

  6. 6

    Hex → nhị phân → lệnh CPU

    Đổi 0x2E sang nhị phân, rồi tách opcode/toán hạng. Đây là lệnh CPU gì?

    Hoàn thành khi: 0x2E = 0010 1110; opcode 2 = ADD, toán hạng 14 → “ADD 14”. Đối chiếu bằng công cụ ở Bước 5.

  7. 7

    Số lớn nhất của 1 byte

    Số lớn nhất biểu diễn được bằng 8 bit là bao nhiêu? Viết ở cả ba hệ và giải thích vì sao.

    Hoàn thành khi: 1111 1111 = 0xFF = 255 = 2⁸ − 1 (8 bit có 256 tổ hợp: 0…255).

  8. 8

    Tự mã hoá một lệnh

    Mã hoá lệnh “LDI 7” (nạp thẳng số 7) thành một byte. Cho biết nhị phân và hex. (Gợi ý: tra opcode LDI ở bài CPU.)

    Hoàn thành khi: LDI = opcode 5, toán hạng 7 → 0101 0111 = 0x57 = 87.