Professional Documents
Culture Documents
Là các phần tử nhớ đặc biệt bên trong bộ vi xử lý. các thanh ghi luôn có kích thước
bằng nhau, kích thước này cũng chính là độ rộng của data bus bên trong bộ xử lý.
8088 là bộ vi xử lý 16 bit do đó các thanh ghi của 8088 đều có kích thước 16 bit.
Một số tác vụ đặc biệt như nhân hay chia, kết quả bắt buộc phải đặt trong thanh ghi
Một số thanh ghi chỉ dùng để xác định địa chỉ cho bộ xử lý
Các tác vụ trên thanh ghi nhanh hơn nhiều so với các tác vụ trên bộ nhớ
Bộ vi xử lý 8088 có 14 thanh ghi 16 bit chia thành nhóm theo chức năng như sau:
Nhóm thanh ghi chỉ mục và con trỏ (Index & Pointer registers):
F E D C B A 9 8 7 6 5 4 3 2 1 0
SI SI
DI DI
BP BP
SP SP
3.1.2 Nhóm thanh ghi chỉ mục và con trỏ (Index & Pointer registers):
SI,DI,BP,SP
Có thể sử dụng như các thanh ghi đa dụng, ngoài ra còn đóng vai trò làm chỉ
mục khi xác dịnh địa chỉ theo offset của bộ xử lý.
- SI và DI là hai thanh ghi chỉ mục để thực hiện các tác vụ chuỗi
- BP và SP là hai thanh ghi con trỏ để thao tác trên cấu trúc STACK
DS,ES,SS,CS
Không thể tham gia vào các tác vụ tính toán, thường chỉ dùng để xác định các
địa chỉ phân đoạn.
IP
Không thể tham gia vào các tác vụ tính toán, không thể gán giá trị trực tiếp,
cùng với CS tạo thành địa chỉ mã lệnh sẽ thực hiện của CPU
Flag
Không thể tham gia vào các tác vụ tính toán, không thể gán giá trị trực tiếp,
chỉ dùng để ghi nhận hoặc chỉ định các trạng thái làm việc của CPU.
Các lệnh của bộ xử lý thao tác trực tiếp lên các đối tượng chủ yếu là thanh ghi và bộ
nhớ . Các thanh ghi dược xác định bằng tên , các phần tử thuộc bộ nhớ được xác định
bằng địa chỉ. Các bộ xử lý thuộc dòng họ x86 xác định địa chỉ bằng hai giá trị 16 bit
gọi là segment và offset. Địa chỉ vật lý tương ứng được tính theo công thức :
Memory_Address = Segment * 10h + Offset
20 bit 16 bit 16 bit
Một địa chỉ vật lý có thể biểu diễn thành nhiều cặp segment và offset khác nhau.
Thí dụ: 0040:006C 0000:046C 0020:026C
là các biểu diễn của dịa chỉ vật lý 20 bit 00046C.
3.2.1 Segment:
Segment là một đoạn bộ nhớ có kích thước tối đa 64KB (16 bit offset) và có
thể bắt đầu tại các địa chỉ chia chẵn cho 16 (10h) trên toàn bộ vùng nhớ 1MB
(20 bit).
Trong hầu hết các tác vụ của bộ xử lý 8088, segment dược xác định gián tiếp
qua các thanh ghi segment DS , ES , SS , CS . Khi cần sử dụng segment nào ,
phải gán giá trị tương ứng cho các thanh ghi segment . Lúc đó các địa chỉ
được thể hiện thành dạng Segment:offset
Thí dụ: CS:Offset , DS:Offset
3.2.2 Offset:
Offset là một cự ly (16 bit) so với điểm đầu của một segment.
Các cách mô tả offset:
[Const] , [BX] , [BP] , [SI] , [DI]
[BX+Const] , [BP+Const] , [SI+Const] , [DI+Const]
[BX+SI+Const] , [BX+DI+Const] , [BP+SI+Const] , [BP+DI+Const]
* Nhận xét: Offset có thể mô tả bằng một tổng của : Hằng số 16 bit và các
thanh ghi chỉ mục BX, BP, SI, DI . Trong đó các cặp BX và BP , SI và DI
không được phép cùng xuất hiện
Các lệnh của bộ vi xử lý 8088 dưới đây sẽ được mô tả theo dạng thức:
Tên_Lệnh [Đích [, Nguồn]]
Đích (Dest) có thể là tên một thanh ghi (Reg) , một địa chỉ trong bộ nhớ (Mem), một
vị trí trong chương trình (Label)
Nguồn (Src) có thể là tên một thanh ghi (Reg) , một địa chỉ trong bộ nhớ (Mem), một
hằng số (Const)
Đích và Nguồn không đồng thời là hai địa chỉ trong bộ nhớ (Mem)
3.3.1 Lệnh MOVE
MOVE <Dest>,<Src>
XCHG <Dest>,<Src>
Không thể XCHG giữa các thanh ghi segment với nhau.
INC <Dest>
Lấy Dest cộng với 1 rồi gán kết quả vào Dest
ADD <Dest>,<Src>
Lấy Dest cộng với Src rồi gán kết quả vào Dest
ADC <Dest>,<Src>
Lấy Dest cộng với Src và cộng thêm 1 nếu CF=1 rồi gán kết quả vào Dest
DEC <Dest>
Lấy Dest trừ đi 1 rồi gán kết quả vào Dest
SUB <Dest>,<Src>
Lấy Dest trừ đi Src rồi gán kết quả vào Dest
SBB <Dest>,<Src>
Lấy Dest trừ đi Src và trừ tiếp 1 nếu CF=1 rồi gán kết quả vào Dest
3.3.5 Lệnh MUL
MUL <Reg_8bit/Mem_8bit>
MUL <Reg_16bit/Mem_16bit>
DIV <Reg_8bit/Mem_8bit>
DIV <Reg_16bit/Mem_16bit>
Giống MUL và DIV, nhưng thực hiện trên các giá trị có dấu và cho ra kết quả
có dấu
ADD <Dest>,<Src>
OR <Dest>,<Src>
XOR <Dest>,<Src>
Lấy Dest AND/OR/XOR với Src rồi gán kết quả vào Dest
NOT <Dest>
SHL/SHR <Reg/Mem>,1
Đẩy các bit của thanh ghi sang trái (SHL)hoặc sang phải(SHR) 1 cột
(Nhân/Chia với 2)
SHL/SHR <Reg/Mem>,CL
Đẩy các bit của thanh ghi sang trái (SHL) hoặc sang phải (SHR) n cột, với n là
giá trị chứ a trong CL (Nhân/Chia với 2n )
Kết thúc lệnh , cờ hiệu CF chứa bit cuối cùng lọt ra ngoài.
RCL/RCR <Reg/Mem>,1
Quay các bit của thanh ghi và CF sang trái hoặc sang phải 1 cột
RCL/RCR <Reg/Mem>,CL
Quay các bit của thanh ghi và CF sang trái hoặc sang phải n cột, với n là giá
trị chứ a trong CL
ROL/ROR <Reg/Mem>,1
Quay các bit của thanh ghi sang trái (ROL) hoặc sang phải (ROR) 1 cột
ROL/ROR <Reg/Mem>,CL
Quay các bit của thanh ghi sang trái (ROL) hoặc sang phải (ROR) n cột, với n
là giá trị chứ a trong CL
JMP <Label>
CPU chuyển đến thực hiện lệnh tại <Label>.
CMP <Dest>,<Src>
Thực hiện phép trừ Dest cho Src, kết quả không được giữ lại, các cờ hiệu bị
thay đổi.
Test <Dest>,<Src>
Thực hiện phép AND Dest với Src, kết quả không được giữ lại, các cờ hiệu
bị thay đổi.
Hai tác vụ này được phối hợp cùng với các lệnh chuyển điều khiển theo điều
kiện.
Lệnh chuyển điều khiển theo điều kiện có dạng thức chung như sau :
<Jump_command> <Label>
<Label> là một tên nhãn đánh dấu một vị trí trong chương trình. Khi điều
kiện kiểm tra là đúng, CPU sẽ chuyển đến thực hiện lệnh tại vị trí <Label> ,
nếu điều kiện kiểm tra là sai CPU sẽ thực hiện lệnh kế tiếp
Lệnh chuyển điều khiển theo điều kiện so sánh
Số không dấu Số có dấu So
sánh
JA JG >
JAE , JNB JGE , JNL >=
JE , JZ JE , JZ =
JBE , JNA JLE , JNG <=
JB JL <
JNE , JNZ JNE , JNZ <>
Lệnh chuyển điều khiển theo cờ hiệu Lệnh làm thay đổi cờ hiệu trực tiếp
Lệnh Điều kiện Lệnh Điều kiện
JC CF = 1 STC CF = 1
JNC CF = 0 CLC CF = 0
JZ ZF = 1 STD DF = 1
JNZ ZF = 0 CLD DF = 0
JO OF = 1 STI IF = 1
JNO OF = 0 CLI IF = 0
JP PF = 1
JNP PF = 0
JS SF = 0
JNS SF = 0
JNS SF = 0
JCXZ CX = 0
Các lệnh chuyển điều khiển theo điều kiện thường đi theo sau lệnh CMP
Các lệnh chuyển điều khiển không làm thay đổi giá trị của các cờ hiệu.
LOOP <Label>
<Label> là một tên nhãn đánh dấu một vị trí trong chương trình.
Đoạn lệnh tương đương:
SUB CX,1
CMP CX,0
JNE <Label>
Mỗi lần thực hiện LOOP , CX giảm đi 1 , sau đó nếu CX=0 CPU sẽ thực hiện
lệnh tiếp theo , nếu CX>0 CPU sẽ chuyển đến thực hiện lệnh tại <Label>.
Nên dùng LOOP khi cần phải thực hiện các chu trình có số lần lặp đã biết
trước.
3.5 Viết chương trình với Assembler 86
3.5.1 Thí dụ 1
Code segment
assume cs,ds,es:code
org 0100h
Code ends
end Main
Có thể viết các chương trình đầu tiên bằng cách dùng thí dụ 1 làm mẫu, chỉ cần thay thế
các các dòng lệnh màu xanh bằng phần chương trình của mình
3.5.2 Thí dụ 2
Code segment
assume cs,ds,es:code
org 0100h
Code ends
end Main
3.5.3 Khai báo và sử dụng bộ nhớ:
Chương trình viết cho bộ vi xử lý 8088 là một tập hợp các byte vừa mã lệnh
vừa dữ liệu. Người viết chương trình phải tự tổ chức và sắp xếp để khi chương
trình được thực hiện bộ vi xử lý không nhầm lẫn giữa dữ liệu và mã lệnh.
Ta có thể khai báo một vùng nhớ trong chương trình dùng để lưu trữ dữ liệu
bằng các dòng lệnh như sau:
Khai báo kiểu dữ liệu (db,dw,dd ) mô tả các ô nhớ và giá trị được gán trong
chương trình. Số lượng các ô nhớ được xác định bằng số lượng các giá trị
được liệt kê ngay sau khai báo kiểu dữ liệu.
Kiểu dữ liệu db ấn định mỗi phần tử dữ liệu có kích thước 1 byte
Kiểu dữ liệu dw ấn định mỗi phần tử dữ liệu có kích thước 2 byte
Kiểu dữ liệu dd ấn định mỗi phần tử dữ liệu có kích thước 4 byte
Để có thể sử dụng được các vùng dữ liệu đã khai báo trong chương trình,
người ta “đánh dấu” các vị trí đó bằng cách đặt các nhãn ngay trước khai báo
kiểu:
chuoi db 'chao'
tongso db 0
dayso db 5,6,7,8
Sau đó có thể khai thác các vùng nhớ này như sau:
Gán địa chỉ (offset) của chuoi vào thanh ghi dx:
mov dx, offset chuoi
hoặc
lea dx, chuoi
Gán giá trị đang lưu tại ô nhớ tongso (1 byte) vào thanh ghi al:
mov al, byte ptr tongso
Gán giá trị trong al vào ô nhớ tongso (1 byte):
mov byte ptr tongso,al
Gán giá trị của ô nhớ thứ 1 trong dayso vào al:
mov al, tongso[0] ; AL sẽ bằng 5
Gán giá trị của ô nhớ thứ 2 trong dayso vào al:
mov al, tongso[1] ; AL sẽ bằng 6
Khi tham chiếu đến một vùng nhớ, nên mô tả tường minh về loại dữ liệu bằng
chỉ định byte ptr hoặc word ptr . Nếu không mô tả thì trình hợp dịch sẽ
lấy theo kiểu dữ liệu đã khai báo.
Có nhiều đoạn mã lệnh dùng để điều khiển các thiết bị được thiết kế sẵn trong
BIOS hoặc OS. Các chương trình viết cho PC thường dùng các đoạn mã lệnh
này hơn là phải thực hiện lại từ đầu. Cách thức này được gọi là sử dụng các
chức năng của hệ thống.
Một số các ký tự điều khiển có ảnh hưởng đến chức năng in như sau:
Chờ đọc một phím, không in lại phím này ra màn hình
mov ah,0
int 016h
Sau khi thực hiện AL = mã ASCII của phím được gõ vào
AH = scan code của phím
AL bằng 0 khi một số các phím chức năng được bấm
Đọc trạng thái của bàn phím
mov ah,2
int 016h
Sau khi thực hiện AL = byte trạng thái của bàn phím
In chuỗi ký tự với thuộc tính màu, bắt đầu tại vị trí row và col:
mov ax,01301h
mov bh,0
mov bl,<color_code>
mov bp,offset <chuoi_can_in>
mov cx,<So_ky_tu_trong_chuoi>
mov dh,<row> ; 0 - 24
mov dl,<col> ; 0 - 79
int 010h
Màu của ký tự được tạo thành từ màu nền (Background color) và màu ký tự
(Foreground/Text color) theo công thức sau:
Color_code = Foreground_Color + 16*Background_Color
Hãy dùng Tech Help để tham khảo các chức năng của BIOS và DOS