GV: Ths. Phạm Nguyên Văn
Lệnh .model lựa chọn mô hình bộ nhớ.
Tiny: Mã và DL phối hợp < 64K.
Small: Mã <=64K, DL <= 64K. Một phân đoạn mã, 1 phân
đoạn dữ liệu.
Medium: Dữ liệu <= 64K, mã có kích cỡ bất kỳ. Nhiều phân
đoạn mã, 1 phân đoạn dữ liệu.
Compact: Mã <= 64K, dữ liệu kích cỡ bất kỳ. Một đoạn mã,
nhiều phân đoạn dữ liệu.
Large: Mã > 64K, dữ liệu > 64K. Nhiều phân đoạn mã và dữ
liệu.
Huge: giống như Large, ngoại trừ các biến riêng lẻ như các
mảng có thể > 64K.
Flat: Không có phân đoạn nào. Các địa chỉ 32bit được dùng
cho cả mã và DL. Chỉ dùng chế độ bảo vệ.
2
Biểu thức là tổ hợp các toán tử và toán hạng được
trình biên dịch chuyển thành một giá trị đơn lẻ.
3
1000h * 50h ; = 50000h
-4 + 2 ; = -6
count + 2 ; số đếm là 1 hằng
31 MOD 6 ; = 1
6 / 4 ; = 1
‘2’ – 30h ; = 2(do giá trị của ‘2’ = 32h)
4
Toán tử Cấp Mô tả
() 1 Dấu ngoặc đơn
+,- 2 Dương và Âm (đơn tử)
*, /, mod 3 nhân, chia, lấy phần dư
+,- 4 Cộng, trừ
5
OFFSET trả về vị trí của 1 nhãn và biến từ đầu
phân đoạn của nó. Toán hạng đích phải là 1 thanh
ghi 16bit:
VD: mov bx, offset count ; BX trỏ đến count
offset có thể được chuyển đến 1 thanh ghi chỉ mục
hoặc cơ số. Trong ví dụ sau, bList mặc định nằm
tại offset 0000:
6
.data
bList db 10h, 20h, 30h, 40h
wList dw 1000h, 2000h, 3000h
.code
mov di, offset bList ; dl = 0000
mov bx, offset bList + 1 ; bx = 0001
mov si, offset wList+2 ; si = 0006
7
Toán tử SEG trả về phần phân đoạn của 1 nhãn
hoặc địa chỉ của biến. Thường được dùng khi biến
nằm trong 1 phân đoạn khác với phân đoạn hiện do
DS trỏ đến
VD: đẩy [push] giá trị hiện thời của DS lên stack,
ấn định DS theo phân đoạn chứa array, và sau đó
phục hồi DS theo giá trị ban đầu của nó
8
push ds ; lưu DS
mov ax,seg array ; ấn định ds theo phân đoạn của
mảng
mov ds, ax
mov bx, offset array ; tìm độ dịch vị mảng
… ;xử lý mảng
pop ds ; phục hồi ds
9
PTR: chạy đè lên kích cỡ ngầm định của một
toán hạng.
Phát biểu rõ kích cỡ của toán hạng.
Phải được kết hợp với các kiểu dữ liệu chuẩn:
BYTE, SBYTE, WORD, DWORD,
SDWORD, FWORD, QWORD, TBYTE.
VD:
mov al,byte ptr count
mov ax, word ptr newVal
mov eax,dword ptr listPointer
10
Do kích cỡ của toán hạng không được rõ ràng xét
theo ngữ cảnh 1 lệnh. VD:
inc [bx] ; toán hạng gián tiếp
báo lỗi do không biết bx chứa byte hay word
inc byte ptr [bx]: xác định rõ kích cỡ của toán hạng
là byte
Có thể chạy đè kích cỡ ngầm định của toán hạng.
11
Vd: ta có từ kép 32bit, muốn nạp từ cao vào
DX, từ thấp vào AX:
.data
val32 dd ?
.code
mov ax, val32 ; có từ thấp (error)
mov dx, val32+2; có từ cao (error)
Sửa lại:
mov ax, word ptr val32 ; AX = 1234h
mov dx, word ptr val32+2 ; DX = 5678h
12
LABEL: chèn 1 nhãn và gán cho nó 1 thuộc
tính kích cỡ, mà không phân bổ bộ nhớ.
VD: khai báo 1 nhãn trước khi val32 gọi val16,
và gán thuộc tính word:
.data
val16 label word
val32 dd 12345678h
.code
mov ax,val16
mov dx,val32
13
EVEN và EVENDATA: căn thẳng hàng lệnh
kế tiếp trong đoạn mã theo offset 16bit đều.
Vd: 1 lệnh NOP 1-byte (90h) được chèn vào
mã đã biên dịch nơi even xuất hiện. Lệnh tiếp
theo nằm tại 0006:
0000 mov ax,@data
0003 mov ds, ax
0005 even ; byte chứa 90h được chèn ở
đây
0006 mov bx, offset array
14
Tương tự với evendata, chèn 1 byte rỗng (0) vào
trước array:
0000 .data
0000 str1 db 3 dup(‘X’)
0003 evendata
0004 array dw 10 dup(0FFFFh)
15
Toán tử SHORT:
thường sử dụng với JMP khi thực hiện nhảy ngắn
khoảng <= 127 byte từ vị trí hiện thời. Điều này giúp
trình biên dịch thực hiện 1 lệnh nhảy ngắn 1 byte
thay vì 1 lệnh nhảy gần 2 byte.
Toán tử TYPE: trả về kích cỡ của 1 thành phần
đơn lẻ trong 1 biến, tính theo byte.
VD: biến 8bit trả về kiểu 1, biến 32bit trả về kiểu 4,
mảng byte trả về 1, mảng 16bit trả về 2. Kiểu 1 nhãn
gần là FFFFh, kiểu 1 nhãn xa là FFFEh.
16
.data
var1 db 20h
var2 dw 1000h
var3 dd ?
var4 db 10,20,30,40,50
msg db ‘File not found’,0
.code
L1: mov ax,type var1 ;ax = 0001
mov ax,type var2 ;ax = 0002
mov ax,type var3 ;ax = 0004
mov ax,type var4 ;ax = 0001
mov ax,type msg ;ax = 0001
mov ax,type L1 ;ax = FFFF
17
Toán tử length: đếm số lượng các thành phần riêng
lẻ trong 1 biến được định nghĩa bằng dup.
Nếu không dùng dup, length = 1.
Nếu dùng dup lồng ghép, chỉ toán tử phía ngoài
mới được đếm.
18
.data
val1 dw 1000h
val2 db 10,20,30
array dw 32 dup(0)
array2 dw 5 dup(3 dup(0))
message db ‘File not found’,0
.code
mov ax,length val1 ; = 1
mov ax,length val2 ; = 1
mov ax,length array; = 32
mov ax,length array2 ; = 5
mov ax,length message ; = 1
19
Toán tử SIZE: = length * type của 1 biến.
intArray dw 32 dup(0) ; SIZE = 64
20
Định nghĩa 1 dãy các hằng và gán giá trị nguyên
cho từng hằng. Tất cả các ký hiệu đều được định
nghĩa trên một dòng:
name enum [, symbol1[, symbol2,…[, symbol-n] ]
]
VD:
driveStatus enum ready, busy, offline
Ngầm định: ready = 0, busy = 1, offline = 2
21
Có thể sử dụng {} để định nghĩa enum trong nhiều
dòng:
ColorType enum {
black, blue
green, cyan
red, magenta
brown, white }
Trình hợp dịch sẽ lựa chọn kiểu DL nhỏ nhất để lưau
các hằng. VD: ColorType được gán thuộc tính byte:
.code
mov al, blue ; ok
mov ax, blue ; lỗi
22
Cách dùng: giả sử đã định nghĩa ColorType
trong chương trình ngay trước lệnh .data:
.data
winColor db cyan
.code
mov al,winColor ; al = 2
hoặc:
.data
winColor ColorType cyan
23
Giá trị tường minh: mỗi hằng có thể tuỳ ý được
gán một giá trị giữa 0 và 0FFFFh (nếu giá trị 0,
1, 2 không thích hợp).
VD:
StatusVals enum normal = 1, overheat = 5,
highSpeed
.code
mov bl, overheat ; bl = 5
mov al, highSpeed ; al = 6
24
Nếu giá trị tường minh đã gán cho các hằng
vượt quá bộ nhớ 1 byte, kiểu enum sẽ tự
chuyển sang word:
StatusVals enum {
normal = 1000h, overheat = 2000h, highSpeed =
3000h }
.code
mov ax, highSpeed ;ok
mov al, overheat ; lỗi
25