Như đã trình bày ở các phần trước, các thanh ghi đoạn và thanh ghi độ lệch được đi cặp với nhau để xác định địa chỉ của ô nhớ. Do đó ta chỉ cần viết thanh ghi độ lệch là đủ cơ sở để tính địa chỉ của ô nhớ trong lệnh.
Bảng 2.4: Các cặp thanh ghi đoạn và thanh ghi độ lệch ngầm định Thanh ghi đoạn Thanh ghi độ lệch Địa chỉ ô nhớ
CS IP [IP]
DS
BX SI DI
[BX]
[SI]
[DI]
ES DI [DI]
SS SP
BP
[SP]
[BP]
Bảng 2.4 trình bày các cặp thanh ghi đoạn và thanh ghi độ lệnh đã được ngầm định. Tuy nhiên, ngoài các tổ hợp ngầm định đã nêu trên bảng 2.4, đôi khi vi xử lý 8088/8086 còn cho phép ta làm việc với các tổ hợp khác của các thanh ghi đoạn và thanh ghi độ lệch. Muốn loại bỏ các tổ hợp ngầm định nói trên, khi viết lệnh ta phải ghi rõ thanh ghi đoạn sẽ dùng để tính địa chỉ và kèm thêm dấu 2 chấm trước thanh ghi độ lệch.
36 Ví dụ:
Trường hợp ngầm định thanh ghi đoạn:
MOV AL, [BX] ; Chuyển nội dung ô nhớ có địa chỉ DS : BX vào AL Trong trường hợp này nội dung ô nhớ có địa chỉ độ lệch cất trong BX còn địa chỉ đoạn đã được ngầm định cất trong thanh ghi DS.
Trường hợp bỏ ngầm định thanh ghi đoạn:
MOV AL, ES : [BX] ; Chuyển nội dung ô nhớ có địa chỉ ES : BX vào AL Trong trường hợp này nội dung ô nhớ có địa chỉ độ lệch cất trong BX còn địa chỉ đoạn đã được bỏ ngầm định và chỉ rõ trong lệnh là thanh ghi ES.
III. CÁCH MÃ HÓA LỆNH CỦA BỘ VI XỬ LÍ 8088
Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6
Mã lệnh Trợ giúp Dữ liệu Dữ liệu Dữ liệu Dữ liệu
Hình 2.3: Dạng tổng quát lệnh của vi xử lý 8088
Một lệnh của vi xử lý 8088/8086 có độ dài từ 1 đến 5 byte tùy theo mỗi lệnh, nhưng được đánh số từ 1 đến 6 byte (sẽ giải thích ở phần tiếp theo). Ý nghĩa của các byte lệnh cho trên hình 2.3.
Byte 1: Mã lệnh
Thường nằm ở byte đầu tiên của lệnh, cho ta biết thao tác của lệnh.
Byte 2: Trợ giúp
Có thể có hoặc không có. Byte này giúp cho mã lệnh xác định toán hạng trong những trường hợp mã lệnh không tìm thấy toán hạng.
Byte 3 ~ 6: Dữ liệu
Tùy thuộc vào từng lệnh cụ thể mà ta biết sử dụng bao nhiêu byte trong tổng số 4 byte này.
Để hiểu được cách mã hóa lệnh ta tìm hiểu cách mã hóa lệnh đặc trưng của lệnh MOV. Tuy nhiên ta chỉ xét trong trường hợp các toán hạng của lệnh là các thanh ghi dữ liệu (không phải là thanh ghi đoạn) và ô nhớ.
37
Hình 2.4 biểu diễn dạng thức các byte để mã hóa cho lệnh MOV.
Byte 1 Byte 2 Byte 3 Byte 4
1 0 0 0 1 0 OPCODE D W MOD REG M/R Địa chỉ trực tiếp
phần thấp
Địa chỉ trực tiếp phần cao Hoặc
Giá trị dịch chuyển phần thấp
Giá trị dịch chuyển phần cao Hình 2.4: Dạng thức byte mã lệnh của lệnh MOV
Byte 1: Byte này bao gồm
OPCODE: operation code - Mã lệnh. Đối với lệnh MOV mã lệnh luôn là 100010.
D: Direction - Hướng đi của dữ liệu.
D = 0 dữ liệu đi từ thanh ghi cho bởi 3 bit của bảng mã thanh ghi (REG), xem bảng 2.5.
D = 1 dữ liệu đi từ thanh ghi cho bởi 3 bit của bảng mã thanh ghi (REG), xem bảng 2.5.
Bảng 2.5: Bảng mã thanh ghi
Thanh ghi (REG) Mã
(Code)
W = 0 W = 1
AL AX 000
CL CX 001
DL DX 010
BL BX 011
AH SP 100
CH BP 101
DH SI 110
BH DI 111
W: Word - Từ nhớ.
W = 0 dữ liệu 8 bit W = 1 dữ liệu 16 bit Byte 2: Byte này bao gồm
MOD: mode - Chế độ địa chỉ cho trong bảng 2.6
REG: register - thanh ghi cho trong bảng 2.5
M/R: memory or register - thanh ghi hay ô nhớ cho trong bảng 2.6
38
Bảng 2.6: Mã hóa các chế độ địa chỉ
MOD 00 01 10
11 W=?
R/M 0 1
000 [BX] + [SI] [BX] + [SI] + d8 [BX] + [SI] + d16 AX AL 001 [BX] + [DI] [BX] + [DI] + d8 [BX] + [DI] + d16 CX CL 010 [BP] + [SI] [BP] + [SI] + d8 [BP] + [SI] + d16 DX DL 011 [BP] + [DI] [BP] + [DI] + d8 [BP] + [DI] + d16 BX BL
100 [SI] [SI] + d8 [SI] + d16 SP AH
101 [DI] [DI] + d8 [DI] + d16 BP CH
110 Địa chỉ trực
tiếp 16 bit [BP] + d8 [BP] + d16 SI DH
111 [BX] [BX] + d8 [BX] + d16 DI BH
Byte 3 và Byte 4:
Sử dụng trong những trường hợp có cộng thêm giá trị dịch chuyển 8 bit, 16 bit hoặc trường hợp địa chỉ trực tiếp 16 bit. Khi đó 8 bit thấp (giá trị dịch chuyển hoặc địa chỉ trực tiếp) được điền vào byte 3 và 8 bit cao được điền vào byte 4 tùy thuộc từng lệnh cụ thể.
Chú ý:
Giá trị dịch chuyển - displacement được ký hiệu bằng chữ cái d. Nếu giá trị dịch chuyển là 8 bit ta sẽ có ký hiệu d8, nếu là 16 bit ta sẽ có ký hiệu d16.
Ví dụ: Mã hóa lệnh MOV cho các trường hợp sau:
1. MOV [BX] , AL;
2. MOV DL, 3F4Ch + [DI]
Giải:
1. MOV [BX] , AL
Ở ví dụ này nội dung dữ liệu trong thanh ghi AL sẽ được chuyển vào cất trong ô nhớ có địa chỉ độ lệch trong thanh ghi BX và địa chỉ đoạn đã được ngầm định trong thanh ghi DS.
Dữ liệu đi từ thanh ghi AL nên bit D = 0;
Dữ liệu 8 bit nên W = 0
Thanh ghi AL có mã REG = 000; - Mod = 00 là chế độ địa chỉ gián tiếp qua thanh ghi ;
M/R = 111 vì là ô nhớ [BX]
39
2. MOV DL, 4Ch + [DI]
Ví dụ này có thêm giá trị dịch chuyển 8 bit nên chỉ cần thêm byte 3 cho giá trị dịch chuyển 8 bit (phần thấp, phần cao coi như bằng 0). Byte 4 không sử dụng.
IV. TẬP LỆNH CỦA BỘ VI XỬ LÍ 8088
Vi xử lý 8088 có xấp xỉ khoảng 120 lệnh. Cấu trúc của 1 lệnh bao gồm 2 trường thông tin chính là:
Mã lệnh: thường nằm ở byte đầu tiên của lệnh, cho ta biết thao tác của lệnh.
Toán hạng: là nơi mà các toán hạng sẽ tác động vào hoặc là nơi chứa kết quả.
Trong một lệnh có thể có một toán hạng, hai toán hạng hoặc không có toán hạng nào cả. Nếu lệnh có hai toán hạng thì một toán hạng sẽ là toán hạng đích và toán hạng còn lại là toán hạng nguồn. Giữa hai toán hạng này phải cách nhau bởi dấu phẩy phân cách.
Để mô tả tập lệnh, vi xử lý sử dụng các từ gợi nhớ. Ví dụ như: ADD, MOV, SUB, MUL, IMUL, DIV, IDIV, AND, OR, NOT, v..v.
Trong một lệnh toán hạng có thể là:
Thanh ghi: Nếu toán hạng là thanh ghi phải cho biết tên của thanh ghi.
1 0 0 0 1 0 1 0 1 0 0 1 0 1 0 1 0 1 0 0 1 1 0 0
OPCODE Đi đến th.ghi DL nên D = 0
Dữ liệu 8 bit nên W = 0
Mod = 10 (bảng 2.6)
REG = 010 (bảng 2.5)
M/R = 101 (bảng 2.6)
Giá trị dịch chuyển phần thấp
1 0 0 0 1 0 0 0 0 0 0 0 0 1 1 1
OPCODE Đi từ thanh ghi AL
Dữ liệu 8 bit nên W = 0
Mod = 00 (bảng 2.6)
REG = 000 (bảng 2.5)
M/R = 111 (bảng 2.6)
40
Ô nhớ: Nếu toán hạng là ô nhớ phải cho biết địa chỉ của ô nhớ.
Biến: Nếu toán hạng là biến thì bắt buộc phải khai báo biến để bộ nhớ chương trình dành cho biến một khoảng nhớ nhất định theo kiểu của biến.
Tên biến khi dịch ra mã máy cũng chính là địa chỉ của ô nhớ.
Hằng số: Nếu toán hạng là hằng số thì chỉ đóng vai trò là toán hạng nguồn trong những lệnh có hai toán hạng.
Tập lệnh của vi xử lý 8088 được chia ra thành các nhóm lệnh sau:
Nhóm lệnh dịch chuyển dữ liệu.
Nhóm lệnh số học và logic.
Nhóm lệnh có cấu trúc điều khiển chương trình.