Tóm tắt lý thuyết lập trình Assembly

Tóm tắt lý thuyết lập trình Assembly

lOMoARcPSD| 36066900
C ĐẦU VI LP TRÌNH ASSEMBLY TRÊN VI X 8088/8086
1. Giái thiu v hp ng:
Hp ng (Assembly) mt ngôn ng lp trình cp thp, thc cht dng gi nh (Mnemonic),
hay dng hiu, ca ngôn ng máy.
Như đã biết, lnh ngôn ng máy mt dãy các con s 0, 1 nên rt kđọc khó lp trình, thế
các nhà thiết kế vi x đã đưa ra tp lnh hp ng gn vi ngôn ng t nhiên n nên d đọc d
lp trình h¢n. Tuy vy, các lnh hp ng vn giao tiếp vi phn cng máy tính mt cách rt cht ch,
nh đó vic tiếp cn vi lp trình hp ng giúp chúng ta hiu h¢n v kiến trúc t chc hot
động ca máy tính.
Ngoài ra còn giúp chúng ta thy h¢n mi quan h gia các thành phn chc năng n trong
máy tính h đi hành. th nói ngưc li là, vic tìm hiu lp trình trên hp ng giúp chúng ta
hiu h¢n v kiến trúc máy tính, t chc hot động bên trong máy tính h điu hành.
Trong gii hn ca tài liu này chúng ta ch tìm hiu tp lnh hp ng ca các vi x lý h Intel
8088/8086, để lp trình chy trên các máy IBM-PC: S dng h vi x này hot động trong s
phi hp vi h điu hành MS_DOS.
Mt trong những đặc đim ca hp ng chư¢ng trình viết trên kích thưc nh h¢n và tốc độ
np/thc hin chư¢ng trình nhanh h¢n so vi viết (chư¢ng trình cùng chc năng) trên các ngôn ng
lp trình bc cao.
Ngoài ra, hu hết các ngôn ng lp trình bc cao hiện nay đều cho phép viết (<nhúng=) mã lnh hp
ng trong nó. Điu này giúp người lp trình khai thác ti đa thế mnh ca các ngôn ng lp trình,
hp ng rt mnh trong các thao tác can thip sâu vào các thành phn bên trong h thng, trong khi
đó ngôn ng bc cao mnh trong các thao tác x d liu thiết kế giao din. Như vy s rt
thun li nếu s dng ngôn ng bc cao đ viết chư¢ng trình x thông tin h thng, khi đó nhim
v truy xut h thng (thanh ghi, b nh, cng vào/ra, thiết b,...) để ly d liu s đưc giao cho các
đon lnh hp ng đưc nhúng trong chư¢ng trình này.
Hp ng h tr 2 chế độ tư¢ng tác h thng: (1) Nhp trc tiếp tng lệnh/đoạn lnh vào b nh ri
cho phép thc hin ngay trên b nh không cn qua c biên dch chư¢ng trình. Chư¢ng trình
g ri Debug (đi kèm h điu hành MS_DOS: Debug.exe) mt trong nhng chư¢ng trình h tr
chế độ này cho hp ng 16 bít; (2) Viết chư¢ng trình hp ng, ri sau đó s dng các chư¢ng trình
biên dch đ dch sang chư¢ng trình thc thi (dng EXE hoc COM) cho thc hin chư¢ng
trình này.
Hin nay hai loi trình biên dch đưc s dng đ biên dch chư¢ng trình hp ng (t tp lnh
hp ng ca các vi x h Intel) sang chư¢ng trình thc thi: Trình biên dch hp ng 16 t, MASM
(Macro Assembler), đưc s dng để dch thành các chư¢ng trình chy trên nn h điu hành 16 bít
MS_DOS; Trình biên dch hp ng 32 bít, MASM32 (Macro Assembler 32 t), đưc s dng để dch
thành các chư¢ng trình chy trên nn h điu hành 32 bít MS_Windows. Trong thc tế, để chuyn
mt chư¢ng trình hp ng sang dng chư¢ng trình thc thi EXE 16 bít hoc COM 16 bít tcn phi
s h tr ca chư¢ng trình tin ích ca h điu hành MS_DOS: Link (Link.exe) EXE2Bin
(EXE2Bin.com).
lOMoARcPSD| 36066900
Chư¢ng trình hp ng 16 t s dng h thng các ngt mm (Interrupt) ca BIOS DOS như
thư vin lp trình ca nó, trong khi đó chư¢ng trình hp ng 32 t s dng tp hàm API làm thư vin
lp trình ca nó.
2. Biến Hng trong chương trình hp ng:
Biến hng
Biến hng (hng n) trong chư¢ng trình hp ng tính cht, mc đích s dng, kiu d liu,
quy tc đt tên, quy tc gán giá tr,... tư¢ng t như biến hng trong các ngôn ng lp trình bc cao
khác. Biến trong chư¢ng trình hp ng ch các kiu d liu là: Byte, Word, Doubleword,... hng
trong chư¢ng trình hp ng th s, t hoc mt xâu t.
Khi viết chư¢ng trình hp ng chúng ta cn quan tâm đến địa ch ca biến trong b nh. Mt biến
đưc khai báo trong chư¢ng trình s đưc h thng gán cho mt địa ch trong b nh (khi chư¢ng
trình đưc np vào b nh để hot động). C th: mi biến trong chư¢ng trình s đưc định v ti
mt địa ch xác định trong b nh, các biến đưc khai báo liên tiếp nhau trong chư¢ng trình (t
trên xung i) s đưc định v ti các địa ch liên tiếp nhau trong b nh (t offset thp đến offset
cao). Nh đó, nếu chư¢ng trình xác định đưc địa ch ca mt biến nào đó thì d dàng đưc
địa ch ni dung ca các biến khác trong chư¢ng trình.
Khác vi biến, hng trong chư¢ng trình hp ng không đưc cp phát b nh để lưu tr, tc là, n¢i
nào trong chư¢ng trình cha trên hng thì s đưc trình biên dch thay bng giá tr ca mt cách
trc tiếp.
Hp ng cung cp các toán t gi đ định nghĩa/khai báo d liu: DB nh nghĩa byte), DW nh
nghĩa word), DD (định nghĩa doubleword),. ... toán t EQU để khai báo hng. Biến th đưc
khai báo đầu hoc cui chư¢ng trình. Trong khi đó, hng th khai báo bt k n¢i đâu trong
chư¢ng trình, khi đó ta th s dng toán t du <== để gán giá tr cho hng.
Khai báo biến hng:
Cú pháp khai báo:
a:
<Tên biến>
DB
<Tr khi to>
b:
<Tên biến>
DW
<Tr khi to>
c:
<Tên biến>
DD
<Tr khi to>
d:
<Tên hng>
EQU
<Hng s>
Trưng hp a đưc s dng để khai báo biến kiu byte, trường hp b đưc s dng để khai
báo biến kiu word, trường hp c đưc s dng để khai báo biến kiu doubleword, trường hp d
đưc s dng để khai báo hng. <Tr khi to> th mt hoc nhiu giá tr, th mt s, mt
t hoc mt xâu t, cũng th mt du hi chm (<?=). <Hng s> th mt s, mt
t hay mt xâu t.
Ví dā 1:
Spt
DB
KiTu
DB
TieuDe
DB
SoNguyen
DW
lOMoARcPSD| 36066900
DaySo DD 1020, 1345, 2389, 5763
Trong d trên, hai biến Spt Kitu đều biến kiu byte, kích thước 1byte. Biến TieuDe cũng
biến kiu byte nhưng gm 7 byte ô nh liên tiếp (kích thưc 7 byte), mi byte cha 1 t ASCII.
Biến SoNguyen biến kiu word, chưa đưc gán giá tr khi to. Biến DaySo biến kiu
doubleword, gm 4 phn t giá tr ln t (t thp đến cao) là: 1020, 1345, 2389, 5763.
d 2:
LF
EQU
0Ah
TB
EQU
8
Cong nghe Thong t
i
n
9
TieuDe
DB
TB
Khai báo trên cho thy, th khi to giá tr ban đu cho biến thông qua mt hng đã đưc định
nghĩa trước.
d
3:
TenKhoa
DB
8
Cong
nghe
Thong
tin
9
,
0Ah,
0Dh,
8
$
9
Khai báo biến TenKhoa cho thy, th khai báo mt biến trong đó bao gm c s, kí t xâu
t, đây biến kiu byte, gm 22 byte.
d 4: SoPT DW 2345h
Biến SoPT trên mt biến word, trong trường hp này byte thp ca nhn giá tr 45h, byte cao
nhn giá tr 23h, nhưng byte thp định v tại địa ch SoPT, byte cao định v ti địa ch SoPT + 1.
Trong hp ng, mt dãy các byte hay word liên tiếp nhau trong b nh th xem mt mng
(mng byte hay mng word). Biến DaySo trong d 1 trên th đưc xem mt mng word
gm 4 phn t. Giá tr ca các phn t trong mng th đưc xác định thông qua tên biến ch
s tư¢ng ng a ch). C th:
DaySo[0] = 1020; DaySo[2] = 1345; DaySo[4] = 2389; DaySo[6] = 5763.
Hp ng cho phép s dng toán t DUP để khai báo mt biến dng mảng trong đó gm nhiu
phn t có cùng giá tr khi to. Dng s dng toán t DUP m Dup (n): gm m phn t cùng
giá tr khi to n.
d 5: MangSN DW 23, 45, 50 Dup (0), 12
Như vy, biến MangSN đưc xem mt mng word gm 53 phn t, hai phn t đầu tiên nhn giá
tr ln t 23 45, 50 phn t tiếp theo nhn cùng giá tr 0 phn t cui cùng nhn giá tr 12.
Trong d 1 trên: Các biến đưc khai báo đây s đưc định v ti các địa ch liên tiếp nhau
trong b nh. Nếu biến Spt đưc định v ti địa ch offset 100 trong đon nh d liu thì các biến tiếp
theo s đưc định v ti các offset sau đó. C th: Biến KiTu bt đu ti offset 101, biến TieuDe bt
đầu ti offset 102, biến SoNguyen định v ti offset 109, biến DaySo bt đu ti offset 111 (xem hình
sau):
100
101
102
103
104
105
106
107
108
109
111
113
115
117
0
a
T
i
n
_
H
o
c
1020
1345
2389
5763
(dòng trên địa ch offset ca biến, dòng i các ô nh cha giá tr ca các phn t trong biến)
lOMoARcPSD| 36066900
Điu cn quan tâm đây là, th truy xut đến giá tr ca mt phn t trong biến này thông qua tên
ca
mt
biến
kc.
V
í
d:
Spt[0]
=
0,
T
i
euDe[0]
=
8
T
9
,
T
i
euDe[1]
=
89
i
,
DaySo[0]
=
1020,
DaySo[6]
= 5763,... nhưng cũng th
Spt[2]
=
K
i
Tu[1]
=
8
T
9
,
K
i
Tu[5]
=
8
h
9
,
DaySo[-5]
=
8
h9
,
T
i
euDe[11]
=
1345,...
lOMoARcPSD| 36066900
Cu trúc ca mt chương trình Assembly
Hu hết các h điu hành máy tính hin nay, đặc bit là các h điu hành ca Microsoft, đều h tr hai dng cu
trúc tp tin thc thi th hoạt động trên nó, đó tp tin cu trúc dng COM và tp tin cu trúc dng EXE.
nhiu đim khác nhau gia hai cu trúc chư¢ng trình này, nhưng đim khác bit ln nht là: Các chư¢ng trình
cu trúc dng EXE gm 3 đoạn: lnh (Code), d liu (Data) Ngăn xếp (Stack). Khi hot động, 3 đon này
s đưc np vào 3 đon (Segment) b nh tách bit trên b nh;
Các chư¢ng trình dng COM thì ngược li, ch 1 đon lnh, trong đó cha c lnh ngăn
xếp. thế, khi đưc np vào b nh để hot động ch đưc cp phát mt đon b nh. ràng kích thước
ca mt chư¢ng trình dng COM không th t quá gii hn ca mt đon b nh (vi Intel 8088/80286
MSDOS, 1 Segment b nh = 64KB).
Trong khi đó mt chư¢ng trình dng EXE th ln h¢n 3 Segment b nh. Do đó, khi thiết kế các
chư¢ng trình ln, vi chc năng phc tp, trong đó liên kết gia các modun chư¢ng trình khác nhau thì ta
phi thiết kế theo cu trúc chư¢ng trình dng EXE.
Hp ng h tr thiết kế c hai dng cu trúc chư¢ng trình EXE COM, mi dng phù hp
vi mt nhóm trình biên dch nào đó. Mun biên dch mt chư¢ng trình hp ng sang dng EXE thì
ngoài vic phi đưc viết theo cu trúc dng EXE ta còn cn phi s dng mt trình biên dch phù
hp. Điu này cũng tư¢ng t vi vic mun mt chư¢ng trình thc thi dng COM.
Văn bn ca mt chư¢ng trình hp ng dng EXE cũng cho thy gm 3 đon: Code,
Data Stack. Tư¢ng t, văn bn ca chư¢ng trình hp ng dng COM cho thy ch 1 đon:
Code, c Data Stack (không ng minh) đều nm đây.
Mt chư¢ng trình hp ng gm hai thành phn chính: phn lnh hp ng phn ch dn
biên dch. Ch các lnh đưc biên dch thành ngôn ng máy. Phn ng dn biên dch không
đưc dch sang ngôn ng máy, ch tác dng vi các trình biên dch. Thông thưng mi chư¢ng
trình biên dch mt nhóm ng dn biên dch phù hp vi nó, nhng vi các ng dn biên
dch bn đ¢n gin t phù hp vi hu hết các trình biên dch hp ng hin nay. Trong tài
liu này chúng tôi s dng các ng dn biên dch phù hp vi trình biên dch Microsoft Macro
Assembler (MASM).
Cu trúc chư¢ng trình đưc gii thiu sau đây s dng các ng dn biên dch đnh nghĩa
đon đ¢n gin (.Model, .Code, .Stack, .Data) phù hp vi MASM, TASM (Turbo Macro Assembler),
A86. Vic s dng định nghĩa đon đ¢n gin s làm cho văn bn chư¢ng trình sáng sa d đọc
h¢n. Vi các định nghĩa đon đ¢n gin ta cũng th xây dng đưc các chư¢ng trình t đ¢n gin
đến phc tp.
Cu trúc chương trình dng COM:
.Model ‹Chế đ b nh>
.Code
ORG 100h
‹Nhãn chính>:
JMP ‹Th tc chính>
lOMoARcPSD| 36066900
‹Khai báo d liu đt ti đây>
‹Th tc chính> PROC
‹Các lnh ca chương trình đt ti đây>
‹Th tc chính> Endp
‹Các th tc khác đt ti đây>
End ‹Nhãn chính>
Trong cu trúc chư¢ng trình trên các t khóa Model, Code, ORG, Proc, Endp, End các ng dn
biên dch. <Nhãn chính> nhãn ca lnh Jmp.
Cu trúc này cho thy rõ, mt chư¢ng trình hp ng dng COM ch 1 đon, đó chính đon
Code (đoạn lnh), trong này bao gm c phn khai báo d liu. Các khai báo d liu trong
chư¢ng trình dng COM th đặt đầu hoc cui chư¢ng trình, nhưng vi vic s dng định
nghĩa đon đ¢n gin các khai báo d liu phi đt đầu chư¢ng trình.
Ch dn ORG 100h và lnh JMP <Th tc chính> s được đề cp trá li á các phần sau đây của
tài liu này.
Cu trúc chương trình dng EXE:
.Model ‹Chế đ b nh>
.Stack 100h
.Data
‹Khai báo d liu đt ti đây>
.Code
‹Th tc chính> PROC
‹Các lnh ca chương trình đt ti đây>
‹Th tc chính> Endp
<Các th tc khác đặt ti đây>
END
Trong cu trúc chư¢ng trình trên các t khóa Model, Code, Data, Stack, Proc, Endp, End các
ng dn biên dch.
Cu trúc này cho thy rõ, mt chư¢ng trình hp ng dng gm 3 đon: đon Code, cha toàn b
lnh ca chư¢ng trình. Đon Data, cha phn khai báo d liu ca chư¢ng trình. Đon Stack, n¢i
cha stack (ngăn xếp) ca chư¢ng trình khi chư¢ng trình đưc np vào b nh để hot động.
lOMoARcPSD| 36066900
Ch dn .Stackđặt đầu chư¢ng trình vi mc đích khai báo kích thưc ca Stack dùng cho chư¢ng
trình sau này. Kích thưc thường đưc chn 100h (256) byte.
Ch dn .Model đưc đặt đầu c cu trúc chư¢ng trình dng COM EXE vi mc đích khai báo
chế độ b nh chư¢ng trình s dng.
dā: Sau đây hai chư¢ng trình hp ng đ¢n gin, dng COM dng EXE, cùng thc hin
nhim v in ra mànnh 3 dòng văn bn như sau :
Nguyen Kim Le Tuan
Nguyen Le Tram Thanh
Nguyen Le Tram Uyen
Hai chương trình dưới đây chỉ có tác dng minh ha cho vic s dụng các hướng dn biên dịch đnh
nghĩa đoạn đơn giản và giúp các bn thấy được những điểm ging nhau, khác nhau gia hai dng
cấu trúc chương trình dạng COM và EXE, vì vậy, á đây các bạn chưa cn quan tâm đến ý nghĩa của
các lnh và các hàm/ngt trong nó. Phn lnh hp ng và các hàm/ngt s đưc trình bày ngay sau
đây.
Chương trình viết theo cu trúc dng COM:
.Model Small
.Code
Start:
ORG 100h
Jmp Main
MyChildren
DB
8
Nguyen
Kim
Le
Tuan
9
,0Ah,0Dh
DB
8
Nguyen
Le
Tram
Than
h9
,0Ah,0Dh
DB
8
Nguyen
Le
Tram
Uyen
9
,9$
9
Main PROC
;------- in ra mot xau voi ham 09/21h -------
Mov Ah, 09h
Lea Dx, MyChildren
Int 21h
;------- ket thuc chuong trinh -------
Int 20h
Main Endp
End Start
lOMoARcPSD| 36066900
Chư¢ng trình này chn chế độ b nh Small. Tên th tc chính Main (tên th tc chính tùy ý).
Nhãn chính ca chư¢ng trình Start (tên th tc chính tùy ý), đó chính nhãn ca lnh Jmp.
Phn khai báo d liu ch khai báo mt biến, đó MyChildren.
Chư¢ng trình này gi hàm 4Ch ca ngt 21h đ kết thúc chư¢ng trình. th gi ngt 20h để kết
thúc các chư¢ng trình dng COM.
Chương trình viết theo cu trúc dng EXE:
.Model Small
.Stack 100h
.Data
MyChildren
DB
8
Nguyen
Kim
Le
Tuan
9
,0Ah,0Dh
DB
8
Nguyen
Le
Tram
Thanh9
,0Ah,0Dh
DB
8
Nguyen
Le
Tram
Uyen
9
,9$
9
.Code
Main PROC
;------- khi to DS -------
Mov Ax, @Data
Mov DS, Ax
;------- in ra mot xau voi ham 09/21h -------
Mov Ah, 09h
Lea Dx, MyChildren
Int 21h
;------- ket thuc chuong trinh -------
Mov Ah, 4Ch
Int 21h
Main Endp
END Main
Chư¢ng trình này chọn chế độ b nh Small. Khai báo kích thước Stack 100h byte. Phn khai báo
d liệu được đặt trong đoạn Data, đây chỉ khai báo mt biến, đó MyChildren. Tên thủ tc chính
Main (tên th tc chính tùy ý).
Thao tác đầu tiên ca chư¢ng trình tr thanh ghi đon DS v đầu đon Data, hay còn gi khi
to thanh ghi đon DS:
Mov Ax, @Data
Mov DS, Ax
lOMoARcPSD| 36066900
thao tác này đưc xem như bt buc đối vi cu trúc chư¢ng trình dng EXE s dng định nghĩa
đon đ¢n gin. Các chư¢ng trình viết theo cu trúc dng EXE phi gi hàm 4Ch ca ngt 21h để kết
thúc.
th thy, cu trúc chư¢ng trình dng COM cu trúc chư¢ng trình dng EXE ch khác phn
ng dn biên dch, phn khai báo biến phn lnh thao tác chính hoàn toàn ging nhau. Hai
chư¢ng trình đ¢n gin trên hoàn toàn ging nhau biến MyChildren các lnh gi hàm 09h
ca ngt 21h để in ra màn hình mt xâu t (xâu này chính giá tr khi to ca biến MyChildren).
Chú ý 1: Trình biên dch hp ng (Macro Assembler) cho phép các chư¢ng trình đưc dch bi nóc
hn s dng mt trong các chế độ b nh sau:
-
Small: Đon lnh (Code) đon d liu (Data) ca chư¢ng trình đu ch th cha trong
mt đon (segment) b nh. Tc là, kích thưc ca chư¢ng trình ch th ti đa hai đon b
nh. Tuy vy chế đ b nh này đủ dùng cho hu hết các chư¢ng trình hp ng.
-
Medium: Đon Code ca chư¢ng trình th chiếm nhiu h¢n mt đon b nh. Trong khi đó,
đon Data ch th chiếm 1 đon b nh.
-
Compact: Đon Data ca chư¢ng trình th chiếm nhiun mt đon b nh. Trong khi đó,
đon Code ch th chiếm 1 đon b nh.
-
Large: Đon Code đoan Data ca chư¢ng trình đều th chiếm nhiu h¢n mt đon b nh.
Nhưng trong trường hp này không th định nghĩa mt mng d liu kích thưc ln h¢n 64
Kbyte.
-
Huge:
Tư¢ng t như Large, nhưng trong trường hp này th định nghĩa mt mng d liu
kích tc ln n 64 Kbyte.
Chế độ b nh Small đ¢n gin nht, đưc hu hết các chư¢ng trình la chn.
Chú ý 2: Vi các chư¢ng trình hp ng s dng định nghĩa đon đ¢n gin: Khi đưc np vào b
nh để hot động thì các thanh ghi đon s t động tr v các đon chư¢ng trình tư¢ng ng. C th:
Thanh ghi đon CS cha địa ch segment ca đon b nh cha đon Code ca chư¢ng trình.
Thanh ghi đon DS (và th c ES) cha địa ch segment ca đon b nh cha đon Data ca
chư¢ng trình. Thanh ghi đon SS cha địa ch segment ca đon b nh cha đon Stack ca
chư¢ng trình.
Tuy nhiên, trong thc tế, khi np chư¢ng trình EXE vào b nh DOS luôn dành ra 256 byte đầu tiên
ca vùng nh, DOS cp phát cho chư¢ng trình, đ cha PSP (Program Segment Prefix) ca
chư¢ng trình. PSP cha các thông tin cn thiết trình biên dch chuyn đến cho DOS để h tr
DOS trong vic thc hin chư¢ng trình này, đặc bit, chư¢ng trình cũng th truy xut vùng nh
PSP. Do đó, DOS phi đưa địa ch segment ca vùng nh cha PSP vào c DS ES trưc khi
chư¢ng trình đưc thc hin. Tc , ngay khi chư¢ng trình đưc np vào b nh DS không phi
cha địa ch segment ca đon Data ca chư¢ng trình cha địa ch segment ca PSP.
vy, để tr DS v li đon Data chư¢ng trình chúng ta phi đặt ngay hai lnh sau đây đầu
chư¢ng trình viết theo cu trúc EXE:
Mov Ax, @Data
Mov DS, Ax
lOMoARcPSD| 36066900
Vi vic khi to thanh ghi đon DS trên, địa ch segment ca tt c các biến khai báo trong đon
Data đều đưc cha trong thanh ghi DS, do đó, trong các thao tác x biến sau này chư¢ng trình
không cn quan tâm đến địa ch segment ca na.
Chú ý 3: Hp ng còn cho phép các chư¢ng trình s dng các ng dn biên dch định nghĩa đon
toàn phn, các định nghĩa này phù hp vi hu hết c trình biên dch hp ng hin nay. Định nghĩa
đon toàn phn giúp cho vic viết chư¢ng trình hp ng tr nên mm do linh hot h¢n, giúp
ngưi lp trình th điu khin th t các đon chư¢ng trình, kết hp các đon chư¢ng trình, liên
kết các đon chư¢ng trình trong b nh,... , ngay trong khi lp trình.
Chi tiết v cách s dng và mục đích sử dng của các hưng dn biên dịch nói chung và các đnh
nghĩa đoạn toàn phn nói riêng d dàng tìm thy trong rt nhiu tài liu v lp trình hp ng [1], [2].
à
đây chúng tôi ch gii thiệu sơ c v thông qua ví d ới đây.
dā: Sau đây mt chư¢ng trình dng EXE s dng các ng dn biên dch định nghĩa đon
toàn phn (phù hp vi Macro Assembler):
S_Seg Segment Stack
DB 100h DUP (?)
S_Seg Ends
D_Seg
Segmet
MyChildren DB
8
Nguyen
Kim
Le
Tuan
9
,0Ah,0Dh
DB
8
Nguyen
Le
Tram
Thanh9,0Ah,0Dh
DB
8
Nguyen
Le
Tram
Uyen
9
,9$
9
D_Seg Ends
C_Seg Segment
ASSUME CS:C_Seg, SS:S_Seg, DS:D_Seg
Main PROC
;------- khi to DS -------
Mov
Mov
Ax, D_Seg
DS, Ax
Mov
Ah, 09h
Lea
Dx, MyChildren ; đa ch offset ca biến MyChildren
Int
21h
Mov
Ah, 4Ch
Int
21h
Main
Endp
C_Seg
Ends
lOMoARcPSD| 36066900
END Main
Điu d nhn thấy đầu tiên phn khai báo biến phn lnh chính trong chư¢ng trình này hoàn
toàn ging như trong chư¢ng trình s dng định nghĩa đon đ¢n gin (hai chư¢ng trình d trên).
Chư¢ng trình này s dng ng dn biên dch định nghĩa đon toàn phn Segment ... Ends để
định nghĩa 3 đon chư¢ng trình vi tên ln t là: S_Seg (đoạn stack), D_Seg (đoạn Data), C_Seg
(đoạn Code). Tên ca các đon đưc định nghĩa đây tùy ý.
ng dn biên dch Assume đưc s dng để báo cho trình biên dch biết chư¢ng trình mun
cha địa ch segment ca các đon chư¢ng trình trong các thanh ghi đon nào (tr thanh ghi đon v
đon chư¢ng trình). C th đây là: Thanh ghi đon CS cha địa ch segment ca đon Code
(CS:C_Seg). Thanh ghi đon SS cha địa ch segment ca đon Stack (SS:S_Seg). Thanh ghi đon
DS cha địa ch segment ca đon Data (DS:C_Seg). Tuy nhiên, trong thc tế Assume
DS:D_Seg không t động np địa ch segment ca D_Seg vào DS, do đó chư¢ng trình phi np trc
tiếp bng các lnh:
Mov Ax, D_Seg
Mov DS, Ax
Nên nh, ng dn biên dch Segment ... Ends ch tác dng định nghĩa đon, không th báo
cho trình biên dch biết đon đưc định nghĩa thuc loi đon chư¢ng trình nào (Code, Data, Stack,
Extra). Ch định nghĩa Segment Stack ... Ends báo cho trình biên dch biết đon đưc định
nghĩa đon Stack, nh đó, khi chư¢ng trình đưc np vào b nh thanh ghi đon SS s đưc tr
v đon này
lOMoARcPSD| 36066900
Phn 1: MT S LNH ASSEMBLY
S
pháp LNH:
Mt lnh hp ng đầy đủ gm bn thành phn sau đây:
[Nhãn lnh:] <Tên lnh> [Các toán hng] [;Li gii thích]
Trong đó:
-
[Nhãn lnh:]: mt dãy các t đứng trưc câu lnh (kết thúc bi du hai chm (:)), đưc
ch định thay thế cho địa ch ca câu lệnh trong các đon lnh lp, r nhánh,... Do đó, ch đưc s
dng khi cn.
Trong mt chư¢ng trình hp ng không th hai nhãn lnh trùng tên, tên ca các nhãn cũng không
th trùng vi tên ca các th tc trong chư¢ng trình.
-
<Tên lßnh>: mt trong các lnh thuc tp lnh hp ng (lnh gi nh: Mnemonic) ca vi x
trên máy tính thc hin lnh này.
Lnh hp ng không phân bit ch hoa hay ch thưng. Trong chư¢ng trình hp ng mi dòng ch
th cha mt lnh mi lnh phi đưc đặt trên mt dòng.
-
[Các toán hng]: đối ng lnh tác đng vào. Mt lnh hp ng ca Intel 8088/8086
th không có toán hng, mt toán hng, hoc hai toán hng. Nếu hai toán hng thì toán
hng đứng trưc gi [Toán hng đích], toán hng đứng sau gi [Toán hng ngun]. [Toán hng
đích] không th mt hng s.
Mt s lnh hp ng ca các Intel 80286/80386/... th đến 3 toán hng, trong trưng hp này
cũng ch mt [Toán hng đích].
-
[;Li gii thích]: Ch tác dng vi người viết người đọc chư¢ng trình, không ý nghĩa
vi trình biên dch, tc là, không đưc dch sang máy. Li gii thích thưng đưc s dng để làm
ý nghĩa ca câu lnh (khi ngưi viết thy cn). Li gii thích phi nm sau du chm phy (;).
1: Xét lnh sau đây:
Lenh_VD: Mov AX,BX ; đặt giá tr thanh ghi BX vào thanh ghi AX
Trong đó:
Lenh_VD: Trong trường hp này dãy t Lenh_VD đưc s dng làm nhãn lnh cho lnh Mov.
Mov: tên lnh.
AX BX: các toán hng (đích ngun). Trong trường hp này toán hng các thanh ghi đa năng 16
bít.
t giá tr thanh ghi BX vào thanh ghi AX=: Là li gii thích cho lnh này. Trong thc tế li gii thích
thường là tiếng Vit không du.
2: Xem các lnh sau đây:
-
NOP ; đây là lnh không có toán hng
lOMoARcPSD| 36066900
-
Mov Ax, Bl ; lnh này hai toán hng, [Toán hng đích] là thanh
; ghi 16 bít, [Toán hng ngun] thanh ghi 8 bít
-
Add Cl, Spt ; lnh này hai toán hng, [Toán hng đích] là thanh
; ghi 8 bít, [Toán hng ngun] mt biến byte
-
Mov Ax, [SI] ; lnh này hai toán hng, [Toán hng đích] thanh
; ghi 16 bít, [Toán hng ngun] mt ô nh
- Sub
Dl,
8
a
9
8
A
9
;
l
nh
y
ha
i
toán
hng,
[Tn
hng
đí
ch]
l
à
thanh
; ghi 8 bít, [Toán hng ngun] mt hng s
-
IMul Ax, Bx, 20 ; lnh này ba toán hng, [Toán hng đích] thanh
; ghi 16 bit (Ax), [Toán hng ngun] thanh ghi 16 bít
; (Bx) mt hng s (20)
Lnh Imul trên là mt lnh nhân mi ca vi x Intel 80286. Lnh này thc hiện như sau: ly ni
dung/giá tr hai [Toán hng ngun] nhân vi nhau, kết qu cha [Toán hạng đích] (trong lnh trên
là: Bx*20, tích kết qu cha thanh ghi Ax (ch ly 16 bít thp ca tích để đưa o Ax)).
1.
Lßnh Mov (Move):
pháp lßnh:
Mov [Toán hng đích], [Toán hng ngun]
Trong đó:
-
[Toán hng đích]: th thanh ghi (8 bít hay 16 bít), ô nh (chính xác h¢n địa ch ca mt ô
nh) hay mt biến nào đó. [Toán hng đích] không th hng s.
-
[Toán hng ngun]: th hng s, biến, thanh ghi, ô nh (chính xác h¢n địa ch ca mt ô
nh) nào đó.
Tác dāng: Ly ni dung (giá tr) ca [Toán hng nguồn] đặt vào [Toán hng đích]. Ni dung ca
[Toán hng ngun] không b thay đổi.
1:
-
Mov
Ax, 5
; Ax ß 5: đặt giá tr 5 vào thành ghi Ax
-
Mov
Ax, 5*2
; Ax ß 5*2: đt giá tr 10 vào thành ghi Ax
-
Mov
Bx, (80*(Dong - 1) + (Cot - 1))*2
; Dong, Cot các biến
-
Mov
Dl,
8
A
9
;
Dl
=
41h:
đặt
ASCII
ca
8
A
9
vào
thanh
gh
i
Dl
-
Mov
Cx, Var1
; Cx = Var1: đặt giá tr ca biến Var1 vào thanh ghi Cx
-
Mov
Ax, Bx
; Ax = Bx: đặt giá tr ca thanh ghi Bx vào Ax
-
Mov
Ax, Dl
; Ax = Dl: đặt giá tr ca Dl (8 bít) vào Ax (16 bít)
lOMoARcPSD| 36066900
-
Mov Bl, Dx ; Bl = Dx: không hp l, vì: Dx (16 bít) Bl (8 bít)
-
Mov Dl, 300 ; Dl = 300: không hp l, 300 t gii hn 1 byte
2: Gi s DI = 100; Ô nh ti địa ch offset 100 trong đon nh Data (được ch bi DS) cha
t B. Thì :
- Mov
Ax, DI
; (1) đặt giá tr thanh ghi DI vào thanh ghi Ax: Ax = 100
- Mov
Ax, [DI]
; (2) Ax = <ni dung ca ô nh đưc ch bi DI (DI
; ch địa ch offset ca ô nh)>. Tc là, đặt ni dung ca
; ô nh đưc ch bi DI vào thanh ghi Ax: Ax = 41h
Hãy phân bit s khác nhau gia hai lnh trên: Lnh (1) s dng chế độ địa ch thanh ghi. Lnh (2)
s dng chế độ địa ch gián tiếp thanh ghi.
Nh li rng: Trong chế độ địa ch gián tiếp thanh ghi, các thanh ghi ch th BX, DI, SI a ch
đon cha trong DS) hay BP a ch đon cha trong SS). Như vy lnh (2) tư¢ng đư¢ng vi lnh
(3) nhưng khác lnh (4):
; (3)
; (4)
; đặt ni dung ô nh đưc ch bi SI vào thanh ghi Ax
; đặt giá tr ca thanh ghi bx vào ô nh đưc ch bi DI
; [DI] ß [SI] : lnh không hp l, vì: không th chuyn
; ni dung ca ô nh vào mt ô nh mt cách trc tiếp
-
Mov Var1, Ax ; Var1 ß Ax : đặt giá tr t/ghi Ax vào biến word Var1
Chú ý:
-
Lnh Mov không làm nh ng đến các c.
- Mov
DS:[DI], ES:[SI]
; lnh không hp l, vì: không th chuyn d liu
; trc tiếp gia hai toán hng b nh vi nhau
- Mov
DS, ES
; DS ß ES: lnh không hp l,
- Mov
ES, 0100
; lnh không hp l, vì: không th chuyn
; trc tiếp mt hng so thanh ghi đon.
Để chuyn giá tr ca hai thanh ghi đon hay ni dung ca hai ô nh ta th n mt thanh ghi đa
năng làm trung gian:
- Mov
Ax, ES
; hai lnh này chuyn ni dung ca thanh ghi đon ES
Mov
DS, Ax
; vào thanh ghi đoạn DS thông qua thanh ghi Ax
-
Mov
Ax, DS:[DI]
-
3:
Mov
Ax, ES:[DI]
-
Mov
Ax, [SI]
-
Mov
[DI], Bx
-
Mov
[DI], [SI]
lOMoARcPSD| 36066900
Theo cách thông thường, để hoán đổi giá tr ca hai thanh ghi đon hay ni dung ca hai ô nh
ngưi ta thường s dng hai thanh ghi đa ng làm trung gian:
- Mov
Ax, [DI]
; lưu tm ni dung ô nh đưc ch bi DI Ax
Mov
Bx, [SI]
; lưu tm ni dung ô nh đưc ch bi SI Bx
Mov
[DI], Bx
; chuyn giá tr ca t/ghi Bx ô nh đưc ch bi DI
Mov
[SI], Ax
; chuyn giá tr ca t/ghi Ax ô nh đưc ch bi SI
Bn lnh trên tác dng hoán đổi ni dung ca hai ô nh trong đon Data (DS) đưc ch bi DI
SI (DI SI cha địa ch Offset ca các ô nh).
-
Không th dùng thanh ghi đoạn CS làm [Toán hạng đích] trong lnh Mov.
2.
Các lßnh Inc Dec Add Sub
pháp lßnh:
Inc [Toán hng đích]
Add [Toán hng đích],[Toán hng ngun]
Dec [Toán hng đích]
Sub [Toán hng đích],[Toán hng ngun]
Trong đó: [Toán hng đích], [Toán hng ngun]: tư¢ng t lnh Mov.
Tác dāng:
Lnh Inc (Increment): làm tăng giá tr ca [Toán hng đích] lên 1 đ¢n v.
Lnh Dec (Decrement): làm gim giá tr ca [Toán hạng đích] xung 1 đ¢n v.
Lnh Add (Addition): ly giá tr/ni dung ca [Toán hng ngun] cng vào giá tr/ni dung ca [Toán hng
đích], kết qu này đặt vào li [Toán hạng đích].
Lnh Sub (Subtract): ly giá tr/ni dung ca [Toán hng đich] tr đi giá tr/ni dung ca [Toán hng ngun],
kết qu này đặt vào li [Toán hạng đích].
Ví dā 1:
Mov
Mov
Ax, 121
Bx, 223
; đặt giá tr 121 vào thanh ghi Ax
; đặt giá tr 232 vào thanh ghi Bx
Inc
Dec
Ax
Bx
; Ax = Ax + 1: tăng Ax lên 1 đ¢n v (Ax = 122)
; Bx = Bx + 1: gim Bx xung 1 đ¢n v (Bx = 222)
Sub
Ax, Bx
; Ax = Ax Bx : Ax = -100
lOMoARcPSD| 36066900
Add
Ax, 120
; Ax = Ax + 120 : Ax = 20
Mov
Cx, Ax
; Cx= Ax : Cx = 20
Dãy lnh trên, đặt giá tr cui cùng ca thanh ghi Ax vào thanh ghi Cx (Cx = 20).
Ví dā 2:
-
Inc
Spt
; Spt = Spt + 1; tăng giá tr biến Spt lên 1 đ¢n v
-
Inc
DS:[SI]
; tăng ndung ô nh đưc ch bi DS:SI lên 1 đ¢n v
-
Add
Ax, Var1
; Ax = Ax + Var1; cng giá tr biến Var1 vào Ax
-
Add
Var2, Dx
; Var2 = Var2 + Dx. Biến Var2 biến dng word
-
Add
Dx, [SI]
; cng thêm ni dung ô nh đưc ch bi SI vào Dx
-
Add
[DI], [SI]
; [DI] = [DI] + [SI] : lnh không hp l, vì: không th
; cng trc tiếp ni dung hai ô nh vi nhau.
; Yêu cu ca lnh trên th đưc viết li như sau:
Mov Ax, [SI] ; lưu tm ni dung ô nh đưc ch bi SI Ax
Mov Bx, [DI] ; lưu tm ni dung ô nh đưc ch bi DI Bx
Add Bx, Ax ; cng Ax Bx, kết qu cha Bx
Mov [DI], Bx ; đặt kết qu phép cng vào li ô nh đưc ch bi DI
3: Cng thêm giá tr ca thanh ghi Ax vào ni dung ca ô nh tại địa ch offset 0100 trong đoạn
DS:
Mov
DI, 0100
; tr DI v ô nh offset 0100
Mov
Bx, DS:[DI]
; lưu tm ndung ô nh DS:DI vào thanh ghi Bx
Add
Bx, Ax
; cng thêm Ax vào Bx
Mov
DS:[DI], Bx
; đặt kết qu vào li ô nh DS:DI (DS:0100)
Trong trường hp này ta th s dng lnh Add DS:[DI],Ax.
4: Gi s ti ô nh 0B800:0100 trong b nh cha mt word d liu. Hãy tăng ni dung ca
ô nh này lên mt đ¢n v.
Mov Ax, 0B800h ; mượn thanh ghi Ax làm trung gian đ chuyn
Mov ES, Ax ; đa ch đon ca ô nh cn truy xut vào ES
Mov DI, 01 ; đt đa ch offset ca ô nh cn truy xut vào DI
; --------------------------- ; (gi ngn gn: tr ES:DI v ô nh cn truy xut)
Mov
Dx, ES:[DI]
; chuyn tm ni dung ô nh cn tăng vào Dx
Inc
Dx
; tăng giá tr thanh ghi Dx lên 1 đơn v
Mov
ES:[DI], Dx
; đt giá tr Dx đã tăng vào li ô nh cn tăng
lOMoARcPSD| 36066900
dā 5: Gi s ti địa ch 0A00:0100 trong b nh cha mt byte d liu. Hãy chuyn ni dung
ca ô nh này vào thành ghi AL.
Mov
Ax, 0A00h
; (1); Các lnh (1), (2), (3) tr cp thanh
Mov
ES, Ax
; (2); ghi ES:DI v ô nh địa ch 0A00:0100
Mov
DI, 0100h
; (3); trong đó 0A00 địa ch Segment
;------------------------- ; 0100 là địa ch Offset. Lnh (4) chuyn ni
Mov Al, ES:[DI] ; (4); dung ô nh đưc ch bi ES:DI o Al.
6: Gi s ti địa ch 0100:0100 trong b nh cha 2 word d liu liên tiếp (hai ô nh liên
tiếp). Hãy tính tng ni dung hai word nh này, ri ly kết qu ghi vào ô nh ti địa ch 0100:0120.
Mov
Mov
Ax, 0100
ES, Ax
; tr cp thanh ghi ES:SI v đầu ng nh
Mov
SI, 0100
; cn truy xut.
Mov
DI,0120
; tr cp thanh ghi ES:DI v ô nh cha kết qu
;------------------------- ; các ô nh này trong ng mt Segment
Mov Ax, ES:[SI] ; lưu tm ni dung ô nh đầu tiên vào Ax
Add Ax, ES:[SI+2] ; cng ni dung ô nh kế tiếp vào Ax
Mov ES:[DI], Ax ; ghi kết qu vào ô nh 0100:0120
Lnh Add Ax, ES:[SI+2] trên s dng chế độ định địa ch b nh gián tiếp, c th định địa
ch ch mc (s dng thanh ghi ch mc SI).
Qua 3 d 4, 5, 6 ta th rút ra nguyên tc bn khi truy xut d liu/ni dung ca mt ô nh là:
S dng mt cp thanh ghi thích hp (DS:DI, DS:SI, ES:DI, ES:SI,...) để cha địa ch logic (gm c
Segment Offset) ca ô nh cn truy xut. Thao tác này thưng gi tr v ô nh cn truy xut.
Sau đó s dng cp thanh ghi này để ghi/đc ni dung ca ô nh đã đưc tr ti.
Ngoài ra, khi truy xut ô nh cn phi xác định d liu/ni dung ti đó mt Byte hay mt Word
nếu truy xut đọc thì kết qu s đưc lưu vào đâu (thanh ghi hay ô nh).
Chú ý 1:
Không th cng trc tiếp hai thanh ghi đon. Trong trường hp này phi s dng các thanh ghi đa năng làm
trung gian.
Lnh Add thc hin phép cng không nh. Để thc hin phép cng nh (cng thêm giá tr ca c nh
(CF) hin ti vào kết qu) phi s dng lnh ADC (ADD with Carry) [2 - 171]. Tư¢ng t vi lnh Sub
SBB [2 - 180].
Để thc hin phép cng trên các s/giá tr BCD (Binary Coded Decimal) ta phi s dng các lnh
cng AAA (Ascii Adjust for Addition) và DAA (Decimal Adjust for Addition) để điu chnh (adjust) kết qu
cui cùng [2 - 172]. Tư¢ng t, vi phép tr trên các s BCD phi s dng lnh AAS DAS [2 - 183].
Chú ý 2:
lOMoARcPSD| 36066900
Các thanh ghi ca vi x Intel 8086/8088 đều 16 bít, nên để cha mt đi ng d liu 32 bít phi
dùng 2 thanh ghi, thường là các thanh ghi đa năng (thanh ghi tích lũy): Ax, Bx, Cx, Dx. Cp thanh ghi Dx:Ax
thường đưc s dng nht, khi đó Ax cha 16 bít thp, Dx cha 16 bít cao ca đại ng 32 bít.
Để cng/tr trên các s 32 bít ta không th s dng Add/Sub theo cách thông thường, phi thc hin
như sau: Cng/Tr 16 bít thp, sau đó Cng/Tr 16 bít cao. Nếu phép Cng/Tr trên 16 bít thp xut hin
bít nh/bít n thì phi tiến hành điu chnh kết qu, nếu không kết qu s sai. S dng các phép kim
tra c để biết phép Cng/Tr xut hin bít nh/bít n hay không [1 - 477].
3.
Lßnh LOOP
pháp:
Loop <Nhãn đích>
Trong đó: <Nhãn đích> mt nhãn lnh phi đứng trước lnh lp Loop không q126 byte.
Tác dāng: Khi gp lnh này chư¢ng trình s lp li vic thc hin các lnh sau <Nhãn lnh> đủ n
ln, vi n đưc đặt trước trong thanh ghi CX. Sau mi ln lp CX t động gim 1 đ¢n v (Cx = Cx - 1)
lnh lp s dng khi Cx = 0.
Lnh Loop thường đưc s dng đ cài đặt các đon chư¢ng trình lp vi s ln lp xác định, đưc
cho trước trong thanh ghi Cx (tư¢ng t các vòng lp For trong các ngôn ng lp trình bc cao).
1: Xem đon lnh sau đây:
Mov
Ax, 6
Mov
Cx, 4
; lp li 4 ln
Lap: Add
Ax, 10
; cng thêm 10 vào Ax
Loop
Lap
; lp li vic cng 10 vào Ax đủ 4 ln
Kết thúc đon lnh trên: Ax = 46 (c th: LÁn 1: Ax = 6 + 10; LÁn 2: Ax = 16 + 10; LÁn 3: Ax = 26 +
10; LÁn 4: Ax = 36 + 10 = 46).
2: Xem đon lnh sau đây:
Mov
Ax, 6
Mov
Mov
Bx, 3
Cx, 4
; lp li 4 ln
Lap_TT:
Add
Ax, Bx
; cng thêm giá tr thanh ghi Bx vào thanh ghi Ax
Inc
Bx
; tăng Bx lên 1 đ¢n v
Loop
Lap_TT
; lp li các lnh sau nhãn lnh Lap_TT đủ 4 ln
;----------------------------- ; sau lnh lp này Ax = 24, Bx = 7
Mov Dx, Ax ; Dx ß Ax
Mov Cx, Bx ; Cx = 7, sau Loop Cx = 0, đưc thay bng Bx = 7
lOMoARcPSD| 36066900
Kết thúc đon lnh trên: Ax = 24 (LÁn 1: Ax = 6 + 3;LÁn 2: Ax = 9 + 4; LÁn 3: Ax = 13 + 5; LÁn 4: Ax
= 18 + 6) Dx = Ax = 24.
Khi gp lnh Loop Lap_TT chư¢ng trình s quay li (nếu Cx <> 0) thc hin lnh Add Ax,
Bx (Lap_TT nhãn ca lnh này), tất nhiên khi đó cũng phi thc hin li lnh Inc Bx. đó,
th nói lnh Loop này thc hin vòng lp cho c hai lnh Add Inc. Đó cũng chính do
ngưi ta thường viết nhãn ca các lnh phi đưc lp theo kiu như trên (nhãn lnh lnh không
cùng trên mt dòng).
3: Xem đon lnh sau đây:
Mov
Mov
TT:
Dx, 6
Cx, 5
; lp li 5 ln
Add
Dx, Cx
; cng thêm giá tr thanh ghi Cx vào thanh ghi Dx
Loop
TT
; lp li các lnh sau nhãn lnh TT đ 5 ln
; ;
Mov Bx, Cx
Kết thúc đon lnh trên Bx = Cx = 0 (khi Cx = 0 thì vòng lpLoop TT kết thúc) và Dx = 21 (LÁn 1: Dx
= Dx + Cx = 6 + 5;LÁn 2: Dx = Dx + Cx = 11 + 4; LÁn 3: Dx = Dx + Cx = 15 + 3; LÁn 4: Dx = Dx + Cx
= 18 + 2;LÁn 5: Dx = Dx + Cx = 20 + 1 = 21).
4: Các lnh sau đây thc hin phép gán:
Ax = 2 + 4 + ...+ 100
Mov Ax, 0
Mov Bx, 2
Mov Cx, 50
Lap_TT:
Add Ax, Bx
Add Bx, 2
Loop Lap_TT
5: Gi s tại địa ch offset 100 trong đoạn nh Data ược ch bởi thanh ghi đọan DS) cha
mt mng d liu, gm 100 ô nh, mi ô mt byte. Hãy cộng thêm 50 đ¢n v vào tt c các ô nh
trong mng này.
Mov DI, 0100 ; tr cp thanh ghi DS:DI v
; vùng nh cn truy xut (DS:0100)
;
Mov Cx, 100 ; lp 100 ln mng gm 100 ô nh
lOMoARcPSD| 36066900
Lap_TangThem:
Mov
Dl, DS:[DI]
; ly nôi dung ô nh ch bi DS:DI lưu vào DL
Add
Dl, 50
; cng thêm 50 vào Dl
Mov
DS:[DI], Dl
; đặt giá tr đã tăng thêm o li ô nh DS:DI
Inc
DI
; ch đến ô nh kế tiếp (vì ô nh byte nên ng 1)
Loop
Lap_TangThem
; lp li đ 100 ln (duyt qua đủ 100 ô nh)
Trong trưng hp này ta có th s dng lnh Add DS:[DI], 50 để tăng trc tiếp ni dung ca ô
nh, hp ng cho phép điều này. Nhưng cách đã viết thường được áp dng n, vì tính tng quát
ca nó. Nói chung, chúng ta nên hn chế tác động trc tiếp lên nôi dung ca ô nh.
6: Gi s tại địa ch 0100:0C00 trong b nh cha mt xâu t gm 50 t (tc là, gm
50 ô nh, mi ô 1 byte). Hãy copy xâu t này sang vùng nh bt đầu ti địa ch 0200:0100.
Mov
Ax, 0100
Mov
DS, Ax
; tr cp thanh ghi DS:SI v
Mov
SI, 0C00
; đầu vùng nh chưa xâu cn copy (0100:0C00)
Mov
Mov
Ax, 0200
ES, Ax
; tr cp thanh ghi ES:DI v
Mov
DI, 0100
; vùng nh cha u kết qu copy 0200:0100
;
Mov Cx, 50 ; lp 50 ln xâu gm 50 t
Lap_Copy:
Mov
Bl, DS:[SI]
; mưn Bl để chuyểnng kí t t ô nh đưc
Mov
ES:[DI], Bl
; ch bi DS:SI sang ô nh đưc ch bi ES:DI
Inc
SI
; chuyn đến t tiếp theo
Inc
Loop
DI
Lap_Copy
; lp li đủ 50 ln copy đủ 50 t)
Trong ví d này, vùng nh cha xâu t cn copy (vùng nh ngun) và vùng nh cha kết qu
copy (vùng nh đích) nm hai đon (segment) nh khác nhau, do đó, ta phi s dng hai thanh ghi
đon d liu kc nhau: DS ES.
Qua 2 d 5 6 ta th rút ra nguyên tc bn đ truy xut d liu trên mt vùng nh/mng
nh:
Chú ý: Lnh Loop thc hin vòng lp cho đến khi Cx = 0, thế đưc xem như lnh lp không
điu kin. Thc tế, hp ng còn các lnh lp điu kin, cho phép kết thúc vòng lp trước khi
Cx = 0 da vào mt điu kiện nào đó. Cụ th: lnh LoopE (Loop while Equal): Ch lp li khi Cx <> 0
lOMoARcPSD| 36066900
c ZF = 1; lnh LoopZ (Loop while Zero): tư¢ng t LoopE; LoopNE (Loop while Not Equal): Ch
lp li khi Cx <> 0 c ZF = 0;... [2 - 154].
4. Lên
h
LEA
(L
oad
E
ffective
A
ddress
)
Cu
´
pha
´
p:
LEA
[
Toa
´
n
hang
đ
i
´
ch
]
,
[
Toa
´
n
han
g
nguô`
n
]
Trong
đo
´
:
[Toa
´
n
han
g
đ
i
´
ch]:
La
`
ca
´
c
thanh
ghi
16
b
i
´
t.
[Toa
´
n
han
g
ng`
n]:
La
`
đ
i
a
ch
i
cu
a
môt
vu
`
ng
nh
¢
´
hay
tên
cu
a
t
b
i
ê
´
n.
Ta
´
c
dun
g:
Lnh
LEA
tác
dng
chuyê n
đ
i
a
ch
i
offset
cu
a
[Toa
´
n
han
g
ng`
n]
va
`
o
[Toa
´
n
han
g
đ
i
´
ch].
n
h
na
`
y
t
hư
¢
`
ng
đ
ư
¢
c
s
ư
dung
đê
l
â
´
y
đ
i
a
ch
i
offset
cu
a
môt
b
i
ê
´
n
đa
đư
¢
c
kha
i
ba
´
o
trong
c
hư
¢
ng
tri
`
nh. Thanh ghi đư¢c s
dụng trong trư¢
`
ng h¢p na
`
y la
`
thanh ghi c¢ s¢
(BX) va
`
thanh ghi ch
mc
(SI va
`
DI).
Vi
´
du
1:
Lea Bx, DS:[0100] ; chuyn tha
`
nh phâ` n đi ch
offset (0100) va
`
o Bx
Lea
DI,
XauKT
;
chuyê n
đ
i
a
ch
i
offset
cu
a
b
i
ê
´
n
XauKT
va
`
o
DI
;
thao
ta
´
c
na
`
y
thư
¢
`
ng
đư
¢
c
go
i
l
a
`
tro
DI
va
`
đâ`
u
; biến XauKT
Khi
c
hư
¢
ng
tr
i
`
nh
đ
ư
¢
c
nap
va
`
o
bô
nh
¢
´
đê
hoat
đôn
g
th
i
`
ca
´
c
biê
´
n
đư
¢
c
kha
i
ba
´
o
trong
c
hư
¢
ng
tr
i
`
nh
se
đư
¢
c
đ
i
n
h
v
i
(
´
p
pha
´
t
vu
`
ng
nh
¢
´
)
ta
i
t
đ
i
a
ch
i
xa
´
c
đ
i
n
h
trong
vu
`
ng
nh
¢
´
Data.
T
ư
`
đây,
đê
thao
ta
´
c
đê
´
n
d
ư
li
êu
trên
ca
´
c
biê
´
n
cu
a
c
hư
¢
ng
tr
i
`
nh
th
i
`
c
hư
¢
ng
tr
i
nh
`
pha
i
xa
´
c
đ
i
n
h
đ
ư
¢
c
đ
i
a
ch
i
segment
va
`
o
offset
(ha
i
tha
`
nh
phâ`
n
cu
a
đ
i
a
ch
i
l
og
i
c)
cu
a
b
i
ê
´
n.
n
h
LEA
¢
trên
ch
i
l
â
´
y
đư
¢
c
đ
i
a
ch
i
offset
cu
a
b
i
ê
´
n,
đê
l
â
´
y
đư
¢
c
đ
i
a
ch
i
segment
cu
a
no
´
ta
co
´
thê
s
ư
dung
l
ên
h
Mov
v
¢
´
i
toa
´
n
t
ư
Seg
(
tư
¢
ng
t
ư
co
´
thê
s
ư
dung
l
ên
h
Mov
v
¢
´
i
toa
´
n
t
ư
Offset
đê
l
â
´
y
đ
i
a
ch
i
offset
cu
a
b
i
ê
´
n).
V
i
´
du:
Ca
´
c
l
ên
h
sau
l
â
´
y
đ
i
a
ch
i
Segment:Offset
cu
a
b
i
ê
´
n
XauKT
(hay
tro
DS:SI
`
đâ`
u
b
i
ê
´
n
XauKT):
Mov
Ax,
Seg
XauKT
;
đư
a
đ
i
a
ch
i
Segment
cu
a
b
i
ê
´
n
XauKT
Mov DS, Ax
; va
`
o thanh ghi DS
Mov
SI,
Offset
XauKT
;
đ
ư
a
đ
i
a
ch
i
Offset
cu
a
b
i
ê
´
n
XauKT
va
`
o
SI
Vi
´
du
2:
G
i
a
s
ư
b
i
ê
´
n
TenGom
(
l
a
`
b
i
ê
´
n
k
i
ê u
byte)
đa
đư
¢
c
kha
i
ba
´
o
nh
ư
sau:
TenGom
DB
8
Nguyen
Kim
Le
Tu
an9
Xem
ca
´
c
l
ên
h
sau
đây
(1):
Mov Bx, 0
Mov
A
l
,
TenGom
[Bx]
;
A
l
=
8
N
9
Add Bx, 7 ;
Mov
B
l
,
TenGom
[Bx]
;
B
l
=
8
K
9
Xem
ca
´
c
l
ên
h
sau
đây
(2):
Lea DI, TenGom
lOMoARcPSD| 36066900
Mov
A
l
,
[DI]
;
A
l
=
8
N9
Mov
B
l
,
[DI
+
7]
;
B
l
=
8
K
9
Ta
co
´
thê
thâ
´
y,
nho
´
m
ca
´
c
l
ên
h
(1)
va
`
nho
´
m
ca
´
c
l
ên
h
(2)
l
a
`
tư
¢
ng
đ
ư
¢
ng
nhau
`
ta
´
c
dung
cu
a
no
´
,
nh
ư
ng
(1):
s
ư
dung
tr
ư
c
tiê
´
p
tên
biê
´
n
đê
truy
xuâ
´
t
đê
´
n
ca
´
c
phâ`
n
t
ư
cu
a
no
´
;
(2):
s
ư
dung
thanh
gh
i
ch
i
muc
DI
đê
truy
xuâ
´
t
đê
´
n
ca
´
c
phâ`
n
t
ư
cu
a
b
i
ê
´
n.
Trong
tr
ư
¢
`
ng
h
¢
p
na
`
y
đ
i
a
ch
i
segment
măc
đi h đư¢c
ch
i
b
¢
i
DS,
đ
i
ê`
u
na
`
y
phu
`
h
¢
p
v
¢
´
i
v
i
êc
s
ư
dung
đ
i
a
ch
i
g
i
a
´
n
t
i
ê
´
p
thanh
ghi
ch
i
muc.
Vi
´
du
3:
G
i
a
s
ư
ta
i
đ
i
a
ch
i
0100:0C00
trong
bô
nh
¢
´
co
´
ch
ư
´
a
môt
u
k
i
´
t
ư
` m
50
k
i
´
t
ư
(t
ư
´
c
l
a
`
,
`
m
50
ô
nh
¢
´
,
mô
i
ô
1
byte).
Ha
y
copy
xâu
k
i
´
t
ư
na
`
y
va
`
o
t
b
i
ê
´
n
trong
c
hư
¢
ng
tr
i
`
nh.
V
¢
´
i
yêu
`
u
na
`
y
c
hư
¢
ng
tr
i
`
nh
pha
i
kha
i
ba
´
o
môt
b
i
ê
´
n
byte
co
´
đô
l
¢
´
n
50
byte:
LuuTru
DB
50
Dup
(
8
8
)
Mov Ax, 0100
Mov
DS,
Ax
;
tro
căp
thanh ghi DS:SI
Mov
SI,
0C00
;
đâ`
u
vu
`
ng
nh
¢
´
c
hư
a
u
`
n
copy
(0100:0C00)
;
Mov
Ax,
Seg
LuuTru
;
tro
căp
thanh ghi ES:DI
Mov
ES,
Ax
;
đâ`
u
b
i
ê
´
n
LuuTru
Lea DI, LuuTru
;
Mov Cx, 50
Lap_Copy:
Mov
Bh,
DS:[SI]
;
m
ư
¢
n
Bh
đê
chuyê n
tư
¢
`
ng
k
i
´
t
ư
t
ư
`
ô
nh
¢
´
đư
¢
c
Mov
ES:[DI],
Bh
;
ch
i
b
¢
i
DS:SI
sang
ô
nh
¢
´
đư
¢
c
ch
i
b
¢
i
ES:DI
Inc
SI
;
chuyê n
đê
´
n
k
i
´
t
ư
t
i
ê
´
p
theo
Inc DI
Loop
Lap_Copy
;
l
ăp
l
a
i
đu
50
l
â`
n
(đê
copy
đu
50
k
i
´
t
ư
)
Chu
´
y
´
:
H
¢
p
ng
ư
co
`
n
cung
´
p
ca
´
c
l
ên
h
LDS
(Load
Po
i
nter
use
DS)
đê
l
â
´
y
i
dung
toa
´
n
han
g
b
nh
¢
´
32
b
i
´
t
đư
a
va
`
o
ca
´
c
thanh
ghi
16
b
i
´
t
(măc
đ
i
n
h
16
b
i
´
t
cao
va
`
o
thanh
gh
i
đoan
d
ư
li
êu
DS);
va
`
l
ên
h
LES
(Load
Pointer
use
DS)
¢
ng
t
ư
LDS
n
hư
ng
măc
(th
ư
´
ha
i
)
ES
[2
-
137].
5. Lên
h
Mul
va
`
Div
Cu
´
pha
´
p:
Mul [T
o
a
´
n
h
a
n
g
ngu
ô`
n
]
đ
i
n
h
16
b
i
´
t
cao
va
`
o
thanh
gh
i
đoan
d
ư
li
êu
lOMoARcPSD| 36066900
IMul [T
o
a
´
n
h
a
ng
ngu
ô`
n
]
Div [T
o
a
´
n
h
a
ng
ngu
ô`
n
]
IDiv [T
o
a
´
n
h
a
ng
ngu
ô`
n
]
Trong
đo
´
:
[Toa
´
n
han
g
nguô`
n]co
´
thê
l
a
`
thanh
gh
i
hay
ô
nh
¢
´
.
V
¢
´
i
ca
´
c
l
ên
h
nhân:
[Toa
´
n
han
g
đ
i
´
ch]
ngâ` m đi h la
`
thanh ghi Al
hoăc ng
Ax,
Bx,...
Ax.
V
¢
´
i
ca
´
c
l
ên
h
chia:
[Toa
´
n
han
g
đ
i
´
ch]
l
a
`
môt
trong
ca
´
c
thanh
ghi
đa
Ta
´
c
dung:
- n
h
Mul
(
Mul
tiply):
Th
ư
c
hiên
phe
´
p
nhân
trên
´
kng
´
u.
´
u
[Toa
´
n
han
g
ng`
n]
l
a
`
toa
´
n
han
g
8
b
i
´
t
th
i
`
l
ên
h
se
nhân
i
dung
cu
a
[Toa
´
n
han
ch
ư
´
a
¢
thanh
ghi
Ax.
g
nguô`
n]
v
¢
´
i
g
i
a
´
tr
i
thanh
gh
i
AL,
kê
´
t
qua
16
b
i
´
t
´
u
[Toa
´
n
han
g
nguô`
n]
l
a
`
toa
´
n
han
g
16
b
i
´
t
th
i
`
l
ên
h
se
nhân
i
dung
cu
a
[Toa
´
n
han
g
nguô`
n]
v
¢
´
i
gia
tr
i
thanh
gh
i
Ax,
kê
´
t
qua
32
b
i
´
t
ch
ư
´
a
¢
căp
thanh
gh
i
Dx:Ax,
phâ`
n
thâ
´
p
¢
Ax,
phâ`
n
cao
¢
Dx.
´
u
phâ`
n
cao
cu
a
kê
´
t
qua
(AH
hoăc
DX)
bă`
ng
0
th
i
`
ca
´
c
c
¢
`
CF
=
0
va
`
OF
=
0.
- Lên
h
IMul
(
I
nterger
Mul
tip
l
y):
T
ư
¢
ng
t
ư
l
ên
h
Mu
l
n
hư
ng
th
ư
c
h
i
ên
´
t
qua
ng
l
a
`
môt
´
co
´
´
u.
phe
´
p
nhân
trên
ha
i
sô
´
co
´
´
u.
-
n
h
Div
(
Div
i
de):
Th
ư
c
hiên
phe
´
p
ch
i
a
trên
´
kng
´
u.
´
u
[Toa
´
n
han
g
ng`
n]
l
a
`
toa
´
n
han
g
8
b
i
´
t
th
i
`
l
ên
h
se
l
â
´
y
gia
´
tr
i
cu
a
thanh
gh
i
Ax
(sô
´
b
i
chia)
chia
cho
[Toa
´
n
han
kê
´
t
qua
thư
¢
ng
´
ch
ư
´
a
trong
thanh
gh
i
A
l
,
sô
´
dư
ch
ư
´
a
trong
thanh
gh
i
Ah.
g
nguô`
n]
(sô
´
ch
i
a),
´
u
[Toa
´
n
han
g
nguô`
n]
l
a
`
toa
´
n
han
g
16
b
i
´
t
th
i
`
l
ên
h
se
l
â
´
y
g
i
a
´
tr
i
cu
a
căp
thanh
gh
i
Dx:Ax
(sô
´
b
i
chia)
chia
cho
[Toa
´
n
han
g
nguô`
n]
(sô
´
chia),
kê
´
t
qua
thư
¢
ng
sô
´
ch
ư
´
a
trong
thanh
gh
i
Ax,
sô
´
dư
ch
ư
´
a
trong
thanh ghi Dx.
´
u
phe
´
p
chia
cho
0
xa
y
ra
hay
th
ư
¢
ng
sô
´
vư
¢
t
qua
´
g
i
¢
´
i
han
(chia
16
b
i
´
t)
th
i
`
CPU
se
pha
´
t
s
i
nh
l
ô
i
<
D
i
v
i
ce
overf
l
ow
=.
cu
a
thanh
gh
i
AL
(ch
i
a
8
b
i
´
t)
hay
Ax
- Lên
h
Idiv
(Integer
Div
i
de):
T
ư
¢
ng
t
ư
l
ên
h
D
i
v
nh
ư
ng
th
ư
c
h
i
ên
qua
cu
`
ng
l
a
`
ca
´
c
´
co
´
´
u.
Vi
´
du
1:
phe
´
p
ch
i
a
trên
hai
sô
´
co
´
´
u.
´
t
- Mul
B
l
;
Ax
ßAL
*
B
l
:
´
b
i
nhân
ngâ`
m
đ
i
n
h
trong
A
l
- Mul
Bx
;
Dx:Ax
ßAx
*
Bx:
´
b
i
nhân
ngâ`
m
đ
i
n
h
trong
Ax
- Id
i
v
B
l
;
Ax/B
l
,
thư
¢
ng
sô
´
ch
ư
´
a
trong
A
l
,
´
dư
ch
ư
´
a
trong
Ah
- Id
i
v
Bx
;
Dx:Ax/Bx,
th
ư
¢
ng
sô
´
ch
ư
´
a
trong
Ax,
´
dư
trong
Dx
Vi
´
du
2:
Da
y
ca
´
c
l
ên
h
dư
¢
´
i
đây
se
th
ư
c
h
i
ên
kiu word:
phe
´
p
ga
´
n
A
=
4*A
3*B,
trong
đo
´
A
va
`
B
l
a
`
ca
´
c
b
i
ê
´
n
Mov
Ax,
4
;
´
nhân
pha
i
đư
¢
c
ch
ư
´
a
trong
Ax
IMu
l
A
;
th
ư
c
h
i
ên
phe
´
p
nhân
Mov
Bx,
Ax
;
l
ư
u
tam
kê
´
t
qua
va
`
o
Bx
lOMoARcPSD| 36066900
Mov
Ax, 3
; Ax = 3
Imul
B
; Ax = Ax * B
Sub
Mov
Bx, Ax
A, Bx
;
đăt
kê
´
t
qua
cuô
´
i
cu
`
ng
va
`
o
A
Trong trư¢
`
ng h¢p na
`
y ta đã
gi
s
h
i
ên trong
thanh
ghi
Ax.
tư
¢
ng
tra
`
n
đa
kng
xa
y
ra
va
`
kê
´
t
qua
phe
´
p
nhân
ch
i
ch
ư
´
a
Vi
´
du
3:
Ca
´
c
l
ên
h
sau
đây
th
ư
c
hiên
phe
´
p:
ch
i
a
-123
cho
24:
Mov
Ax,
-123
;
đăt
´
b
i
chia
va
`
o
Ax
Mov
B
l
,
24
;
đăt
´
chia
va
`
o
B
l
(thanh
ghi
8
b
i
´
t)
Idiv
B
l
;
ch
i
a
Ax
cho
B
l
,
kê
´
t
qua
ch
ư
´
a
¢
A
l
va
`
Ah
Vi
´
du
4:
Da
y
l
ên
h
dư
¢
´
i
đây
se
th
ư
c
hiên
phe
´
p
ga
´
n
A
=
N!
(t
i
´
nh
N
g
i
a
i
th
ư
`
a).
A
l
a
`
môt
b
i
ê
´
n
word:
Mov
Ax, 1
;
chuâ
n
b
i
Ax
đê
l
ư
u
kê
´
t
qua
Mov
LapNhan:
Cx, N
;
t
i
´
nh
N!
Mul
Cx
; Ax ßAx * Cx
Loop
LapNhan
;
Mov
A,
Ax
;
tra
kê
´
t
qua
va
`
o
b
i
ê
´
n
A
Trong
tr
ư
¢
`
ng
h
¢
p
na
`
y
chu
´
ng
ta
gia
s
ư
kê
´
t
qua
không
v
ư
¢
t
qua
´
g
¢
´
i
han
16
b
i
´
t.
Chu
´
ng
ta
đa
b
i
ê
´
t:
N!
=
1
´
u
N
=
1,
N!
=
N*(N-1)*(N-2)*...*1
nê
´
u
N>1,
đ`u
na
`
y
hoa
`
n
toa
`
n
phu
`
h
¢
p
v
¢
´
i
s
ư
thay
đô
i
cu
a
thanh
ghi
CX
trong
l
ên
h
l
ăp
b
i
ê u
th
ư
´
c
t
i
´
nh
g
i
a
i
th
ư
`
a.
Loop.
Do
đo
´
,
¢
đây
ta
co
´
thê
s
ư
dung
CX
nh
ư
l
a
`
N
trong
Chu
´
y
´
:
H
¢
p
ng
ư
cung
´
p
l
ên
h
AAM
(Asc
ii
Ad
j
ust
for
Mult
i
p
l
e)
đê
đ` u
ch
i
nh
kê
´
t
qu
phe
´
p
nhân
trên
2
´
BCD
dan
g
kng
`
n.
Va
`
l
ên
h
AAD
(Asc
ii
Ad
j
ust
for
Div
i
s
i
on)
đê
đ`
u
chin
h
kê
´
t
qua
phe
´
p
ch
i
a
trên
2
´
BCD
dan
g
kng
`
n.
Ngoa
`
i
ra
co
`
n
co
´
l
ên
h
CBW
(Convert
Byte
to
Word)
va
`
l
ên
h
CWD
(Convert
Word
to
Doub
l
eword)
đê
hô
tr
¢
cho
phe
´
p
chia
trên
ca
´
c
´
co
´
´
u
[2
187-200].
n
h
IMu
l
cu
a
v
i
x
ư
l
y
´
Intel
80286
cho
phe
´
p
ghi
ro
[Toa
´
n
hang
đ
i
´
ch],
[Toa
´
n
han
g
nguô`
n]
trong
u
l
ên
h,
ca
´
c
l
ên
h
na
`
y
co
´
thê
co
´
đê
´
n
3
toa
´
n
han
g [1 - 541].
6. Lên
h
logic:
NOT
AND
OR
XOR
TEST
Tr
ư
¢
´
c
khi
t
i
m
hiê u
`
ca
´
c
l
ên
h
l
og
i
c
chu
´
ng
ta
xem
l
a
i
kê
´
t
qua
th
ư
c
h
i
ên
ca
´
c
phe
´
p
t
i
´
nh
l
ogic
trên
2
b
i
´
t
nhi phân A va
`
B thông qua b
ng sau đây:
A
B
A And B
A Or B
A Xor B
NotA
lOMoARcPSD| 36066900
0
0
0
0
0
1
0
1
0
1
1
1
1
0
0
1
1
0
1
1
1
1
0
0
Ba
ng
trên
cho
thâ
´
y:
V
¢
´
i
phe
´
p
And:
kê
´
t
qua
=
1
ch
i
khi
ca
ha
i
b
i
´
t
=
1;
V
¢
´
i
phe
´
p
Or:
kê
´
t
qua
=
0
ch
i
khi
ca
ha
i
b
i
´
t
=
0;
V
¢
´
i
phe
´
p
Xor:
kê
´
t
qua
=
0
khi
hai
b
i
´
t
g
i
ô
´
ng
nhau,
kê
´
t
qua
=
1
khi
ha
i
b
i
´
t
kha
´
c
nhau.
V
¢
´
i
phe
´
p
Not:
0
tha
`
nh
1,
1
tha
`
nh
0.
Cu
´
pha
´
p:
Not
[
T
o
a
´
n
h
ang đ
i
´
c
h
]
And
[
T
o
a
´
n
h
ang đ
i
´
c
h
], [T
o
a
´
n
h
a
ng
ngu
ô`
n
]
Or
[
T
o
a
´
n
h
a
n
g
đ
i
´
c
h
]
, [T
o
a
´
n
h
a
ng
ngu
ô`
n
]
Xor
[
T
o
a
´
n
h
ang đ
i
´
c
h
], [T
o
a
´
n
h
a
ng
ngu
ô`
n
]
Te
st [
T
o
a
´
n
h
ang đ
i
c
´
h
], [T
o
a
´
n
h
a
ng
ngu
ô`
n
]
Trong
đo
´
:
[Toa
´
n
han
g
đ
i
´
ch],
[Toa
´
n
hang
nguô`
n]
co
´
thê
l
a
`
hă` ng
´
(tr
ư
c
hă` ng),
b
i
ê
´
n,
thanh
gh
i
hay
đ
i
a
ch
i
ô
nh
¢
´
.
[Toa
´
n
han
g
đ
i
´
ch]
kng
thê
l
a
`
hă`
ng
´
.
Ta
´
c
dun
g:
Mô
i
l
ên
h
l
ogic
th
ư
c
hiên
phe
´
p
t
i
´
nh
l
ogic
tư
¢
ng
ư
´
ng
trên
ca
´
c
b
i
´
t
(
¢
ng
ư
´
ng
`
v
i
tr
i
´
)
cu
a
[Toa
´
n
han
g
đ
i
´
ch]
va
`
[Toa
´
n
han
g
ng`
n],
kê
´
t
qua
đư
¢
c
gh
i
va
`
o
l
a
i
[Toa
´
n
han
g
đ
i
´
ch].
R
i
êng
l
ên
h
Not,
th
ư
c
hiên
phe
´
p
đa
o
b
i
´
t
ngay
trên
ca
´
c
b
i
´
t
cu
a
[Toa
´
n
han
g
đ
i
´
ch].
`
u
hê
´
t
ca
´
c
l
ên
h
l
og
i
c
đê` u
a
nh
hư
¢
ng
đê
´
n
ca
´
c
c
¢
`
CF,
OF,
ZF,...
- n
h
Not
(Log
i
ca
l
Not
):
Th
ư
c
hiên
v
i
êc
đa
o
ng
ư
¢
c
t
ư
`
ng
b
i
´
t
trong
i
dung
cu
a
[Toa
´
n
han
g
đ
i
´
ch].
n
h
na
`
y
kng
l
a
`
m
a
nh
h
ư
¢
ng
đê
´
n
ca
´
c
c
¢
`
.
n
h
Not
thư
¢
`
ng
đư
¢
c
s
ư
dung
đê
tao
- n
h
And
(Log
i
cal
And
):
Th
ư
c
hiên
dan
g
bu
`
1
cu
a
[Toa
´
n
han
g
đ
i
´
ch].
phe
´
p
t
i
´
nh
l
ogic
And
trên
t
ư
`
ng
căp
b
i
´
t
(tư
¢
ng
ư
´
ng
`
v
i
tr
i
´
)
cu
a
[Toa
´
n
hang
nguô`
n]
v
¢
´
i
[Toa
´
n
han
g
đ
i
´
ch],
kê
´
t
qua
l
ư
u
va
`
o
[Toa
´
n
han
g
đ
i
´
ch].
n
h
And
t
hư
¢
`
ng
đ
ư
¢
c
s
ư
dung
đê
xo
´
a
(=
0)
t
hoăc
nh
i
ê` u
b
i
´
t
xa
´
c
đ
i
n
h
na
`
o
đo
´
trong
môt
thanh
gh
i
.
- n
h
Or
(Log
i
cal
Inc
l
us
i
ve
Or
):Th
ư
c
hiên
phe
´
p
t
i
´
nh
l
ogic
Or
trên
t
ư
`
ng
căp
b
i
´
t
(
¢
ng
ư
´
ng
`
v
i
tr
i
´
)
cu
a
[Toa
´
n
hang
nguô`
n]
v
¢
´
i
[Toa
´
n
han
g
đ
i
´
ch],
kê
´
t
qua
l
ư
u
va
`
o
[Toa
´
n
han
g
đ
i
´
ch].
n
h
Or
th
ư
¢
`
ng
du
`
ng
đê
th
i
ê
´
t
l
âp
(=
1)
môt
hoăc
nh
i
ê` u
b
i
´
t
xa
´
c
đ
i
n
h
na
`
o
đo
´
trong
môt
thanh
gh
i
.
- n
h
Xor
(e
X
c
l
us
i
ve
OR
):Th
ư
c
hiên
phe
´
p
t
i
´
nh
l
ogic
Xor
trên
t
ư
`
ng
căp
b
i
´
t
(
¢
ng
ư
´
ng
`
v
i
tr
i
´
)
cu
a
[Toa
´
n
han
g
nguô`
n]
v
¢
´
i
[Toa
´
n
han
g
đ
i
´
ch],
kê
´
t
qua
l
ư
u
va
`
o
[Toa
´
n
hang
đ
i
´
ch].
lOMoARcPSD| 36066900
n
h
Xor
thư
¢
`
ng
du
`
ng
đê
so
sa
´
nh
(bă` ng
nhau
hay
kha
´
c
nhau)
gia
´
tr
i
cu
a
ha
i
toa
´
n
han
g,
no
´
cu
ng
giu
´
p
pha
´
t
hiên
ra
ca
´
c
b
i
´
t
kha
´
c
nhau
gi
ư
a
ha
i
toa
´
n
han
g
na
`
y.
- n
h
Test
:
T
ư
¢
ng
t
ư
n
hư
l
ên
h
And
nh
ư
ng
không
gh
i
kê
´
t
qua
va
`
o
l
a
i
[Toa
´
n
han
g
đ
i
´
ch],
no
´
ch
i
a
nh
hư
¢
ng
đê
´
n
ca
´
c
c
¢
`
CF,
OF,
ZF,...
Vi
´
du
1:
Mov Al,0 ; Al ß0
Not
A
l
;
A
l
=
Not
A
l
.
T
ư
´
c
l
a
`
A
l
=
0FFh
Vi
´
du
2:
Cho
AL
=
(10010011)
2
,
BL
=
(11001100)
2
.
- And
Al, Bl
; Al ß 10010011 And 11001100. Al =
- And
Al, 0
; Al ß 10010011 And 0. Al =
- Or
Bl, Al
; Bl ß 11001100 Or 10010011. Al =
- Or
Bl, 4
; Bl ß 11001100 Or 100. Al =
- Xor
Al, Bl
; Al ß 10010011 Xor 11001100. Al =
- Xor
Bl, Bl
; Bl ß 11001100 Xor 11001100. Bl = 00000000
Vi
´
du
3:
Đê
xo
´
a
i
dung
thanh
gh
i
na
`
o
đo
´
,
trong
h
¢
p
ng
ư
ta
co
´
thê
s
ư
dung
môt
trong
ca
´
c
l
ên
h
sau
đây:
-
Mov Ax, 0
-
Sub Ax, Ax
- Xor
Ax,
Ax
;
ca
´
c
căp
b
i
´
t
giô
´
ng
nhau
th
i
`
đê` u
=
0
Vi
´
du
5:
Lên
h
sau
đây
se
xo
´
a
(=
0)
ca
´
c
b
i
´
t
3
va
`
6
cu
a
thanh
gh
i
AL,
ca
´
c
b
i
´
t
kha
´
c
gi
ư
nguyên
g
i
a
´
tr
i
:
- And AL, 10110111b ; AL ßAL And 10110111
Trong
tr
ư
¢
`
ng
h
¢
p
na
`
y:
da
y
b
i
´
t
1
0
11
0
111
đư
¢
c
go
i
l
a
`
da
y
b
i
´
t
măt
na,
ca
´
c
b
i
´
t
3
(=
0)
va
`
6
(=
0)
đư
¢
c
go
i
l
a
`
ca
´
c
b
i
´
t
măt
na.
N
hư
y
m
´
n
l
a
`
m
cho
b
i
´
t
na
`
o
=
0
ta
cho
b
i
´
t
măt
na
¢
ng
ư
´
ng
v
¢
´
i
no
´
=
0,
ca
´
c
b
i
´
t
co
`
n
l
a
i
trong
da
y
b
i
´
t
măt
na
đê` u
=
1.
Vi
´
du
6:
Lnh
sau
đây
se
thiê
´
t
l
âp
tri:
(=
1)
ca
´
c
b
i
´
t
3
va
`
6
cu
a
thanh
gh
i
AL,
ca
´
c
b
i
´
t
kha
´
c
gi
ư
nguyên
g
i
a
- Or AL, 01001000b ; AL ßAL Or 01001000
Trong
tr
ư
¢
`
ng
h
¢
p
na
`
y:
da
y
b
i
´
t
0
1
00
1
000
đ
ư
¢
c
go
i
l
a
`
da
y
b
i
´
t
măt
na,
ca
´
c
b
i
´
t
3
(=
1)
va
`
6
(=
1)
đư
¢
c
go
i
l
a
`
ca
´
c
b
i
´
t
măt
na.
N
hư
y
m
´
n
l
a
`
m
cho
b
i
´
t
na
`
o
=
1
ta
cho
b
i
´
t
măt
na
¢
ng
ư
´
ng
v
¢
´
i
no
´
=
1,
ca
´
c
b
i
´
t
co
`
n
l
a
i
trong
da
y
b
i
´
t
măt
na
đê` u
=
0.
Vi
´
du
7:
Lên
h
sau
đây
se
k
i
ê m
tra
b
i
´
t
12
cu
a
thanh
gh
i
AX
l
a
`
=
0
hay
=
1:
- And AX, 0001000000000000b ; AX ßAX And 0001000000000000
V
¢
´
i
da
y
b
i
´
t
măt
na
nh
ư
trên,
´
u
b
i
´
t
12
cu
a
Ax
=
0
th
i
`
kê
´
t
qua
:
Ax
=
0,
nê
´
u
b
i
´
t
12
cu
a
Ax
=
1
th
i
`
kê
´
t
qu
: Ax <> 0.
lOMoARcPSD| 36066900
Ca
´
ch
du
`
ng
l
ên
h
And
nh
ư
trên
đê
k
i
ê m
tra
b
i
´
t
i
´
t
đư
¢
c
s
ư
dung,
v
i
`
no
´
l
a
`
m
thay
đô
i
gia
´
tr
i
cu
a
thanh
gh
i
`
n
k
i
ê m
tra
(điu
y
th
khc
phc
bng
l
nh
Test)
va
`
pha
i
tm
bư
¢
´
c
k
i
ê m
tra
gia
´
tr
i
cu
a
Ax
(=
0
hay
<>
0)
m
¢
´
i
biê
´
t
đư
¢
c
kê
´
t
qua
k
i
ê m
tra.
Ngoa
`
i
ra,
no
´
cu
ng
ch
i
k
i
ê m
tra
đư
¢
c
1
b
i
´
t.
Trong
th
ư
c
´
ngư
¢
`
i
ta
t
hư
¢
`
ng
s
ư
dung
kê
´
t
h
¢
p
gi
ư
a
ca
´
c
l
ên
h
d
i
c
h
b
i
´
t,
l
ên
h
quay
b
i
´
t,
l
ên
h
nha
y,...
đê
k
i
ê m
tra
ca
´
c
b
i
´
t
trong
môt
thanh
gh
i
.
7. Lên
h
chuyê
n
d
u
lu
Cu
´
pha
´
p:
qua c ng: IN OUT
IN AL, <Địa ch cng>
OUT <Địa ch cng>, AL
Trong
đo
´
:
<Địa
ch
cng>
c
hín
h
l
à
s
hiu
cng
(port)
mà
l
nh
nhn
nh
i
m
v
trao
đổ
i
d
li
u
qua
.
Địa ch cng th đưc ghi trc tiếp i dng mt hng s hoc đưc ghi thông qua thanh ghi Dx.
Ta
´
c
dung:
-
Lênh
In
(
In
put): Đọc mt ng d liu 8 bít t cng đưc ch ra a ch cng> đưa o lưu tr
trong thanh ghi AL.
Nếu địa ch cng nm trong gii hn t 0 đến FF (h thp lc phân) t th viết trc tiếp trong câu
lnh, nếu địa ch cng ln h¢n FF thì ta phi dùng thanh ghi Dx để ch định địa ch cng.
-
LnhOut (Output): Gi mt ng d liu 8 bít t thanh ghi AL ra cng đưc ch ra a ch
cng>. Tư¢ng t lnh In, địa ch cng th đưc viết trc tiếp trong câu lnh hoc thông qua thanh
ghi Dx.
;
;
Các khai báo hng:
DAT EQU 13h ;
POR EQU 7Ch ;
Các lnh:
Mov Al, POR ;
Vi
´
du
1:
-
-
In
Mov
In
Al, 40h
Dx, 3B0h
Al, Dx
;
;
2:
-
Out
40h, Al
-
Mov
Dx, 3B0h
;
3:
Out
Dx, Al
;
lOMoARcPSD| 36066900
Mov Bl, DAT ;
Out Bl, Al ;
Vi
´
du
1:
G
i
a
s
ư
ta
i
đ
i
a
ch
i
0100:0120
trong
bô
nh
¢
´
co
´
ch
ư
´
a
môt
ma
ng
d
ư
li
êu
,
gô`
m
100
ô
nh
¢
´
,
mô
i
ô
l
a
`
1
word.
Ha
y
t
i
´
nh
tô
ng
i
dung
cu
a
ca
´
c
ô
nh
¢
´
na
`
y,
´
t
qua
ch
ư
´
a
trong
thanh
gh
i
Dx.
Mov Ax, 0100
Mov DS, Ax
; tro
că
p thanh ghi DS:DI vê
Mov DI, 0120
; đâ
u vu
ng nh
câ
n truy xuâ
t (0100:0120)
;
Mov Dx, 0
; chuâ
n bi
Dx đê
l
ư
u tô
ng
Mov Cx, 100
; lă
p 100 lâ
n vi
ma
ng gô
m 100 ô nh
Lap_TT:
Add
Dx,
DS:[DI]
;
c
ô
ng
thêm
n/dung
ô
nh
ơ
ch
i
b
ơ
i
DS:DI
va
o Dx
nên
tăng 2)
nh)
´
t
thu
´
c
đoan
Add DI, 2
; chi
đê
n ô nh
kê
tiê
p (vi
ô nh
word
Loop Lap_TT
; lă
p la
i đu
100 lâ
n (duyê
t qua đu
100 ô
;
l
ên
h
trên
tô
ng
i
dung
cu
a
100
word
nh
¢
´
bă
´
t
đâ`
u
ta
i
đ
i
a
ch
i
0100:0120
trong
bô
nh
¢
´
đư
¢
c
l
ư
u
va
`
o
thanh
gh
i
Dx.
¡
đây
chu
´
ng
ta
bo
qua
kha
năng
tra
`
n
d
ư
li
êu
trong
thanh
gh
i
kê
´
t
qua
Dx.
Ví dā 2: Các lnh sau đây s copy 100 word d liu t vùng nh bt đầu ti địa ch 0100:0120 sang
vùng nh bt đầu ti 0100:0500:
Mov Ax, 0100
Mov DS, Ax
Mov SI, 0120 ; tr DS:SI v vùng nh ngun 0100:0120
Mov DI, 0500 ; tr DS:DI v vùng nh đch 0100:0500
;
Mov Cx, 100
Lap_Copy:
Mov
Ax, DS:[SI]
; lưu tm ni dng word nh ti DS:SI vào Ax
Mov
DS:[DI], Ax
; ghi giá tr Ax word nh ti DS:DI
Add
Add
SI, 2
DI, 2
; đến word nh tiếp theo
lOMoARcPSD| 36066900
Loop Lap_Copy
;
Hai vùng b nh đã cho đều trong cùng mt segment nên đây ta ch cn s dng mt thanh ghi
đon d liu DS.
Vi
´
du
3:
Các
l
nh
sau
đây
s
t
ính
tng
n
i
dung
ca
100
ô
nh
(100
byte
nh
)
trong
b
nh
,
bt
đầu
ti địa ch 0A00:0120. Kết qu đưc lưu o word nh ngay trưc vùng nh này:
Mov
Mov
Ax, 0A00h
ES, Ax
Mov
SI, 0120h
; tr DS:SI v vùng nh ngun 0A00:0120
Mov
DI, SI
; tr DS:DI v vùng nh ngun 0A00:0120
Sub
DI,2
; tr DS:DI v word nh trước vùng nh ngun
;
Mov
Cx, 100
Mov
Dx, 0
; DX cha tng
TTong:
Add
Dx, Byte
PTR
ES:[SI]
; cng n.d ca byte nh ti ES:SI vàoDX
Inc SI ; ô nh byte
Loop TTong
;
Mov Word PTR ES:[DI], DX
;
Trong đon lnh trên chúng ta s dng toán t PTR đ định kiu ô nh cn truy xut.
Lnh Add Dx, Byte PTR ES:[SI]: ly ni dung ca byte nh ti ô nh đưc ch bi ES:SI cng
thêm vào thanh ghi DX. Nếu ta viết Add Dx, ES:[SI] thì h thng ly giá tr c 1 word ti ES:SI
cng thêm vào DX (vì DX thanh ghi word (16 bít), điu này không đúng vi thc tế, chúng ta
đang cn truy xut đến các byte nh. Trong trường hp này, nếu không dùng toán t PTR thì lnh
Add phi viết như sau: Add DL, ES:[SI], khi đó hệ thng ch ly giá tr c 1 byte ti ES:SI cng
thêm vào DL (vì DL thanh ghi byte: 8 bít),
4: Các lnh sau đây s copy toàn b 20 t Ascii t biến Xau1 vào biến Xau2. Gi s Xau1
Xau2 đã đưc khai báo trước như sau:
Xau1
DB
8
Khoa
CNTT
DHKH
Hue
9
Xau2
DB
20
Dup
(8
9
)
Các lnh:
Mov Ax, @Data
lOMoARcPSD| 36066900
Mov DS, Ax
Lea SI, Xau1
Lea DI, Xau2
;
Mov Cx, 20
Lap_Copy:
Mov Al, Byte PTR DS:[SI]
Mov Byte PTR DS:[DI], Al
Inc SI
Dec DI
Loop Lap_Copy
;
Các biến ca chư¢ng trình h¢p ng
đưc khai báo trong đon Data. Hai lnh đu tiên trên tác
dng lấy địa ch segment của đoạn Data đưa vào thanh ghi đoạn DS. Do đó, DS s cha địa ch
segment ca hai biến Xau1 Xau2. Hay c th: DS:SI tr v biến Xau1 DS:DI tr v Xau2.
5: Chư¢ng trình sau đây: Để in mt xâu t t trong chư¢ng trình ra n hình văn bn đ¢n
sc (môi trường MSDOS).
Chú ý:
-
BIOS MSDOS đã cung cp nhiu hàm/ngt để chư¢ng trình h¢p ng
ghi mt t hoc mt
xâu t ra màn hình, ti v trí hin ti ca con tr màn hình hoc ti mt ta độ màn hình xác định
nào đó. K thut này đưc gi k thut ghi ran hình gián tiếp thông qua các hàm/ngt màn
hình.
-
Biết rng, tt c nhng thông tin chúng ta thy đưc trên màn hình ca mt máy tính đều
đưc lưu tr trong b nh màn hình ca máy tính đó, theo mt cách nào đó. Tc là, ni thao tác
ghi/đọc trên màn hình đều phi thông qua b nh màn hình. Như vy: Mun ghi mt xâu t ra màn
hình chư¢ng trình th ghi vào b nh n hình. Mun đọc mt xâu t t màn hình chư¢ng
trình th đọc t b nh màn hình. K thut này đưc gi k thut truy xut trc tiếp b nh
màn hình.
-
Mi h điu hành, mi chế độ màn hình s dng mt đon b nh xác định (thường khác
nhau) cho b nh màn hình. cách t chc lưu tr thông tin trên màn hình trong b nh màn hình
cũng khác nhau vi các h điu hành, các chế độ màn hình khác nhau.
-
Trên môi trường h điu hành MSDOS, b nhn hình ca chế đ nàm hình đ¢n sc 25 ng
(0 đến 24) x 80 ct (0 đếm 79) đưc lưu tr ti segment nh 0B800, bt đu ti offset 0000.
-
T chức lưu trữ thông tin trên màn hình trong b nh màn hình loại này như sau: Mỗi t trên
nàm hình chiếm 1 word trong b nh màn hình: byte thp cha mã ASCII ca kí t, byte cao cha
thuc tính (màu ch, màu nn,...) ca t đó. Từng dòng kí t trên màn hình, t trái sang phi (t
ct 0 đến ct 79), đưc lưu t ln t ti các offset liên tiếp nhau trong b nh màn hình: 80 t
lOMoARcPSD| 36066900
ca ng 0 đưc lưu tr ti 80 word đầu tiên, 80 t ca dòng 1đưc lưu tr ti 80 word tiếp
theo,... , 80 t ca ng 79ưc lưu tr ti 80 word cui cùng trong b nh nàm hình. Như vy ta
d dàng tính ra đưc offset trong b nh màn nh, tư¢ng ng vi mt t trên màn hình khi ta biết
đưc ta độ (dòng, ct) ca nó. C th, offset ca t to ta độ (ng, Cßt) đưc tính theo công
thc sau:
(80*(Dong - 1) + (Cot - 1))*2
-
B nh màn hình loi này kích thưc 25 x 80 x 2 (byte) = 40000 byte.
lOMoARcPSD| 36066900
NG¾T TRONG CH¯¡NG TRÌNH ASSEMLBLY
Ngt (Interrupt) các tín hiu mà các thành phn trong h thng, như: thiết b ngoi vi, h điu hành,
chư¢ng trình người s dng, ..., gi đến vi x (h Intel) mi khi cn trao đổi thông tin vi vi x
hay cn đưc s phc v t vi x lý. Ngt cũng th phát sinh t chính bên trong vi x khi
phát hin mt li nghiêm trong xy ra trong quá trình x lý ca nó. Khi nhn đưc mt tín hiu yêu
cu ngt vi x lý s dng ngay thao tác (lnh) hin ti để xem xét đáp ng yêu cu ngt đó, sau
đo mi tiếp tc li t thao tác (lnh) b dng trước đó.
Các máy IBM_PC, s dng vi x Intel, bao gm nhiu loi ngt: Ngt phn cng, ngt phn mm,
ngt bên trong, ngt không chn đưc (ngt độ ưu tiên cao nht). Trong đó ngt phn mm các
ngt đưc phát sinh t h điu hành chư¢ng trình ca người s dng, điu này thưng thy trong
các chư¢ng trình h¢p ng
.
H thng các ngt mm bên trong máy tính IBM_PC đưc cung cp bi BIOS h điu hành, gm
256 ngt, chúng đưc đánh s t 0 đến 255 đưc gi s hiêu ngt. Mi ngt mm ¢ng ng
vi mt chư¢ng con đưc gi chư¢ng trình con phc v ngt, tc là, đ đáp ng mt u cu ngt
mm thì h thng s phi thc hin mt chư¢ng trình con phc v ngt ¢ng ng.
H¢p ng
cung cp lệnh Int để các chư¢ng trình gọi mt ngt mm khi cn. Khi gi ngt mềm chư¢ng
trình phi ch ra s hiu ngt cn gọi, khi đó hệ thng s phi gi thc hin chư¢ng trình con phc v
ngt tư¢ng ng đ đáp ng yêu cu gi này.
Trong môi trường h điu hành 16 bít MSDOS, ngay sau khi khi động, h điu hành np tt c 256
chư¢ng trình con phc v ngt vào b nh. Khi đó 256 địa ch (Segment:Offset) các vùng nh,
n¢i định v ca 256 chư¢ng trình con phc v ngt, s đưc lưu tr ti mt không gian nh đặc bit
trong b nh, vùng nh này đưc gi bng vector ngt (mi địa ch định v ca mt chư¢ng trình
con phc v ngt đưc gi mt vector ngt.
Như vy khi h thng nhn đưc mt yêu cu ngt n (Int n) t chư¢ng trình thì phi: 1. Dng
lnh hin ti, đưa giá tr con tr lnh CS:IP hin ti (đó chính địa ch ca lnh sau lnh gi ngt)
vào lưu tr hai phn t trên đỉnh Stack; 2. Xác định phn t a ch) trong bng vector ngt cha
vector ngt ca ngt n, ly giá tr ti đây (2 phn t liên tiếp) để đưa vào cp thanh ghi con tr lnh
CS:IP (đây chính địa ch ca lnh đầu tiên ca chư¢ng trình con phc v ngt n trong b nh); 3.
Bt đầu thc hin chư¢ng trình con phc v ngt cho đến khi gp lnh kết thúc chư¢ng trình này, đó
lnh Iret; 4. Ly ni dung ca hai phn t trên đỉnh Stack đặt vào li cp thanh ghi con tr lnh để
quay tr li tiếp tc thc hin lnh sau lnh gi ngt trong chư¢ng trình.
Nhng vn đ liên quan đến Stack và cơ chế ca mt lßi gi ngt s được chúng tôi làm rõ hơn á
phn sau ca tài liu này.
1.n
h
Int
Cu
´
pha
´
p:
Int <n>
Trong
đo
´
:
Trong
đó
<n>
l
à
s
h
i
u
ngt
ca
mt
ngt
mm
cn
g
i
.
T
c
l
à,
n
th
l
à
mt
trong
các
giá tr t 0 đến 255, đó chính s hiu ngt ca 256 ngt mm BIOS và MSDOS cung cp.
lOMoARcPSD| 36066900
Ta
´
c
dun
g: Lnh Int (Interrupt) đưc s dng để gi mt ngt mm (ca BIOS hoc MSDOS) trong
chư¢ng trình h¢p ng. Khi mt ngt mm đưc gi thì h thng s thc hin chư¢ng trình con phc
v ngắt tư¢ng ng vi .
Ví dā 1:
Int 10h ; gi ngt 10h ca BIOS
Int 20h ; gi ngt 20h ca MSDOS
Mt ngt mm, hay chính xác h¢n mt chư¢ng trình con phc v ngt, th thc hin nhiu chc
năng khác nhau, mi chc năng này đưc th hin thông qua mt con s, đưc gi s hiu hàm
ca ngt. Do đó, trước khi gi ngt chư¢ng trình phi ch gi ngt vi hàm nào, bng cách đặt s
hiu hàm cn gi vào thanh ghi AH.
Ví dā 2:
Mov Ah, 01 ; gi ngt 21h vi hàm 01, Hay nói ngưc li: gi hàm
Int 21h ; 01 ca ngt 21h
Trưc khi gi hàm/ngt chư¢ng trình cn cung cp đầy đủ d liu vào (nếu có) cho nó, sau khi
hàm/ngt đưc thc hin chư¢ng trình cn xác định tr v d liu kết qu (d liu ra) hay
không, nếu thì cha đâu: thanh ghi hay ô nh, tác động đến các c hiu hay không.
Vi
´
du
3:
Mov
Ah, 02
; đặt s hiu hàm cn gi vào AH
Mov
DH, 10
; cung cp d liu vào th nht vào DH
Mov
DL, 20
; cung cp d liu vào th hai vào DL
Int
10h
; gi ngt 10h vi hàm 02. Hàm/ngt này không
; tr v d liu kết qu.
Dãy lnh trên thc hin vic gi hàm 02 ca ngt 10h (ngt ca BIOS), thc hin vic dch chuyn
con tr đến dòng 10 ct 20 ca màn hình văn bn.
Ví dā 4:
Mov Ah, 2Bh ; gi ngt 21h vi
Int 21h ; hàm 2Bh
Hàm này tr v ngày-tháng-năm hin ti (theo đồng h h thng trên máy tính). C th: Thanh ghi CX
(1980-2099) cha năm hin ti, thanh ghi DH (1-12) cha tháng hin ti, thanh ghi DL (1-31) cha
ngày hin ti. Đồng thi AL cho biết ngày trong tun (0 : ch nht, 6 : th 7).
Môt
´
ha
`
m
cu
a
ngă
´
t
21h
(MSDOS)
Ngt 21h ca MSDOS ngt thưßng đưc s dng nht, nên á đây chúng tôi chn gii thiu
v ngt này, nhưng ch vi các hàm vào/ra t/xâu t bn. Chc năng ca mi ngt, chc
lOMoARcPSD| 36066900
năng của các hàm trong mt ngt, các yêu cu d liu vào/ra ca tng hàm trong mi ngt,... d
dàng tìm thy trong các tài liu v lp trình h thng.
Ha
`
m
02
a
ng
¿t
21h:
Ta
´
c
dun
g: In mt t ra màn hình. t (hoc ASCII ca t) cn in đưc đặt trước trong
thanh ghi DL. t đây th t thưng hoc t điu khin.
S
dung:
Va
`
o:
Ah
=
02
Dl = <Kí t cn in ra>
Ra: Không
Vi
´
du
1:
Các
l
nh
sau
đây
i
n
ra
n
nh
k
í
t
A:
A:
3: Các lnh sau đây in xâu t t trong biến TieuDe ra n hình. Gi s rng biến TieuDe đã
đưc khai báo như sau:
T
i
euDe
DB
8
Khoa
CNTT
Truong
DHKH
Hue
9
Các lnh:
Lea DI, TieuDe
Mov Cx, 25
Mov Ah, 02
Lap_In:
Mov Dl, Byte PTR [DI]
Int 21h
INC DI
Mov
Mov
Int
Ah, 02
D
l
,
8
A
9
21h
;có th viết lnh Mov Dl, 41h
; 41h ASCII ca t A
2:
Các lnh sau đây in ra n hình 10 t, bt đầu t t
Mov
Cx, 10
Mov
Ah, 02
Mov
D
l
,
8
A
9
Lap_In:
Int
21h
INC
DL
Loop
Lap_In
lOMoARcPSD| 36066900
Loop Lap_In
;
4: Gi s ti địa ch 0A00:0100 trong b nh cha mt xâu t ASCII, gm 50 t. Các
lnh sau đây s inu t nói trên ra màn hình.
Mov Ax, 0A00h
Mov ES, Ax
Mov DI, 0100h
;
Mov Cx, 50
Mov Ah, 02
Lap_In:
Mov Dl, Byte PTR ES:[DI]
Int 21h
INC DI
Loop Lap_In
;
Ha
`
m
09
a
ng
¿t
21h:
Ta
´
c
dun
g: In mt dãy t (mt xâu t) ra màn hình. Địa ch ca xâu cn in này phi đưc ch bi
cp thanh ghi DS:DX xâu phi đưc kết thúc bi du $.
S
dung:
Va
`
o:
Ah
=
09
DS:DX = <Segment:Offset ca xâu cn in ra>
Ra: Không
Vi
´
du
1:
G
i
s
c
hư
¢
ng
tr
ì
nh
đã
kha
i
o
b
i
ến
TieuDe
.
V
i
ết
l
nh
i
n
n
i
dung
ca
biến
TieuDe
ra
màn
hình:
-
Trong trường hp này biến TieuDe phi đưc khai báo trước như sau:
TieuDe
DB
8
Truong
DH
Khoa
hoc
Hue$
9
-
Và đoạn lnh gm các lnh sau:
Mov Ah, 09
Mov Ax, Seg TieuDe
Mov DS, Ax
Mov Dx, Offset TieuDe ; có th dùng lnh Lea TieuDe
lOMoARcPSD| 36066900
Int 21h
Trong th tế, vi các chư¢ng trình h¢p ng
viết dng đon gin đ¢n, thì không cn đưa địa ch
Segment ca biến cn in vào DS. Bi vì:
-
Đối vi các chư¢ng trình dng COM:
-
Đối vi các chư¢ng trình dng EXE:
2: Gi s biến TieuDe đã đưc khai báo như sau:
TieuDe
DB
8
Khoa
CNTT
Truong
DHKH
Hue
$9
Các lnh sau ch in các t <Truong DHKH Hue= t biến TieuDe ra màn hình:
Mov Ax, Segment TieuDe
Mov DS, Ax
Mov Dx, TieuDe
Add Dx, 11
Mov Ah, 09
Int 21h
Các lnh sau ch in các t <Khoa CNTT= t biến TieuDe ra màn hình:
Mov Ax, Segment TieuDe
Mov DS, Ax
Mov Dx, TieuDe
Mov DI, Dx
Add DI, 10
Mov
Byte PTR DS:[DI], 8$9
Mov Ah, 09
Int 21h
3: Gi s ti địa ch 0A00:0100 trong b nh cha mt xâu t ASCII, gm 50 t. Các
lnh sau đây s inu t nói trên ra màn hình.
Mov Ax, 0A00h
Mov DS, Ax
Mov Dx, 0100h
;
Mov DI, Dx
Mov Cx, 50
Add DI, Cx
lOMoARcPSD| 36066900
Mov
Byte PTR DS:DX,
8$9
;
Mov Ah, 09
Int 21h
;
Ha
`
m
01
a
ng
¿t
21h:
Ta
´
c
dun
g:Nhp mt t t bàn phím vào lưu trong thanh ghi AL. C th là, AL s cha ASCII
ca t ghi trên phím nhp.
S
dung:
Va
`
o:
Ah
=
01
Ra: Al = 0: nếu phím nhp mt trong các phím chc năng
Al = < ASCII ca t ghi trên phím nhp>
C th như sau: Khi chư¢ng trình gi ngt 21h vi hàm 01 thì màn hình s xut hin mt con tr
nhp, đ ngưi s dng nhp vào mt t t bàn phím. Khi đó, nếu ngưi s dng mt trong
các phím chc năng thì AL nhn đưc giá tr 0, nếu ngưi s dng mt phím t nào đó thì AL
nhn đưc ASCII ca t đó.
Chú ý: Hàm 08 ca ngt 21h chc năng tư¢ng t hàm 01 ngt 21h nhưng t trên phím
không
xut
h
i
n
trên
n
h
ình
,
tt
c
đều
đư
c
xut
h
i
n
b
i
k
í
t
8
*
9
.
Vi
´
du
1:
Mov Ah, 01 ; vi hai lnh này màn hình s xut hin con tr
Int 21h ; nhp để người s dng nhp mt t vào AL
2: Các lnh sau đây cho phép nhp mt u t, vi s ng t đưc n định trước, vào
biến LuuXau đã khai báo trước trong chư¢ng trình
Gi s biến LuuXau đưc khai báo như sau:
LuuXau
DB
30
Dup
(
8
8
)
Các lnh:
Mov Ax, Seg LuuXau
Mov DS, Ax
Lea DI, LuuXau
;
Mov Cx, 30
Mov Ah, 01
Nhap_Xau:
lOMoARcPSD| 36066900
Int 21h
Mov Byte PTR DS:[DI], Al
INC DI
Loop Nhap_Xau
;
Trong trường hp này chúng ta đã gi s: Người s dng ch nhp các t (gõ phím t để nhp),
không nhp các phím chc năng.
Trong thc tế, không bao gi chúng ta s dng hàm 01 ngt 21h để nhp xâu, tn ti hai hn
chế: không th kết thúc nhp bng cách phím Enter; s t ca xâu nhp phi đưc n định
trước trong chư¢ng trình. Đ khc phc, MSDOS cung cp hàm 0Ah ca ngt 21h để h tr nhp
xâu t.
Ha
`
m
0Ah
a
ng
¿t
21h:
Ta
´
c
dun
g:Nhp mt xâu t o mt biến đm cho trước trong chư¢ng trình, biến này phi đưc
ch bi cp thanh ghi DS:DX. biến đm phi dng như sau:
-
Byte 0: cha s t ti đa ca xâu nhp vào
-
Byte 1: cha mt tr không (= 0)
-
Byte 2, byte 3, byte 4, ... cha mt tr rng trng), đ cha các t s đưc nhp vào sau
này (khi chư¢ng trình thc hin).
Để đưc mt biến như trên chư¢ng trình phi khai báo biến (tên biến Xau_Nhap) như sau:
Xau_Nhap
DB
256,
0,
256
Dup
(
8
8)
Như vy Xau_Nhap mt biến kiu byte, gm 258 byte. Byte đầu tiên (byte) cha tr 256, byte 1
cha tr 0, 256 byte tiếp theo cha t trng, đưc s dng để cha các t s đưc nhp sau
này. Xau_Nhap cha ti đa 256 t.
Cũng th s dng hàm 0Ah/21h để nhp mt xâu t vào vùng nh địa ch xác định trong
nh.
S
dung:
Va
`
o:
Ah
=
0Ah
DS:DX = a ch Segment:Offset ca xâu nhp>
Ra: DS:DX không thay đổi
Biến đm bây gi dng như sau:
-
Byte 0: không thay đổi
-
Byte 1: cha tng s t đã đưc nhp vào
-
Byte 2, byte 3, byte 4, ... cha các t đã đưc nhp vào.
lOMoARcPSD| 36066900
Vi
´
du
1:
V
i
kha
i
o
biến
đệm
Xau_Nhap
nh
ư
trên,
nếu
sau
y
c
hư
¢
ng
tr
ình
nhp
vào
xâu:
<
T
i
n
hoc= thì:
-
Byte 0: vn cha s 256
-
Byte 1: cha giá tr 7, đó chính 7 t trong xâu <Tin hoc=
-
T byte 2 đến 8 cha ln t các t trong xâu <Tin hoc.
2: Gi s chư¢ng trình đã khai báo xâu TieuDe như sau:
TieuDe
DB
100,
0,
100
Dup
(
8
8
)
Các lnh sau đây s dng hàm 0Ah/21h đ nhp mt xâu t vào biến TieuDe:
Mov Ax, Seg TieuDe
Mov Ds, Ax
Lea Dx, TieuDe
Mov Ah, 0Ah
Int 21h
Các lnh sau đây ly s t thc s nhp đưa vào lưu tr trong thanh ghi Cx:
Mov Cx, 0
Mov Cl, TieuDe[1]
Các lnh sau đây s dng hàm 02/21h để in u t va nhp ra li màn hình:
Lea DI, TieuDe
Mov Cx, 0
Mov Cl, TieuDe[1]
Add DI, 2
Mov Ah, 02
Lap_In:
Mov Dl, DS:[DI]
Int 21h
INC DI
Loop Lap_In
Các lnh sau đây s dng hàm 09/21h để in xâu t va nhp ra li màn hình:
Mov Ax, Seg TieuDe
Mov Ds, Ax
Lea Dx, TieuDe
lOMoARcPSD| 36066900
Add Dx, 2
Mov DI, Dx
Mov Cx, 0
Mov Cl, TieuDe[1]
Add DI, Cx
Mov
Byte PTR DS:[DI], 8$9
Mov Ah, 09h
Int 21h
3: Chư¢ng trình dng COM sau đây s dng hàm 0Ah ngt 21h để nhp mt xâu t vào
biến Buff. Sau đó s dng hàm 09h ngt 21h để in xâu t va nhp ra li màn hình.
Để
đ
¢
n
gin,
c
hư
¢
ng
trình
kha
i
o
biến
Buff
gm
tn
k
í
t
8
$9
,
nh
đó,
khi
dùng
m
09h/21h
để
in ra chư¢ng trình không cần đưa thêm kí t
8$9
vào cui xâu nhp, mà ch cn tr DS:DX v đầu
vùng/xâu t cn in ra.
.Model small
.Code
ORG 100h
Start:
JMP Main
TBN DB 'Nhap vao mot xau ki tu: $'
TBX DB 0Ah,0Dh,'Xau vua nhap: $'
Buff DB 100,0,100 Dup ('$')
Main Proc
Mov Ah, 09h
Lea Dx, TBN
Int 21h
;
Mov Ah, 0Ah
Lea Dx, Buff
Int 21h
;
Mov Ah, 09h
Lea Dx, TBX
lOMoARcPSD| 36066900
Int 21h
;
Mov Ah, 09h
Lea Dx, Buff
Add Dx, 2
Int 21h
;
Int 20h
Main Endp
End Start
Mßt dā:
Vi
´
du
1:
G
i
s
m
X
ca
ngt
Y
khi
đư
c
g
i
s
tr
v
trong
cp
thanh
ghi
ES:SI
địa
ch
ca
vùng
nh cha tên ca nhà sn xut (nhãn hiu) ca vi x lý đang s dng trên máy tính hin ti, tên này
dài không quá 8 t.
Các lnh sau đây s in tên nhà sn xut nói trên ra màn hình:
Mov
Ah, X
; hàm cn gi đưc đưa o thanh ghi ah
Int
Y
; gi ngt Y vi hàm X
;
Mov Cx, 8 ; tên dài không quá 8 t
Mov Ah, 02 ; dùng hàm 02/21h để in t ra nàm nh
LapIn:
Mov Dl, Byte PTR ES:[SI]
Int 21h
INC SI ; đến t tiếp theo
Loop LapIn
;
2: Gi s hàm X ca ngt Y khi đưc gi vi AL = 1 (được gi m con) s tr v trong cp
thanh ghi ES:DI địa ch ca vùng nh cha ngày-tháng-năm sn xut ROM-BIOS đang s dng trên
máy tính hin ti. Đồng thi hàm/ngt này cũng cho biết s t trong xâu ngày-tháng-năm trong
thanh ghi BX.
Các lnh sau đây s in xâu ngày-tháng-m nói trên ra màn hình:
Mov Ah, X ; hàm cn gi đưc đưa o thanh ghi ah
Mov Al, 1 ; gi hàm X vi Al = 1
lOMoARcPSD| 36066900
Int Y ; gi ngt Y vi hàm X
;
Mov Cx, Bx ; đưa s t ca xâu ngày-tháng-nămvào Cx
Mov Ah, 02 ; dùng hàm 02/21h để in t ra nàm hình
LapIn:
Mov Dl, Byte PTR ES:[DI]
Int 21h
INC DI ; đến t tiếp theo
Loop LapIn
;
3: Hàm 39h ca ngt 21h đưc s dng để to thư mc con trên đĩa. Hàm này quy định:
DS:DX cha xâu n thư mc cn to, bao gm c đưng dntìm đến thư mc y, xâu này kết thúc
bi tr 0. Nếu vic to không thành công thì Cf = 1, khi đó thanh ghi Ax s cha li.
Các lnh sau đây sẽ to ra thư mc con BTCB trong thư mc ASSEM trên thư mc gc đĩa D.
Chư¢ng trình phi khai báo biến TenTM, cha xâu tên thư mc cn to như sau:
TenTM
DB
8
D:\ASSEM\BTCB
9
,0
Các lnh:
Mov Ax, Seg TenTM
Mov DS, Ax
Mov Dx, Offset TenTM
Mov Ah, 39h
Int 21h
;
Jc TB_Loi ; nếu CF = 1 thì vic to b li
<In ra thong bao hoan thanh>
Jmp KetThuc
TB_Loi:
<In ra thong bao khong tao duoc thu muc>
KetThuc:
...
;
T
lOMoARcPSD| 36066900
1: Gi s hàm X ca ngắt Y khi được gi s tr v trong cặp thanh ghi ES:SI đa ch ca vùng
nh cha tên ca nhà sn xut (nhãn hiu) ca vi x đang s dng trên máy tính hin ti, tên này
dài không quá 8 t.
Các lnh sau đây s in tên nhà sn xut nói trên ra màn hình:
Mov Ah, X ; hàm cn gi được đưa vào thanh ghi ah
Int Y ; gi ngt Y vi hàm X
;
Mov
Cx, 8
; tên dài không quá 8 t
Mov
Ah, 02
; dùng hàm 02/21h đ in t ra nàm hình
LapIn:
Mov Dl, Byte PTR ES:[SI]
Int 21h
INC SI ; đến kí t tiếp theo
Loop LapIn
;
2: Gi s hàm X ca ngt Y khi đưc gi vi AL = 1 (được gi hàm con) s tr v trong cp
thanh ghi ES:DI địa ch ca vùng nh cha ngày-tháng-năm sn xut ROM-BIOS đang s dng trên
máy tính hin ti. Đồng thi hàm/ngt này cũng cho biết s t trong xâu ngày-tháng-năm trong
thanh ghi BX.
Các lnh sau đây s in xâu ngày-tháng-m nói trên ra màn hình:
Mov
Ah, X
; hàm cn gi được đưa vào thanh ghi ah
Mov
Al, 1
; gi hàm X vi Al = 1
Int
Y
; gi ngt Y vi hàm X
;
Mov
Cx, Bx
; đưa s t ca xâu ngày−tháng−nămvào Cx
Mov
Ah, 02
; dùng hàm 02/21h đ in t ra nàm hình
LapIn:
Mov Dl, Byte PTR ES:[DI]
Int 21h
INC DI ; đến kí t tiếp theo
Loop LapIn
;
lOMoARcPSD| 36066900
3: Hàm 39h ca ngt 21h đưc s dng để to thư mc con trên đĩa. Hàm này quy định:
DS:DX cha xâu n thư mc cn to, bao gm c đưng dntìm đến thư mc này, xâu này kết thúc
bi tr 0. Nếu vic to không thành công thì Cf = 1, khi đó thanh ghi Ax s cha li.
Các lnh sau đây s to ra thư mc con BTCB trong thư mc ASSEM trên thư mc gc đĩa
D. Chư¢ng trình phi khai báo biến TenTM, cha xâu tên thư mc cn to như sau:
TenTM DB 8D:\ASSEM\BTCB9,0
Các lnh:
Mov Ax, Seg TenTM
Mov DS, Ax
Mov Dx, Offset TenTM
Mov Ah, 39h
Int 21h
;
Jc TB_Loi ; nếu CF = 1 thì vic to b li
‹In ra thong bao hoan thanh>
Jmp KetThuc
TB_Loi:
‹In ra thong bao khong tao duoc thu muc>
KetThuc:
...
;
4: Sau đây chư¢ng trình dng COM: In ra tt c (256) các t trong bng ASCII:
.Model Small
.Code
ORG 100h
Start:
Jmp Main
TB DB 'Noi dung Bang ma ASCII:',0Ah,0Dh,'$'
Main Proc
Mov Ah, 09h
Lea Dx, TB
Int 21h
lOMoARcPSD| 36066900
;
Mov Cx, 256
Mov Ah, 02
Mov Dl, 0
LapIn:
Int 21h
;
Mov Bl, Dl
Mov Dl, ' '
Int 21h
Mov Dl, Bl
;
INC Dl
Loop LapIn
;
Int
20h
Main
Endp
End
Start
5.1: Sau đây chư¢ng trình dng COM: Nhp vào mt xâu t bt k. Sau đó in ra li chính
xâu t va đưc nhp o nhp. S dng hàm 09/21h để in ra.
.Model Small
.Code
Start:
ORG 100h
JMP Main
TBN DB 'Nhap vao mot xau ki tu: $'
TBX DB 0Ah,0Dh,'Xau vua nhap: $'
Buff DB 100,0,100 Dup (' ')
Main Proc
Mov Ah, 09h
lOMoARcPSD| 36066900
Lea Dx, TBN
Int 21h
;
Mov Ah, 0Ah
Lea Dx, Buff
Int 21h
;
Mov Cx, 0
Mov Cl, Buff[1]
Add Dx, 2
Mov DI, Dx
Add DI, Cx
Mov
Byte PTR [DI],
8$9
;
Mov Ah, 09h
Lea Dx, TBX
Int 21h
;
Mov Ah, 09h
Lea Dx, Buff
Add Dx, 2
Int 21h
;
Int 20h
Main Endp
End Start
5.2: Sau đây chư¢ng trình dng EXE: Nhp vào mt xâu t bt k. Sau đó in ra li chính
xâu t va đưc nhp vào nhp. S dng m 02/21h để in ra.
.Model Small
.Stack 100h
lOMoARcPSD| 36066900
.Data
TBN
DB
'Nhap vao mot xau ki tu: $'
TBX
DB
0Ah,0Dh,'Xau vua nhap: $'
Buff
DB
100,0,100 Dup (' ')
.Code
Main Proc
Mov Ax,@Data
Mov DS, Ax
;
Mov Ah, 09h
Lea Dx, TBN
Int 21h
;
Mov Ah, 0Ah
Lea Dx, Buff
Int 21h
;
Mov Cx, 0
Mov Cl, Buff[1]
Add Dx, 2
Mov DI, Dx
;
Mov Ah, 09h
Lea Dx, TBX
Int 21h
;
Mov Ah, 2
Lap_In:
Mov Dl, [DI]
Int 21h
INC DI
lOMoARcPSD| 36066900
Loop Lap_In
;
Mov Ah, 4Ch
Int 21h
Main Endp
End
6:
Sau đây chư¢ng trình dng COM: Nhp vào mt t thường, chư¢ng trình s in ra t
in hoa tư¢ng ng.
.Model Small
.Code
Start:
ORG 100h
Jmp Main
TB1 DB 'Nhap vao mot ki tu thuong: $'
TB2 DB 0Ah,0Dh,'Ki tu hoa tuong ung: $'
Main Proc
Mov Ah, 09h
Lea Dx, TB1
Int 21h
;
Mov Ah, 01
Int 21h
Mov Bl, Al
;
Mov Ah, 09h
Lea Dx, TB2
Int 21h
;
Mov Ah, 02
Mov Dl, Bl
Sub Dl, 20h
lOMoARcPSD| 36066900
Int 21h
;
Int 20h
Main Endp
End Start
7: Sau đây chư¢ng trình dng COM: Nhp vào mt xâu t sau đó in ra li xâu đã nhp
theo th t đảo ngưc.
.Model Small
.Code
Start:
ORG 100h
JMP Main
TBN DB 'Nhap vao mot xau ki tu: $'
TBX DB 0Ah,0Dh,'Xau vua nhap: $'
Buff DB 100,0,100 Dup (' ')
Main Proc
Mov Ah, 09h
Lea Dx, TBN
Int 21h
;
Mov Ah, 0Ah
Lea Dx, Buff
Int 21h
;
Mov Cx, 0
Mov Cl, Buff[1]
;
Mov Ah, 09h
Lea Dx, TBX
Int 21h
;
lOMoARcPSD| 36066900
Lea Dx, Buff
Add Dx, 2
Mov DI, Dx
Add DI, Cx
Dec DI
Mov Ah, 02
Lap_In_Nguoc:
Mov Dl, [DI]
Int 21h
DEC DI
Loop Lap_In_Nguoc
;
Int 20h
Main Endp
End Start
8:,Sau đây chư¢ng trình dng COM: Nhp vào hai s (s th nht: nh h¢n 5; s th hai:
nh h¢n hoc bng 5), sau đó in ra tng ca hai s va nhp.
.Model Small
.Code
ORG 100h
Start:
Jmp
Main
TBN1
DB
'Nhap so hang thu nhat (nho hon 5): $'
TBN2
DB
0Ah,0Dh,'Nhap so hang thu hai (nho hon bang 5): $'
TBX
DB
0Ah,0Dh,'Tong cua hai so la: $'
Main Proc
Mov Ah, 09h
Lea Dx, TBN1
Int 21h
Mov Ah, 01
lOMoARcPSD| 36066900
Int 21h
Mov Bl, Al
Sub Bl, 30h
;
Mov Ah, 09h
Lea Dx, TBN2
Int 21h
Mov Ah, 01
Int 21h
Sub Al, 30h
Add Bl, Al
;
Mov Ah, 09h
Lea Dx, TBX
Int 21h
Mov Ah, 02
Mov Dl, Bl
Add Dl, 30h
Int 21h
;
Int 20
Main Endp
End Start
lOMoARcPSD| 36066900
TP LÞNH ASSEMBLY CŨA INTEL 8088/8086 - (Tiếp theo)
8. Lßnh so sánh:
Cu
´
pha
´
p:
Cmp
[
Toa
´
n
han
g
đ
i
´
ch
]
,
[
Toa
´
n
han
g
ng`
n
]
Trong đo
´
: [T
o
a
´
n
h
ang đ
i
c
´
h
], [T
o
a
´
n
h
a
ng
ngu
ô` n] có th
l
à hng, b
i
ến, thanh gh
i
hay ô nh
.
[Toa
´
n
h
ang đ
i
c
´
h
]
kng th
l
à hng s. [Toa
´
n
h
ang đ
i
c
´
h
] v
à
[T
o
a
´
n
h
a
n
g
ngu
ô` n] không th đồng th
i
l
à ô nh
.
Ta
´
c
dun g: Lnh Cmp (
C
om
p
a
re) đ
ượ
c s
dng để so sánh g
i
á tr
/n
i
dung ca [Toa
´
n
h
a
n
g
đ
i
´
ch] so v
i
[T
o
a
´
n
h
a
ng
ngu
ô` n]. T
ư¢
ng t
nh
ư
l
nh Sub, nó
l
y [Toa
´
n
h
an g đ
i
c
´
h]
tr
đ
i
[Toa
´
n
h
a
ng
ngu
ô` n] nh
ư
ng kết
qu kng
l
àm thay đổ
i
[Toa
´
n
h
ang đ
i
´
ch] mà ch
l
àm thay đổ
i
g
i
á tr
ca mt s c
h
i
u: CF, ZF, OF,...
Kết
qu
so
sánh
ca
l
nh
Cmp
l
à:
[Toa
´
n
hang
đ
i
´
ch]
>
[Toa
´
n
han
g
ng`
n];
[Toa
´
n
han
g
đ
i
´
ch]
g[Toa
´
n
han
g
ng`
n];
[Toa
´
n
han
g
đ
i
´
ch]
<
[Toa
´
n
han
g
nguô`
n];
[Toa
´
n
han
g
đ
i
´
ch]
f[
Toa
´
n
han
g
nguô`
n];
[Toa
´
n
han
g
đ
i
´
ch]
=
[Toa
´
n
han
g
ng`
n];
[Toa
´
n
han
g
đ
i
´
ch]
[Toa
´
n
han
g
ng`
n];...
mi
kết
qu
s
c
động
(0
→1, 1→0) đến mt c ¢ng ng c th nào đó.
Do đó, để biết đưc kết qu so sánh chư¢ng trình phi s dng các lnh kim tra c (đó lnh
nhy), chúng phi đưc đặt ngay sau lnh so sánh. Như vy lnh Cmp s không ý nghĩa khi
đứng độc lp.
th nói ngược li, lnh Cmp đưc s dng để cung cp điu kin nhy (thay đổi giá tr các c)
cho các lnh nhy điu kin.
Vi
´
du
1:
Cmp
Ax, Bx
; so sánh giá t thanh ghi Ax vi Bx
Cmp
Ax, 20
; so sánh giá tr thanh ghi Ax vi 20
Cmp
Ax, [SI]
; so sánh Ax vi ni dung ô nh đưc ch bi SI
Ví dā 2:
Cmp
Al, 8A9
; so sánh giá tr thanh ghi Al vi
8A9
Cmp
Al, Var1
; so sánh giá tr thanh ghi Al vi giá tr biến Var1
Tt c lnh Cmp trên điu không ý nghĩa, không cho biết kết qu so sánh mt cách trc
tiếp phi ánh thông qua các c.
Lnh Cmp không th s dng để sonh hoc kim tra giá tr ca các c.
9. Các lßnh nhy
Lßnh nhy không điu kißn:
Cu
´
pha
´
p:
Jmp
<
V
trí
đíc
h
>
Trong đo
´
:
<V
t
đ
íc
h> có th
l
à nhãn ca mt
l
nh, tên ca mt th tc hoc có th
l
à mt thanh gh
i
, mt ô
nh (đã đưc định nghĩa) nào đó. <V trí đích> cũng th mt biến nào đó, giá tr ca thường địa
ch ca mt ô nh trong đon Code.
lOMoARcPSD| 36066900
Ta
´
c
dun g
:
Khi
gp
l
nh này ch
ư¢
ng t
rìn
h chuyn đ
i
u kh
i
n (nhảy đến) đến th
c
h
i
n
l
nh sau <Nhãn
đích> mà không phụ thuc vào bt k điu kin nào.
chế thc hin ca lnh Jmp thay đổi ni dung ca cp thanh ghi con tr lnh CS:IP. CS:IP mi
s địa ch ca lnh sau <Nhãn đích> trong b nh.
Lnh Jmp 3 dng: Short, Near Far. Đối vi dng Short Far tch thanh ghi IP b thay đổi
khi lnh thc hin, ngưc li, vi dng Far, khi lnh thc hin thì c thanh ghi IP thanh ghi đon
CS đều b thay đổi. Hay nói cách khác: Đi vi dng Short Near thì lnh Jmp <V trí đích> phi
nm trong cùng Segment nh, ngưc li, vi dng Far thì lnh Jmp <V trí đích> th nm các
Segment nh khác nhau.
Vi
´
du
1:
Start:
Jmp Main
T
i
euDe
DB
8
Khoa
CNTT
DHHH9
Main Proc
..................
Main
Endp
End
Start
Ví dā 2:
Jmp
short
Main
Jmp
Jmp
Ax
word
PTR
[BX]
Jmp
dword
PTR
[BX]
Ví dā 3:
Reset DD 5BE000F0h
Jmp Reset
Ví dā 4:
Mov Ax, 15
Mov Bx, 20
Jmp TTong
Add Ax, Bx
TTong:
Sub Ax, Bx
Mov Cx, Ax
lOMoARcPSD| 36066900
Kết thúc đon lnh trên Cx = Ax = -5, lnh Add Ax, Bx không đưc thc hin. Khi gp
lnh Jmp TTong chư¢ng trình nhy đến thc hin lnh sau nhãn TTong, đó chính
lnh Sub Ax, Bx.
Lßnh nhy điu kißn:
Cu
´
pha
´
p
chung:
<L
ßnh
nhy
điu
ki
ßn>
<
V
trí
đíc
h
>
Trong đo
´
:
<V
t
đ
íc
h>: T
ư¢
ng t
nh
ư
l
nh Jmp.
Ta
´
c
dun g: Kh
i
gp mt
l
nh nhy đ
i
u k
i
ện, đầu t
i
ên ch
ư
¢ng
t
rìn
h s k
i
m tra đ
i
u k
i
n nhy ca nó,
nếu tha mãn thì s nhảy đến thc hin lnh <V trí đích>, nếu không thì b qua không thc hin lnh
nhy này.
Điu kin nhy ca các lnh nhy này chính s thay đổi giá tr ca các c hiu, do đó để to điu
kin nhy cho mt lnh nhy xác định thì chư¢ng trình phi làm thay đổi giá tr ca c hiu tư¢ng
ng vi . Chư¢ng trình thường dùng các lnh địch bít, quay bít, so sánh,... để làm thay đi giá tr
các c hiu để to điu kin nhy cho các lnh nhay. Cách đ¢n gin nht s dng lnh Cmp ngay
trước lnh nhy.
Sau đây các lßnh nhy điu kißn vái d lißu d¿u:
Lnh JG: Nhy nếu [Đích] > [Ngun] ; (SF = 0F ZF = 0)
Lnh JL: Nhy nếu [Đích] < [Ngun] ; (SF <> 0F)
Lnh JGE: Nhy nếu [Đích] g[Ngun] ; (SF = 0F)
Lnh JLE:
Nhy nếu [Đích] f[Ngun] ; (CF <> 0F ZF = 1)
... <còn nhiu lnh khác>
Trong
đó:
[Đíc
h]
[Ngun]
c
hín
h
l
à
ha
i
toán
hng:
[Toa
´
n
han
g
đ
i
´
ch]
[Toa
´
n
han
g nguô` n] trong
lnh Cmp đứng ngay trước lnh nhy. Tc là, chư¢ng trình s dng lnh Cmp để to điu kin nhy
cho các lnh này. C th: lnh nhy thc hin đưc hay không (có chuyn điu khin đến <V trí
đích> hay không) ph thuc vào giá tr ca [Đích] [Ngun] trong lnh Cmp đứng ngay trước nó.
Vi vic s dng lnh Cmp để to điu kin nhy cho các lnh nhy thì ta không cn quan tâm đến
các c điu kin nhy ca chúng.
Sau đây các lßnh nhy điu kißn vái d lißu không d¿u:
Lnh JA: Nhy nếu [Đích] > [Ngun] ; (CF = 0 ZF = 0)
Lnh JB: Nhy nếu [Đích] < [Ngun] ; (CF = 0)
Lnh JNA: Nhy nếu [Đích] không ln h¢n [Ngun]; (CF =1 or ZF =1)
Lnh JNB: Nhy nếu [Đích] không nh h¢n [Ngun] ; (CF = 0)
Các lnh nhy vi d liu du th áp dng vi các d liu không du.
Sau đây các lßnh nhy điu kißn dùng chung:
Lnh JC: Nhy nếu c CF = 1
Lnh JNC: Nhy nếu c CF = 0
Lnh JZ: Nhy nếu c ZF = 1
lOMoARcPSD| 36066900
Lnh JNZ: Nhy nếu c ZF = 0
Lnh JE: Nhy nếu [Đích] = [Ngun]; Tư¢ng t JZ; (ZF = 1)
Lnh JNE: Nhy nếu [Đích] ≠[Nguồn]; Tư¢ng t JNZ; (ZF = 0)
... <còn nhiu lnh khác> [2 - 150]
Vi các lnh này, chư¢ng trình thưng s dng các lnh dch bít hoc lnh quay bít để to điu kin
nhy nó.
dā 1a: Dãy lnh sau đây thc hin vic gán giá tr cho thanh ghi Cx da vào giá tr ca thanh ghi
Ax Dx:
Mov Ax, 12
Mov Dx, 25
;
Cmp
Ax, Dx
; Ax ? Bx
Jg
Nhan1
; nếu Ax > Dx
Jle
Nhan2
Nhan1:
Mov
Cx, Ax
Jmp
Tiep_Tuc
Nhan2:
Mov
Cx, Dx
Jmp
Tiep_Tuc
Tiep_Tuc:
Mov
Bx, Cx
;
th thy, đây không cn dùng lnh Jle Nhan2, nếu Ax không ln h¢n Dx thì chc chn
s nh h¢n hoc bng Dx. Ngoài ra cũng không cần dùng lnh Jmp Tiep_Tuc sau nhãn Nhan2,
vic chuyn đến lnh sau nhãn Tiep_Tuc đây tt nhiên. thế đon lnh trên th đưc viết
rút gn như trong 1b sau đây.
1b: Dãy lnh sau đây trưng hp rút gn ca dãy lnh trên:
Mov Ax, 12
Mov Dx, 25
;
Cmp Ax, Dx
Jg Nhan1 ; nếu Ax > Dx
lOMoARcPSD| 36066900
Mov Cx, Dx
; khi Ax
fDx
Jmp Tiep_Tuc
Nhan1:
Mov Cx, Ax ; khi Ax > Dx
Tiep_Tuc:
Mov Bx, Cx
;
Trong c hai d trên: khi kết thúc, Bx = Cx = Dx = 25. Nhưng nếu cho
Ax = 120 (Ax > Bx) thì Bx = Cx = Ax = 120.
Ví dā 2: Gi s ti địa ch 0A000:0100 trong b nh cha mt mng các s nguyên kiu byte,
gm 100 phn t (100 byte).
Các lnh sau đây tính tng ca các phn t trong mng này giá tr ca ln h¢n 123. Kết qu
cha thanh ghi Dx.
Mov Ax, 0A000h
Mov DS, Ax
Mov DI, 0100h
;
Mov Dx, 0
Mov Cx, 100
Lap_TT:
Mov Al, Byte PTR DS:[DI]
Cmp Al, 123
Jle Tiep_Tuc
Add Dx, Al
Tiep_Tuc:
INC DI ; tr đến phn t kế tiếp
Loop Lap_TT ; lp li: kin tra tính tng
;
3: Gi s ti địa ch 0C000:00120 trong b nh cha mt xâu t, xâu này đưc kết thúc
bi giá tr 0 (s 0).
Các lnh sau đây sẽ đếm xem xâu nói trên gm bao nhiêu t. Kết qu ghi vào ô nh ngay trước
vùng nh cha xâu này:
Mov Ax, 0C000h
lOMoARcPSD| 36066900
Mov ES, Ax
Mov DI, 00120h
Mov SI, DI
;
Mov
Lap_Dem:
Mov
Dx, 0
Al, Byte PTR ES:[DI]
Cmp
Al, 0
; so sánh Al vi 0
Je
KetThuc
; nếu Al = 0: đã đến cui xâu
INC
Dx
; khi Al <> 0: đếm
INC
DI
; tr đến t kế tiếp
Jmp
Lap_Dem
; lp li: kin tra đếm
KetThuc:
Mov Byte PTR DS:[SI - 1], Dx
;
Ví dā 4: Các lnh sau đây in ni dung bn bn ASCII ra màn hình, nhưng không in ra các t có mã
07h, 0Ah, 0Dh.
Mov Cx, 256
Mov Ah, 02
Mov Dl, 0
Lap_In:
Cmp Dl, 07h
Je TTuc
Cmp Dl, 0Ah
Je TTuc
Cmp Dl, 0Dh
Je TTuc
Int 21h
TTuc:
INC DL
Loop Lap_In
lOMoARcPSD| 36066900
;
5: Các lnh sau đây cho phép nhp mt xâu t bt k, dài không quá 200 t, t bàn phím
vào biến XauNhap. Sau đó copy các t ch cái in hoa trong xâu va nhp o biến XauHoa.
Trước hết chư¢ng trình phi khai báo các biến:
XauNhap
DB
200,
0,
200
Dup
(
8
9
)
XauHoa
DB
200
Dup
(
8
9
)
Các lnh:
Mov Ax, Seg XauNhap
Mov DS, XauNhap
Mov Dx, Offset XauNhap
Mov Ax, Seg XauHoa
Mov ES, XauHoa
Mov DI, Offset XauHoa
;
Mov Ah, 0Ah
Int 21h
;
Mov Cx, 0
Mov Cl, XauNhap[1]
Mov SI, Dx
Add SI, 2
;
Lap_Copy:
Mov Al, DS:[SI]
Cmp
A
l
,
8
A
9
Jl TTuc
Cmp
A
l
,
8
Z
9
Jg TTuc
Mov ES:[DI], Al
INC DI
TTuc:
lOMoARcPSD| 36066900
INC SI ;
Loop Lap_Copy
;
n nh, trong bng ASCII các t ch cái in hoa nm nhng v trí liên tiếp nhau: A, B, C,
..., Z, chúng ln t 65, 66, 67, ..., 90.
6: Gi s ti địa ch 0F000:FFFE trong b nh ROM-BIOS cha mt byte d liu. Byte này
cho biết loi ca máy tính đang s dng. C th, nếu byte này: cha tr 0FBh: máy PC/XT; cha tr
0FCh: máy PC/AT; cha tr 0FFh: máy PC classic;...
Các lnh sau đây cho biết máy tính đang s dng thuc loi máy nào:
Trưc hết chư¢ng trình phi khai báo các biến tr li:
TB1
DB
8
Day
l
a
may
PC/XT
.$9
TB2
DB
8
Day
l
a
may
PC/AT
.$9
TB3
DB
8
Day
l
a
may
PC
c
l
ass
i
c
.$9
Các lnh:
Mov Ax, 0F000h
Mov ES, Ax
Mov SI, 0FFFEh
;
Mov Al, Byte PTR ES:[SI]
Cmp Al, 0FBh
Je TraLoi1
Cmp Al, 0Fch
Je TraLoi2
Cmp Al, 0Ffh
Je TraLoi3
...
TraLoi1:
Mov Ax, Seg TB1
Mov DS, Ax
Lea Dx, Offset TB1
Mov Ah, 09
Int 21h
lOMoARcPSD| 36066900
Jmp KetThuc
TraLoi2:
Mov Ax, Seg TB2
Mov DS, Ax
Lea Dx, Offset TB2
Mov Ah, 09
Int 21h
Jmp KetThuc
TraLoi1:
Mov Ax, Seg TB3
Mov DS, Ax
Lea Dx, Offset TB3
Mov Ah, 09
Int 21h
Jmp KetThuc
.....
KetThuc:
Mov Ah, 4Ch
Int 21h
;
th nói, d trên đây mt thao tác đin hình trong lp trình h¢p ng. cũng cho thy chc
năng thế mnh ca ngôn ng này. Đây cũng mc tiêu ngưi lp trình h¢p ng
nhm ti.
Vic truy xut vào các vùng nh d liu để ly các byte/word thông tin cu hình h thng mt yêu
cu bn vi các ngôn ng lp trình cp thp, đưc thc hin mt cách khá đ¢n gin trong
ngôn ng h¢p ng. d trên đây cũng cho thy nguyên tc để làm vic này.
10. Các lßnh Dch bít Quay bít
Các lnh dch bít các lnh làm cho các bít trong mt thanh ghi b dch v bên trái (lnh ShR) hoc
v bên phi (lnh ShL) mt hoc nhiu bít. Lnh quay bít làm cho các bít trong mt thanh ghi quay
theo <chiu trái= hoc theo <chiu phi= mt hoc nhiu bít. Thông thường các bít đưc dch hay đưc
quay đều ln t đưc đưa qua cờ CF. Do đo, các lnh dch bít và quay bít thường được s dng
để kim tra giá trt (= 0 hay = 1) ca các bít trong thanh ghi.
H¢p ng
cung cp hai dng lnh quay bít, quay không qua c CF (lnh RcL Rcl) quay qua
c CF (lnh ShL ShR).
lOMoARcPSD| 36066900
Cu
´
pha
´
p:
Shr [T
o
a
´
n
h
ang đ
i
´
c
h
], <
n
>
Shl [T
o
a
´
n
h
a
ng
đ
i
c
´
h
], <
n
>
Rcr
[T
o
a
´
n
h
ang đ
i
´
c
h
], <
n
>
Rcl [T
o
a
´
n
h
ang đ
i
c
´
h
], <
n
>
Trong
đo
´
:
[Toa
´
n
han
g
đ
i
´
ch]
l
à
mt
thanh
ghi
8
b
í
t
hoc
16
t.
<n>
l
à
s
b
ít
cn
d
ch,
nếu
<n>
=
1
thì ch định trc tiếp trong câu lnh, nếu <n> ln h¢n 1 phi ch định thông qua thanh ghi CL.
Ta
´
c
dung:
Lnh ShR (S
hi
ft
Logi
c
al
R
i
ght):
Dc
h chuyn các b
ít
trong thanh gh
i
[Toa
´
n
h
ang đ
i
´
ch] sang ph
i
mt hoc
nhiu bít. Các bít đưc dch ln t đưc đưa vào c CF, c CF s cha bít ca ln dch cui cùng. Sau
khi dch các bít b khuyết ( bên đối din) s đưc thay bng các bít tr 0. Tc là, vi thanh ghi 8 bít thì
sau 8 ln dch s nhn đưc mt dãy 8 bít = 0, tư¢ng t vi thanh ghi 16 bít thì sau 16 ln dch s
nhn đưc mt dãy 16 bít = 0. Nếu thanh ghi AL = 01001001 thì sau khi b dch v bên trái 2 bít s như
sau: AL = 00100100, khi đó CF = 1.
Lnh ShL (Shift Logical Left): Tư¢ng t như lnh ShR nhưng các bít đưc dch v phía bên trái.
Lnh RCR (Rotate through Carry Right): Tư¢ng t như lnh ShR, nhưng bít đưc dch s đưc đặt vào li
bít b khuyết bên đối din. Tc là, vi thanh ghi 8 bít thì sau 8 ln dch s nhn li dãy bít ban đầu,
tư¢ng t vi thanh ghi 16 bít thì sau 16 ln dch s nhn li dãy bít ban đầu. Nếu thanh ghi AL
= 01001001 thì sau khi b quay v bên trái 2 bít s như sau: AL = 00100101, khi đó CF = 1.
Lnh RCL (Rotate through Carry Left): Tư¢ng t như lnh RCR nhưng các bít đưc quay v phía bên trái.
Ví dā 1:
Shr Al, 1
Mov Cl, 2
Shr Al, CL
Shl Bl, CL
Rcl AL, CL
Rcr Dl, 1
Ví dā 2: Các lnh sau đây đếm s bít bng 1 trong thanh ghi BX, kết qu cha thanh ghi Al
không làm thay đổi giá tr ca nó:
Mov Al, 0
Mov Cx, 16
DemBit1:
Rcl Bx, 1
Jnc TiepTuc
lOMoARcPSD| 36066900
Inc Al
TiepTuc:
Loop DemBit1
;
3: Các lnh sau đây đếm s bít ging nhau (tư¢ng ng) gia hai thanh ghi Ax Bx. Kết qu
cha trong biến Dem (Dem DB 0):
Mov Dem, 0
Xor Ax, Bx
Mov Cx, 16
KTra:
Shl Ax, 1
Jnc Bit_0
Jmp TiepTuc
Bit_0:
Inc Dem
TiepTuc:
Loop KTra
;
Ví dā 4: Các lnh sau đây in ni dung ca thanh ghi BX ra màn hình i dng nh phân:
Mov
Cx, 16
; lp in đủ 16 bít
Mov
Ah, 02
; in ra t vi hàm 02/21h
In_NhiPhan:
Shl Bx, 1 ; dch trái để bít cn in r¢i vào c CF
Jc In_1 ; lnh JC nhy khi c CF = 1
Mov
Dl, 809
; CF = 0 tc là bít cn in tr = 0, nên in ra t
809
Int 21h
Jmp In_Tiep
In_1:
Mov
Dl, 819
Int 21h
In_Tiep:
lOMoARcPSD| 36066900
Loop In_NhiPhan
;
5: Các lnh sau đây nhp mt s nh phân t bàn phím đưa vào lưu tr trong thanh ghi BX:
Mov Bx, 0
Mov Cx, 0
Mov Ax, 0
Mov Ah, 1
Nhap:
Int 21h
Cmp Al, 0Dh ; nếu nhp Enter thì kết thúc
Je KetThuc
;
Cmp
Al, 819
Je Them_Bit
Cmp
Al, 809
Je Them_Bit
;
Mov
Mov
Ah,09
Dx, Seg TB
; Biến
TB đưc khai báo như sau:
Mov
DS, Dx
; TB
DB
8Ban phai nhap 0/1
hoac
Enter$
9
Mov
Dx, Offset TB
Int
21h
Jmp
Nhap
Them_Bit:
Sub
Al, 30h
; th s dng lnh And
Al, 0Fh
Shl
Bx, 1
Or
Bx, Al
Inc
Cx
Cmp
Cx, 17
Jne
Nhap
KetThuc:
lOMoARcPSD| 36066900
Mov 4Ch
Int 21h
;
Ví dā 6: Gi s ti địa ch 0B000:0010 trong b nh cha mt byte d liu, cho biết mt s
thông tin liên quan đến cu hình h thng. Byte 3 cho biết máy tính hin ti (byte 3 = 1) hay không
(byte 3 = 0) cng cm USB.
Các lnh sau đây cho biết máy tính hin ti (máy thc hin đon lnh) hay không cng cm
USB. Kết qu đưc thông báo thông qua thanh ghi Cx: Cx = 0: không cng cm USB; Cx =
0FFFFh: có cng cm USB.
Mov Ax, 0B000h
Mov DS, Ax
Mov DI, 0010h
;
Mov Ax, 0
Mov Al, byte PTR DS:[DI]
;
Mov
Cl, 4
Shr
Al, Cl
Jc
CoUSB
; co cong USB
Mov
Cx, 0
; khong co cong USB
Jmp
KetThuc
CoUSB:
Mov
Cx, 0FFFFh
KetThuc:
...
;
Trong thc tế, kết qu kim tra này thường đưc tr li thông qua ngay chính c CF. CF = 0: không
cng USB, CF = 1: cng USB.
Chú ý 1: th s dng lnh dcht ShR/ShL để thc hin phép chia/phép nhân giá tr ca mt
thanh ghi (cha s nguyên không du) vi mt s bi s ca 2.
Ví dā: Hai lnh sau đây s dch AL sang trái 3 bít, tc nhân AL vi 8:
Mov Cl, 3
Shl Al, Cl ; Al ß AL * 8, 8 = 2
3
.
lOMoARcPSD| 36066900
dā: Hai lnh sau đây s dch AL sang phi 3 bít, tc chia AL vi 8:
Mov Cl, 3
Shr Al, Cl ; Al ß AL * 8, 8 = 2
3
.
Chú ý 2: H¢p ng
còn cung cp các lnh dch chuyn s hc SAL (Shift Arithmetic Left) và SAR
(Shift Arithmetic Right) . SAL tư¢ng t hoàn toàn ShL, th s dng để thc hin nhân 2 vi các s
âm.
SAR
¢
ng
t
ShR
nh
ư
ng
t
cui
cùng
ca
[Toa
´
n
hang
đ
i
´
ch]
không
b
thay
bng
t
0
vn
gi nguyên giá tr cũ, th s dng để thc hin chia 2 vi các du.
Các lnh dich bít, quay bít ca các vi x Intel 80286/80386/. .... cho phép viết s bít cn dch, trong
trường hp ln h¢n mt, trc tiếp trong lnh dch, quay không cn thông qua thanh ghi Cl [1
540].
lOMoARcPSD| 36066900
Thanh Ghi
Thanh ghi nằm bên trong CPU tùy theo đi dài 8 hay 16 bít vàtùy theo chức năng. Khi
đó, thanh ghi đưc dùng để cha d liu, lưu trữ dliu, kết qu trung gian ca máy tính
hoc đơn vị địa ch b nh 8088 14thanh ghi được chia làm 5 nhóm
I.
Nhóm thanh ghi đa dng : (General Register)
Gm 4 thanh ghi đa dng : AX,BX,CX DX (có 16 bít)
Công dng chung ca các thanh ghi này : dùng trong các phép
toán s hc, logic, cha d liu.
Mt thanh ghi 16 bít có th đưc xem là 2 thanh ghi 8bít và
chúng đưc chia như sau :
Thanh ghi
16 bít 2 thanh ghi 8 bít
=========================
Byte cao Byte thp
AX AH AL
BX BH BL
CX CH CL
DX DH DL
==========================
d :
AX = 0x1234
AH = 0x12
AL = 0x34
Mi thanh ghi còn nhng công dng riêng ca :
a.
Thanh ghi AX : (Auxliary Register)
Công dng riêng dùng trong các phép toán s hc, lưu kết
qu ca các phép toán *, chia, ...
b.
Thanh ghi BX : (Base Regiser)
Dùng trong phép định địa ch s ca b nh, nó đóng vai
trò như 1 thanh ghi địa ch offset ca b nh
c.
Thanh ghi CX : (Count Regiser)
Dùng để cha s vòng lặp trong chương trình, nó đóng vai
tròn như một biến đếm cho vic lp vòng. Ngoài ra, thanh ghi
CL còn được dùng trong các phép dch chuyn vi s ln dch
chuyn ni dung ca thanh ghi CL.
d.
Thanh ghi DX : (Data Regiser)
Dùng để lưu trữ kết qu ca phép toán * hoặc /, định địa ch
cng trong các lnh xut nhp cng.
II.
Nhóm thanh ghi đon : (Segiment regiset)
Gm 4 thanh ghi : CS, DS, ES, SS
a.
Thanh ghi CS : (Code Segment)
Dùng để cha địa ch Segment ca đon của đoạn mã
chương trình.
lOMoARcPSD| 36066900
b.
Thanh ghi DS : (Data Segment)
Chứa địa ch Segment ca đoạn d liu
c. Thanh ghi ES : (Extra Segment)
Chứa địa ch Segment của đoạn d liu b sung. Như vậy nếu
ta có hai đoạn d liu thì mt s do thanh ghi DS và hai s do
thanh ghi ES qun
d. Thanh ghi SS (Stack Segment)
Dùng lưu địa ch Segment ca đon Stack
Bn thanh ghi này th truy xut trên bốn đoạn khác nhau.
Như vậy một chương trình làm việc cùng mt lúc tối đa là bn
đon
III.
Nhóm thanh ghi con tr và ch mc :
a.
Thanh ghi SI : (Source Index)
Dùng để tr đến ô nh trong đoạn d liệu định bi thanh ghi
DS, trong x lí chuỗi thanh ghi SI dùng để tr đến địa ch bt
đầu ca chui ngun
b.
Thanh ghi DI : (Distination Index)
Dùng để tr đến ô nh có địa ch Segment đnh bi thanh ghi
ES, trong x lí chuỗi nó dùng để tr đến địa ch ca chuỗi đích
c. Thanh ghi SP : (Stack pointer)
Dùng để tr đến phn t trên đỉnh ca Stack
d. Thanh ghi BP : (Base pointer)
Dùng trong phép định địa ch cơ sở, trong vic truy xut
phn t trên Stack. Nó được dùng trong các phép gọi chương
trình con
e. Thanh ghi IP : (Instruction Pointer)
Cha đến địa ch ô nh đưc định bi thanh ghi CS để ch
đến mã lnh của chương trình. Khi thc thi mt lnh CPU s t
động thay đổi ni dung của thanh ghi IP để tr đến lnh kế tiếp
của chương trình, thanh ghi này không bị tác động trc tiếp bi
các lnh. Vì vy, nó thường không có mt trong nhng lnh ca
hp ng.
Nhng cp thanh ghi thường đi chung :
DS : SI
ES : DI
SS : SP
SS : BP
CS : IP
IV.
Thanh ghi c :
Mục đích của vic s dng c là vic ch ra trng thái ca CPU.
Để làm được điều đó bộ vi x lí đã dành riêng ra mt thanh ghi
gi là thanh ghi c. Nhng bit trên thanh ghi này đưc gi là các
c . hai loi c : C trng thái, c điu khin
C trng thái phn ánh kết qu ca phép toán
C điu khin dùng để cho phép hay không cho phép mt thao tác
nào đó
lOMoARcPSD| 36066900
Chúng ta ch quan tâm đến nhóm c trng thái gm 6 c :
CF, AF, SF, OF, PF, ZF.
a.
C CF : (Carry Flag) " C nh "
C CF được bt lên mt nếu kết qu của phép toán có mưn
hay nh đối vi bít cao
b.
C AF : (Awiliary Flag) " C nh ph "
Bt lên một khi có mượn hay có nh bít 3
c. C SF : (Sign Flag) " C du "
C SF được bt lên mt nếu như kết qu ca mt phép tính có
bít cao nht bng mt (s âm)
d.
C OF : (Over Flag) " C tràn "
Đưc bt lên mt nếu như kết qu ca phép toán có du b sai
d :
01010000 = AL (dương)
+ 01110000 = BL (dương)
11000000
e.
C PF : (Parity Flag) " C chn le "
C PF được bt lên mt nếu như kết qu ca mt phép toán có
tng 8 bít thp mt s chn
f.
C ZF : (Zero Flag)
ZF = 1 nếu như kết qu ca phép toán bng không
d :
AX = FFFFh
+
BX = FFFFh
1FFFEh
| 1/68

Preview text:

lOMoAR cPSD| 36066900
BƯỚC ĐẦU VỚI LẬP TRÌNH ASSEMBLY TRÊN VI XỬ LÝ 8088/8086
1. Giái thiệu về hợp ngữ:
Hợp ngữ (Assembly) là một ngôn ngữ lập trình cấp thấp, nó thực chất là dạng gợi nhớ (Mnemonic),
hay dạng kí hiệu, của ngôn ngữ máy.
Như đã biết, lệnh ngôn ngữ máy là một dãy các con số 0, 1 nên rất khó đọc và khó lập trình, vì thế
các nhà thiết kế vi xử lý đã đưa ra tập lệnh hợp ngữ gần với ngôn ngữ tự nhiên h¢n nên dễ đọc và dễ
lập trình h¢n. Tuy vậy, các lệnh hợp ngữ vẫn giao tiếp với phần cứng máy tính một cách rất chặt chẽ,
nhờ đó việc tiếp cận với lập trình hợp ngữ giúp chúng ta hiểu rõ h¢n về kiến trúc và tổ chức hoạt động của máy tính.
Ngoài ra nó còn giúp chúng ta thấy rõ h¢n mối quan hệ giữa các thành phần chức năng bên trong
máy tính và hệ điề hành. Có thể nói ngược lại là, việc tìm hiểu và lập trình trên hợp ngữ giúp chúng ta
hiểu rõ h¢n về kiến trúc máy tính, tổ chức hoạt động bên trong máy tính và hệ điều hành.
Trong giới hạn của tài liệu này chúng ta chỉ tìm hiểu tập lệnh hợp ngữ của các vi xử lý họ Intel
8088/8086, để lập trình chạy trên các máy IBM-PC: Sử dụng họ vi xử lý này và hoạt động trong sự
phối hợp với hệ điều hành MS_DOS.
Một trong những đặc điểm của hợp ngữ là chư¢ng trình viết trên nó có kích thước nhỏ h¢n và tốc độ
nạp/thực hiện chư¢ng trình nhanh h¢n so với viết (chư¢ng trình cùng chức năng) trên các ngôn ngữ lập trình bậc cao.
Ngoài ra, hầu hết các ngôn ngữ lập trình bậc cao hiện nay đều cho phép viết (ngữ trong nó. Điều này giúp người lập trình khai thác tối đa thế mạnh của các ngôn ngữ lập trình,
hợp ngữ rất mạnh trong các thao tác can thiệp sâu vào các thành phần bên trong hệ thống, trong khi
đó ngôn ngữ bậc cao mạnh trong các thao tác xử lý dữ liệu và thiết kế giao diện. Như vậy sẽ là rất
thuận lợi nếu sử dụng ngôn ngữ bậc cao để viết chư¢ng trình xử lý thông tin hệ thống, khi đó nhiệm
vụ truy xuất hệ thống (thanh ghi, bộ nhớ, cổng vào/ra, thiết bị,...) để lấy dữ liệu sẽ được giao cho các
đoạn mã lệnh hợp ngữ được nhúng trong chư¢ng trình này.
Hợp ngữ hỗ trợ 2 chế độ tư¢ng tác hệ thống: (1) Nhập trực tiếp từng lệnh/đoạn lệnh vào bộ nhớ rồi
cho phép thực hiện ngay trên bộ nhớ mà không cần qua bước biên dịch chư¢ng trình. Chư¢ng trình
gỡ rối Debug (đi kèm hệ điều hành MS_DOS: Debug.exe) là một trong những chư¢ng trình hỗ trợ
chế độ này cho hợp ngữ 16 bít; (2) Viết chư¢ng trình hợp ngữ, rồi sau đó sử dụng các chư¢ng trình
biên dịch để dịch nó sang chư¢ng trình thực thi (dạng EXE hoặc COM) và cho thực hiện chư¢ng trình này.
Hiện nay có hai loại trình biên dịch được sử dụng để biên dịch chư¢ng trình hợp ngữ (từ tập lệnh
hợp ngữ của các vi xử lý họ Intel) sang chư¢ng trình thực thi: Trình biên dịch hợp ngữ 16 bít, MASM
(Macro Assembler), được sử dụng để dịch thành các chư¢ng trình chạy trên nền hệ điều hành 16 bít
MS_DOS; Trình biên dịch hợp ngữ 32 bít, MASM32 (Macro Assembler 32 bít), được sử dụng để dịch
thành các chư¢ng trình chạy trên nền hệ điều hành 32 bít MS_Windows. Trong thực tế, để chuyển
một chư¢ng trình hợp ngữ sang dạng chư¢ng trình thực thi EXE 16 bít hoặc COM 16 bít thì cần phải
có sự hỗ trợ của chư¢ng trình tiện ích của hệ điều hành MS_DOS: Link (Link.exe) và EXE2Bin (EXE2Bin.com). lOMoAR cPSD| 36066900
Chư¢ng trình hợp ngữ 16 bít sử dụng hệ thống các ngắt mềm (Interrupt) của BIOS và DOS như là
thư viện lập trình của nó, trong khi đó chư¢ng trình hợp ngữ 32 bít sử dụng tập hàm API làm thư viện lập trình của nó.
2. Biến – Hằng trong chương trình hợp ngữ: Biến và hằng
Biến và hằng (hằng có tên) trong chư¢ng trình hợp ngữ có tính chất, mục đích sử dụng, kiểu dữ liệu,
quy tắc đặt tên, quy tắc gán giá trị,... tư¢ng tự như biến và hằng trong các ngôn ngữ lập trình bậc cao
khác. Biến trong chư¢ng trình hợp ngữ chỉ có các kiểu dữ liệu là: Byte, Word, Doubleword,... và hằng
trong chư¢ng trình hợp ngữ có thể là số, kí tự hoặc một xâu kí tự.
Khi viết chư¢ng trình hợp ngữ chúng ta cần quan tâm đến địa chỉ của biến trong bộ nhớ. Một biến
được khai báo trong chư¢ng trình sẽ được hệ thống gán cho một địa chỉ trong bộ nhớ (khi chư¢ng
trình được nạp vào bộ nhớ để hoạt động). Cụ thể: mỗi biến trong chư¢ng trình sẽ được định vị tại
một địa chỉ xác định trong bộ nhớ, và các biến được khai báo liên tiếp nhau trong chư¢ng trình (từ
trên xuống dưới) sẽ được định vị tại các địa chỉ liên tiếp nhau trong bộ nhớ (từ offset thấp đến offset
cao). Nhờ đó, nếu chư¢ng trình xác định được địa chỉ của một biến nào đó thì nó dễ dàng có được
địa chỉ và nội dung của các biến khác trong chư¢ng trình.
Khác với biến, hằng trong chư¢ng trình hợp ngữ không được cấp phát bộ nhớ để lưu trữ, tức là, n¢i
nào trong chư¢ng trình chứa trên hằng thì sẽ được trình biên dịch thay bằng giá trị của nó một cách trực tiếp.
Hợp ngữ cung cấp các toán tử giả để định nghĩa/khai báo dữ liệu: DB (định nghĩa byte), DW (định
nghĩa word), DD (định nghĩa doubleword),. ... Và toán tử EQU để khai báo hằng. Biến có thể được
khai báo ở đầu hoặc ở cuối chư¢ng trình. Trong khi đó, hằng có thể khai báo ở bất kỳ n¢i đâu trong
chư¢ng trình, khi đó ta có thể sử dụng toán tử dấu <== để gán giá trị cho hằng.
Khai báo biến – hằng: Cú pháp khai báo: • a: DB b: DW c: DD d: EQU
Trường hợp a được sử dụng để khai báo biến kiểu byte, trường hợp b được sử dụng để khai
báo biến kiểu word, trường hợp c được sử dụng để khai báo biến kiểu doubleword, trường hợp d
được sử dụng để khai báo hằng. có thể một hoặc nhiều giá trị, nó có thể là một số, một
kí tự hoặc một xâu kí tự, và cũng có thể là một dấu hỏi chấm (<?=). có thể là một số, một
kí tự hay một xâu kí tự. Ví dā 1: • Spt DB 0 • KiTu DB 8a9 • TieuDe DB 8Tin hoc9 • SoNguyen DW ? lOMoAR cPSD| 36066900 • DaySo DD 1020, 1345, 2389, 5763
Trong ví dụ trên, hai biến Spt Kitu đều là biến kiểu byte, kích thước 1byte. Biến TieuDe cũng là
biến kiểu byte nhưng gồm 7 byte ô nhớ liên tiếp (kích thước 7 byte), mỗi byte chứa 1 kí tự ASCII.
Biến SoNguyen là biến kiểu word, chưa được gán giá trị khởi tạo. Biến DaySo là biến kiểu
doubleword, gồm 4 phần tử có giá trị lần lượt (từ thấp đến cao) là: 1020, 1345, 2389, 5763. Ví dụ 2: • LF EQU 0Ah • TB EQU 8Cong nghe Thong tin9 • TieuDe DB TB
Khai báo trên cho thấy, có thể khởi tạo giá trị ban đầu cho biến thông qua một hằng đã được định nghĩa trước.
Ví dụ 3: TenKhoa DB 8Cong nghe Thong tin9, 0Ah, 0Dh, 8$9
Khai báo biến TenKhoa cho thấy, có thể khai báo một biến mà trong đó bao gồm cả số, kí tự và xâu
kí tự, đây là biến kiểu byte, gồm 22 byte. Ví dụ 4: SoPT DW 2345h
Biến SoPT ở trên là một biến word, trong trường hợp này byte thấp của nó nhận giá trị 45h, byte cao
nhận giá trị 23h, nhưng byte thấp định vị tại địa chỉ SoPT, byte cao định vị tại địa chỉ SoPT + 1.
Trong hợp ngữ, một dãy các byte hay word liên tiếp nhau trong bộ nhớ có thể xem là một mảng
(mảng byte hay mảng word). Biến DaySo trong ví dụ 1 ở trên có thể được xem là một mảng word
gồm 4 phần tử. Giá trị của các phần tử trong mảng có thể được xác định thông qua tên biến và chỉ
số tư¢ng ứng (địa chỉ). Cụ thể:
DaySo[0] = 1020; DaySo[2] = 1345; DaySo[4] = 2389; DaySo[6] = 5763.
Hợp ngữ cho phép sử dụng toán tử DUP để khai báo một biến dạng mảng mà trong đó gồm nhiều
phần tử có cùng giá trị khởi tạo. Dạng sử dụng toán tử DUP là m Dup (n): gồm m phần tử có cùng
giá trị khởi tạo là n.
Ví dụ 5: MangSN DW 23, 45, 50 Dup (0), 12
Như vậy, biến MangSN được xem là một mảng word gồm 53 phần tử, hai phần tử đầu tiên nhận giá
trị lần lượt là 23 và 45, 50 phần tử tiếp theo nhận cùng giá trị 0 và phần tử cuối cùng nhận giá trị 12.
Trong ví dụ 1 ở trên: Các biến được khai báo ở đây sẽ được định vị tại các địa chỉ liên tiếp nhau
trong bộ nhớ. Nếu biến Spt được định vị tại địa chỉ offset 100 trong đoạn nhớ dữ liệu thì các biến tiếp
theo sẽ được định vị tại các offset sau đó. Cụ thể: Biến KiTu bắt đầu tại offset 101, biến TieuDe bắt
đầu tại offset 102, biến SoNguyen định vị tại offset 109, biến DaySo bắt đầu tại offset 111 (xem hình sau):
100 101 102 103 104 105 106 107 108 109 111 113 115 117 0 a T i n _ H o c 1020 1345 2389 5763
(dòng trên là địa chỉ offset của biến, dòng dưới là các ô nhớ chứa giá trị của các phần tử trong biến) lOMoAR cPSD| 36066900
Điều cần quan tâm ở đây là, có thể truy xuất đến giá trị của một phần tử trong biến này thông qua tên
của một biến khác. Ví dụ: Spt[0] = 0, TieuDe[0] = 8T9, TieuDe[1] = 89i, DaySo[0] = 1020, DaySo[6]
= 5763,... nhưng cũng có thể
Spt[2] = KiTu[1] = 8T9, KiTu[5] = 8h9, DaySo[-5] = 8h9, TieuDe[11] = 1345,... lOMoAR cPSD| 36066900
Cấu trúc của một chương trình Assembly
Hầu hết các hệ điều hành máy tính hiện nay, đặc biệt là các hệ điều hành của Microsoft, đều hỗ trợ hai dạng cấu
trúc tập tin thực thi có thể hoạt động trên nó, đó là tập tin cấu trúc dạng COM và tập tin cấu trúc dạng EXE. Có
nhiều điểm khác nhau giữa hai cấu trúc chư¢ng trình này, nhưng điểm khác biệt lớn nhất là: Các chư¢ng trình
cấu trúc dạng EXE gồm 3 đoạn: Mã lệnh (Code), dữ liệu (Data) và Ngăn xếp (Stack). Khi hoạt động, 3 đoạn này
sẽ được nạp vào 3 đoạn (Segment) bộ nhớ tách biệt trên bộ nhớ;
Các chư¢ng trình dạng COM thì ngược lại, nó chỉ có 1 đoạn mã lệnh, trong đó chứa cả mã lệnh và ngăn
xếp. Vì thế, khi được nạp vào bộ nhớ để hoạt động nó chỉ được cấp phát một đoạn bộ nhớ. Rõ ràng kích thước
của một chư¢ng trình dạng COM không thể vượt quá giới hạn của một đoạn bộ nhớ (với Intel 8088/80286 và
MSDOS, 1 Segment bộ nhớ = 64KB).
Trong khi đó một chư¢ng trình dạng EXE có thể lớn h¢n 3 Segment bộ nhớ. Do đó, khi thiết kế các
chư¢ng trình lớn, với chức năng phức tạp, trong đó có liên kết giữa các modun chư¢ng trình khác nhau thì ta
phải thiết kế theo cấu trúc chư¢ng trình dạng EXE.
Hợp ngữ hỗ trợ thiết kế cả hai dạng cấu trúc chư¢ng trình EXE và COM, mỗi dạng phù hợp
với một nhóm trình biên dịch nào đó. Muốn biên dịch một chư¢ng trình hợp ngữ sang dạng EXE thì
ngoài việc nó phải được viết theo cấu trúc dạng EXE ta còn cần phải sử dụng một trình biên dịch phù
hợp. Điều này cũng tư¢ng tự với việc muốn có một chư¢ng trình thực thi dạng COM.
Văn bản của một chư¢ng trình hợp ngữ dạng EXE cũng cho thấy rõ nó gồm 3 đoạn: Code,
Data và Stack. Tư¢ng tự, văn bản của chư¢ng trình hợp ngữ dạng COM cho thấy nó chỉ có 1 đoạn:
Code, cả Data và Stack (không tường minh) đều nằm ở đây.
Một chư¢ng trình hợp ngữ gồm hai thành phần chính: phần lệnh hợp ngữ và phần chỉ dẫn
biên dịch. Chỉ có các lệnh là được biên dịch thành ngôn ngữ máy. Phần hướng dẫn biên dịch không
được dịch sang ngôn ngữ máy, nó chỉ có tác dụng với các trình biên dịch. Thông thường mỗi chư¢ng
trình biên dịch có một nhóm hướng dẫn biên dịch phù hợp với nó, những với các hướng dẫn biên
dịch c¢ bản và đ¢n giản thì nó phù hợp với hầu hết các trình biên dịch hợp ngữ hiện nay. Trong tài
liệu này chúng tôi sử dụng các hướng dẫn biên dịch phù hợp với trình biên dịch Microsoft Macro Assembler (MASM).
Cấu trúc chư¢ng trình được giới thiệu sau đây sử dụng các hướng dẫn biên dịch định nghĩa
đoạn đ¢n giản (.Model, .Code, .Stack, .Data) phù hợp với MASM, TASM (Turbo Macro Assembler),
A86. Việc sử dụng định nghĩa đoạn đ¢n giản sẽ làm cho văn bản chư¢ng trình sáng sủa và dễ đọc
h¢n. Với các định nghĩa đoạn đ¢n giản ta cũng có thể xây dựng được các chư¢ng trình từ đ¢n giản đến phức tạp.
Cấu trúc chương trình dạng COM: .Model ‹Chế độ bộ nhớ> .Code ORG 100h ‹Nhãn chính>: JMP ‹Thủ tục chính> lOMoAR cPSD| 36066900
‹Khai báo dữ liệu đặt tại đây> ‹Thủ tục chính> PROC
‹Các lệnh của chương trình đặt tại đây> ‹Thủ tục chính> Endp
‹Các thủ tục khác đặt tại đây>
End ‹Nhãn chính>
Trong cấu trúc chư¢ng trình trên các từ khóa Model, Code, ORG, Proc, Endp, End là các hướng dẫn
biên dịch. là nhãn của lệnh Jmp.
Cấu trúc này cho thấy rõ, một chư¢ng trình hợp ngữ dạng COM chỉ có 1 đoạn, đó chính là đoạn
Code (đoạn mã lệnh), trong này bao gồm cả phần khai báo dữ liệu. Các khai báo dữ liệu trong
chư¢ng trình dạng COM có thể đặt ở đầu hoặc ở cuối chư¢ng trình, nhưng với việc sử dụng định
nghĩa đoạn đ¢n giản các khai báo dữ liệu phải đặt ở đầu chư¢ng trình.
Chỉ dẫn ORG 100h và lệnh JMP sẽ được đề cập trá lại á các phần sau đây của tài liệu này.
Cấu trúc chương trình dạng EXE: .Model ‹Chế độ bộ nhớ> .Stack 100h .Data
‹Khai báo dữ liệu đặt tại đây> .Code ‹Thủ tục chính> PROC
‹Các lệnh của chương trình đặt tại đây> ‹Thủ tục chính> Endp END
Trong cấu trúc chư¢ng trình trên các từ khóa Model, Code, Data, Stack, Proc, Endp, End là các hướng dẫn biên dịch.
Cấu trúc này cho thấy rõ, một chư¢ng trình hợp ngữ dạng gồm 3 đoạn: đoạn Code, chứa toàn bộ mã
lệnh của chư¢ng trình. Đoạn Data, chứa phần khai báo dữ liệu của chư¢ng trình. Đoạn Stack, n¢i
chứa stack (ngăn xếp) của chư¢ng trình khi chư¢ng trình được nạp vào bộ nhớ để hoạt động. lOMoAR cPSD| 36066900
Chỉ dẫn .Stackđặt ở đầu chư¢ng trình với mục đích khai báo kích thước của Stack dùng cho chư¢ng
trình sau này. Kích thước thường được chọn là 100h (256) byte.
Chỉ dẫn .Model được đặt ở đầu cả cấu trúc chư¢ng trình dạng COM và EXE với mục đích khai báo
chế độ bộ nhớ mà chư¢ng trình sử dụng.
Ví dā: Sau đây là hai chư¢ng trình hợp ngữ đ¢n giản, dạng COM và dạng EXE, cùng thực hiện
nhiệm vụ in ra màn hình 3 dòng văn bản như sau : Nguyen Kim Le Tuan Nguyen Le Tram Thanh Nguyen Le Tram Uyen
Hai chương trình dưới đây chỉ có tác dụng minh họa cho việc sử dụng các hướng dẫn biên dịch định
nghĩa đoạn đơn giản và giúp các bạn thấy được những điểm giống nhau, khác nhau giữa hai dạng

cấu trúc chương trình dạng COM và EXE, vì vậy, á đây các bạn chưa cần quan tâm đến ý nghĩa của
các lệnh và các hàm/ngắt trong nó. Phần lệnh hợp ngữ và các hàm/ngắt sẽ được trình bày ngay sau đây.
Chương trình viết theo cấu trúc dạng COM: .Model Small .Code ORG 100h Start: Jmp Main MyChildren DB
8Nguyen Kim Le Tuan9,0Ah,0Dh DB
8Nguyen Le Tram Thanh9,0Ah,0Dh DB
8Nguyen Le Tram Uyen9,9$9 Main PROC
;------- in ra mot xau voi ham 09/21h ------- Mov Ah, 09h Lea Dx, MyChildren Int 21h
;------- ket thuc chuong trinh ------- Int 20h Main Endp End Start lOMoAR cPSD| 36066900
Chư¢ng trình này chọn chế độ bộ nhớ Small. Tên thủ tục chính là Main (tên thủ tục chính là tùy ý).
Nhãn chính của chư¢ng trình là Start (tên thủ tục chính là tùy ý), đó chính là nhãn của lệnh Jmp.
Phần khai báo dữ liệu chỉ khai báo một biến, đó là MyChildren.
Chư¢ng trình này gọi hàm 4Ch của ngắt 21h để kết thúc chư¢ng trình. Có thể gọi ngắt 20h để kết
thúc các chư¢ng trình dạng COM.
Chương trình viết theo cấu trúc dạng EXE: .Model Small .Stack 100h .Data MyChildren DB
8Nguyen Kim Le Tuan9,0Ah,0Dh DB
8Nguyen Le Tram Thanh9,0Ah,0Dh DB
8Nguyen Le Tram Uyen9,9$9 .Code Main PROC
;------- khởi tạo DS ------- Mov Ax, @Data Mov DS, Ax
;------- in ra mot xau voi ham 09/21h ------- Mov Ah, 09h Lea Dx, MyChildren Int 21h
;------- ket thuc chuong trinh ------- Mov Ah, 4Ch Int 21h Main Endp END Main
Chư¢ng trình này chọn chế độ bộ nhớ Small. Khai báo kích thước Stack là 100h byte. Phần khai báo
dữ liệu được đặt trong đoạn Data, ở đây chỉ khai báo một biến, đó là MyChildren. Tên thủ tục chính là
Main (tên thủ tục chính là tùy ý).
Thao tác đầu tiên của chư¢ng trình là trỏ thanh ghi đoạn DS về đầu đoạn Data, hay còn gọi là khởi tạo thanh ghi đoạn DS: Mov Ax, @Data Mov DS, Ax lOMoAR cPSD| 36066900
thao tác này được xem như là bắt buộc đối với cấu trúc chư¢ng trình dạng EXE sử dụng định nghĩa
đoạn đ¢n giản. Các chư¢ng trình viết theo cấu trúc dạng EXE phải gọi hàm 4Ch của ngắt 21h để kết thúc.
Có thể thấy, cấu trúc chư¢ng trình dạng COM và cấu trúc chư¢ng trình dạng EXE chỉ khác phần
hướng dẫn biên dịch, phần khai báo biến và phần lệnh thao tác chính hoàn toàn giống nhau. Hai
chư¢ng trình đ¢n giản ở trên hoàn toàn giống nhau ở biến là MyChildren và các lệnh gọi hàm 09h
của ngắt 21h để in ra màn hình một xâu kí tự (xâu này chính là giá trị khởi tạo của biến MyChildren).
Chú ý 1: Trình biên dịch hợp ngữ (Macro Assembler) cho phép các chư¢ng trình được dịch bởi nóc
họn sử dụng một trong các chế độ bộ nhớ sau:
- Small: Đoạn mã lệnh (Code) và đoạn dữ liệu (Data) của chư¢ng trình đều chỉ có thể chứa trong
một đoạn (segment) bộ nhớ. Tức là, kích thước của chư¢ng trình chỉ có thể tối đa là hai đoạn bộ
nhớ. Tuy vậy chế độ bộ nhớ này đủ dùng cho hầu hết các chư¢ng trình hợp ngữ.
- Medium: Đoạn Code của chư¢ng trình có thể chiếm nhiều h¢n một đoạn bộ nhớ. Trong khi đó,
đoạn Data chỉ có thể chiếm 1 đoạn bộ nhớ.
- Compact: Đoạn Data của chư¢ng trình có thể chiếm nhiều h¢n một đoạn bộ nhớ. Trong khi đó,
đoạn Code chỉ có thể chiếm 1 đoạn bộ nhớ.
- Large: Đoạn Code và đoan Data của chư¢ng trình đều có thể chiếm nhiều h¢n một đoạn bộ nhớ.
Nhưng trong trường hợp này không thể định nghĩa một mảng dữ liệu có kích thước lớn h¢n 64 Kbyte.
- Huge: Tư¢ng tự như Large, nhưng trong trường hợp này có thể định nghĩa một mảng dữ liệu có
kích thước lớn h¢n 64 Kbyte.
Chế độ bộ nhớ Small là đ¢n giản nhất, được hầu hết các chư¢ng trình lựa chọn.
Chú ý 2: Với các chư¢ng trình hợp ngữ sử dụng định nghĩa đoạn đ¢n giản: Khi được nạp vào bộ
nhớ để hoạt động thì các thanh ghi đoạn sẽ tự động trỏ về các đoạn chư¢ng trình tư¢ng ứng. Cụ thể:
Thanh ghi đoạn CS chứa địa chỉ segment của đoạn bộ nhớ chứa đoạn Code của chư¢ng trình.
Thanh ghi đoạn DS (và có thể cả ES) chứa địa chỉ segment của đoạn bộ nhớ chứa đoạn Data của
chư¢ng trình. Thanh ghi đoạn SS chứa địa chỉ segment của đoạn bộ nhớ chứa đoạn Stack của chư¢ng trình.
Tuy nhiên, trong thực tế, khi nạp chư¢ng trình EXE vào bộ nhớ DOS luôn dành ra 256 byte đầu tiên
của vùng nhớ, mà DOS cấp phát cho chư¢ng trình, để chứa PSP (Program Segment Prefix) của
chư¢ng trình. PSP chứa các thông tin cần thiết mà trình biên dịch chuyển đến cho DOS để hỗ trợ
DOS trong việc thực hiện chư¢ng trình này, đặc biệt, chư¢ng trình cũng có thể truy xuất vùng nhớ
PSP. Do đó, DOS phải đưa địa chỉ segment của vùng nhớ chứa PSP vào cả DS và ES trước khi
chư¢ng trình được thực hiện. Tức là, ngay khi chư¢ng trình được nạp vào bộ nhớ DS không phải
chứa địa chỉ segment của đoạn Data của chư¢ng trình mà chứa địa chỉ segment của PSP.
Vì vậy, để trỏ DS về lại đoạn Data chư¢ng trình chúng ta phải đặt ngay hai lệnh sau đây ở đầu
chư¢ng trình viết theo cấu trúc EXE: Mov Ax, @Data Mov DS, Ax lOMoAR cPSD| 36066900
Với việc khởi tạo thanh ghi đoạn DS ở trên, địa chỉ segment của tất cả các biến khai báo trong đoạn
Data đều được chứa trong thanh ghi DS, do đó, trong các thao tác xử lý biến sau này chư¢ng trình
không cần quan tâm đến địa chỉ segment của nó nữa.
Chú ý 3: Hợp ngữ còn cho phép các chư¢ng trình sử dụng các hướng dẫn biên dịch định nghĩa đoạn
toàn phần, các định nghĩa này phù hợp với hầu hết các trình biên dịch hợp ngữ hiện nay. Định nghĩa
đoạn toàn phần giúp cho việc viết chư¢ng trình hợp ngữ trở nên mềm dẻo và linh hoạt h¢n, nó giúp
người lập trình có thể điều khiển thứ tự các đoạn chư¢ng trình, kết hợp các đoạn chư¢ng trình, liên
kết các đoạn chư¢ng trình trong bộ nhớ,... , ngay trong khi lập trình.
Chi tiết về cách sử dụng và mục đích sử dụng của các hướng dẫn biên dịch nói chung và các định
nghĩa đoạn toàn phần nói riêng dễ dàng tìm thấy trong rất nhiều tài liệu về lập trình hợp ngữ [1], [2]. à
đây chúng tôi chỉ giới thiệu sơ lược về nó thông qua ví dụ dưới đây.

Ví dā: Sau đây là một chư¢ng trình dạng EXE sử dụng các hướng dẫn biên dịch định nghĩa đoạn
toàn phần (phù hợp với Macro Assembler): S_Seg Segment Stack DB 100h DUP (?) S_Seg Ends D_Seg Segmet MyChildren DB
8Nguyen Kim Le Tuan9,0Ah,0Dh DB
8Nguyen Le Tram Thanh9,0Ah,0Dh DB
8Nguyen Le Tram Uyen9,9$9 D_Seg Ends C_Seg Segment ASSUME CS:C_Seg, SS:S_Seg, DS:D_Seg Main PROC
;------- khởi tạo DS ------- Mov Ax, D_Seg Mov DS, Ax Mov Ah, 09h Lea
Dx, MyChildren ; địa chỉ offset của biến MyChildren Int 21h Mov Ah, 4Ch Int 21h Main Endp C_Seg Ends lOMoAR cPSD| 36066900 END Main
Điều dễ nhận thấy đầu tiên là phần khai báo biến và phần lệnh chính trong chư¢ng trình này hoàn
toàn giống như trong chư¢ng trình sử dụng định nghĩa đoạn đ¢n giản (hai chư¢ng trình ví dụ ở trên).
Chư¢ng trình này sử dụng hướng dẫn biên dịch định nghĩa đoạn toàn phần Segment ... Ends để
định nghĩa 3 đoạn chư¢ng trình với tên lần lượt là: S_Seg (đoạn stack), D_Seg (đoạn Data), C_Seg
(đoạn Code). Tên của các đoạn được định nghĩa ở đây là tùy ý.
Hướng dẫn biên dịch Assume được sử dụng để báo cho trình biên dịch biết chư¢ng trình muốn
chứa địa chỉ segment của các đoạn chư¢ng trình trong các thanh ghi đoạn nào (trỏ thanh ghi đoạn về
đoạn chư¢ng trình). Cụ thể ở đây là: Thanh ghi đoạn CS chứa địa chỉ segment của đoạn Code
(CS:C_Seg). Thanh ghi đoạn SS chứa địa chỉ segment của đoạn Stack (SS:S_Seg). Thanh ghi đoạn
DS chứa địa chỉ segment của đoạn Data (DS:C_Seg). Tuy nhiên, trong thực tế Assume
DS:D_Seg không tự động nạp địa chỉ segment của D_Seg vào DS, do đó chư¢ng trình phải nạp trực tiếp bằng các lệnh: Mov Ax, D_Seg Mov DS, Ax
Nên nhớ, hướng dẫn biên dịch Segment ... Ends chỉ có tác dụng định nghĩa đoạn, nó không thể báo
cho trình biên dịch biết đoạn được định nghĩa thuộc loại đoạn chư¢ng trình nào (Code, Data, Stack,
Extra). Chỉ có định nghĩa Segment Stack ... Ends là báo cho trình biên dịch biết đoạn được định
nghĩa là đoạn Stack, nhờ đó, khi chư¢ng trình được nạp vào bộ nhớ thanh ghi đoạn SS sẽ được trỏ về đoạn này lOMoAR cPSD| 36066900
Phần 1: MỘT SỐ LỆNH ASSEMBLY CƠ SỞ Cú pháp LỆNH:
Một lệnh hợp ngữ đầy đủ gồm bốn thành phần sau đây: [Nhãn lệnh:] [Các toán hạng]
[;Lời giải thích] Trong đó:
- [Nhãn lệnh:]: Là một dãy các kí tự đứng trước câu lệnh (kết thúc bởi dấu hai chấm (:)), nó được
chỉ định thay thế cho địa chỉ của câu lệnh trong các đoạn lệnh lặp, rẽ nhánh,... Do đó, nó chỉ được sử dụng khi cần.
Trong một chư¢ng trình hợp ngữ không thể có hai nhãn lệnh trùng tên, tên của các nhãn cũng không
thể trùng với tên của các thủ tục trong chư¢ng trình.
- : Là một trong các lệnh thuộc tập lệnh hợp ngữ (lệnh gợi nhớ: Mnemonic) của vi xử lý
trên máy tính thực hiện lệnh này.
Lệnh hợp ngữ không phân biệt chữ hoa hay chữ thường. Trong chư¢ng trình hợp ngữ mỗi dòng chỉ
có thể chứa một lệnh và mỗi lệnh phải được đặt trên một dòng.
- [Các toán hạng]: Là đối tượng mà lệnh tác động vào. Một lệnh hợp ngữ của Intel 8088/8086 có
thể không có toán hạng, có một toán hạng, hoặc có hai toán hạng. Nếu có hai toán hạng thì toán
hạng đứng trước gọi là [Toán hạng đích], toán hạng đứng sau gọi là [Toán hạng nguồn]. [Toán hạng
đích] không thể là một hằng số.
Một số lệnh hợp ngữ của các Intel 80286/80386/... có thể có đến 3 toán hạng, trong trường hợp này
cũng chỉ có một [Toán hạng đích].
- [;Lời giải thích]: Chỉ có tác dụng với người viết và người đọc chư¢ng trình, nó không có ý nghĩa
với trình biên dịch, tức là, không được dịch sang mã máy. Lời giải thích thường được sử dụng để làm
rõ ý nghĩa của câu lệnh (khi người viết thấy cần). Lời giải thích phải nằm sau dấu chấm phảy (;).
Ví dā 1: Xét lệnh sau đây:
Lenh_VD: Mov AX,BX
; đặt giá trị thanh ghi BX vào thanh ghi AX Trong đó:
Lenh_VD: Trong trường hợp này dãy kí tự Lenh_VD được sử dụng làm nhãn lệnh cho lệnh Mov.
Mov: Là tên lệnh.
AX và BX: Là các toán hạng (đích và nguồn). Trong trường hợp này toán hạng là các thanh ghi đa năng 16 bít.
<đặt giá trị thanh ghi BX vào thanh ghi AX=: Là lời giải thích cho lệnh này. Trong thực tế lời giải thích
thường là tiếng Việt không dấu.
Ví dā 2: Xem các lệnh sau đây: - NOP
; đây là lệnh không có toán hạng lOMoAR cPSD| 36066900 - Mov Ax, Bl
; lệnh này có hai toán hạng, [Toán hạng đích] là thanh
; ghi 16 bít, [Toán hạng nguồn] là thanh ghi 8 bít - Add Cl, Spt
; lệnh này có hai toán hạng, [Toán hạng đích] là thanh
; ghi 8 bít, [Toán hạng nguồn] là một biến byte - Mov Ax, [SI]
; lệnh này có hai toán hạng, [Toán hạng đích] là thanh
; ghi 16 bít, [Toán hạng nguồn] là một ô nhớ - Sub Dl, 8a9 – 8A9
; lệnh này có hai toán hạng, [Toán hạng đích] là thanh
; ghi 8 bít, [Toán hạng nguồn] là một hằng số - IMul Ax, Bx, 20
; lệnh này có ba toán hạng, [Toán hạng đích] là thanh
; ghi 16 bit (Ax), [Toán hạng nguồn] là thanh ghi 16 bít
; (Bx) và một hằng số (20)
Lệnh Imul ở trên là một lệnh nhân mới của vi xử lý Intel 80286. Lệnh này thực hiện như sau: lấy nội
dung/giá trị hai [Toán hạng nguồn] nhân với nhau, kết quả chứa ở [Toán hạng đích] (trong lệnh trên
là: Bx*20, tích kết quả chứa ở thanh ghi Ax (chỉ lấy 16 bít thấp của tích để đưa vào Ax)).
1. Lßnh Mov (Move): Cú pháp lßnh: Mov
[Toán hạng đích], [Toán hạng nguồn] Trong đó:
- [Toán hạng đích]: Có thể là thanh ghi (8 bít hay 16 bít), ô nhớ (chính xác h¢n là địa chỉ của một ô
nhớ) hay một biến nào đó. [Toán hạng đích] không thể là hằng số.
- [Toán hạng nguồn]: Có thể là hằng số, biến, thanh ghi, ô nhớ (chính xác h¢n là địa chỉ của một ô nhớ) nào đó.
Tác dāng: Lấy nội dung (giá trị) của [Toán hạng nguồn] đặt vào [Toán hạng đích]. Nội dung của
[Toán hạng nguồn] không bị thay đổi. Ví dā 1: - Mov Ax, 5
; Ax ß 5: đặt giá trị 5 vào thành ghi Ax - Mov Ax, 5*2
; Ax ß 5*2: đặt giá trị 10 vào thành ghi Ax - Mov
Bx, (80*(Dong - 1) + (Cot - 1))*2 ; Dong, Cot là các biến - Mov Dl, 8A9
; Dl = 41h: đặt mã ASCII của 8A9 vào thanh ghi Dl - Mov Cx, Var1
; Cx = Var1: đặt giá trị của biến Var1 vào thanh ghi Cx - Mov Ax, Bx
; Ax = Bx: đặt giá trị của thanh ghi Bx vào Ax - Mov Ax, Dl
; Ax = Dl: đặt giá trị của Dl (8 bít) vào Ax (16 bít) lOMoAR cPSD| 36066900 - Mov Bl, Dx
; Bl = Dx: không hợp lệ, vì: Dx (16 bít) mà Bl (8 bít) - Mov Dl, 300
; Dl = 300: không hợp lệ, vì 300 vượt giới hạn 1 byte
Ví dā 2: Giả sử DI = 100; Ô nhớ tại địa chỉ offset 100 trong đoạn nhớ Data (được chỉ bởi DS) chứa kí tự B. Thì : - Mov Ax, DI
; (1) đặt giá trị thanh ghi DI vào thanh ghi Ax: Ax = 100 - Mov Ax, [DI] ; (2) Ax =
; chứ địa chỉ offset của ô nhớ)>. Tức là, đặt nội dung của
; ô nhớ được chỉ bởi DI vào thanh ghi Ax: Ax = 41h
Hãy phân biệt sự khác nhau giữa hai lệnh trên: Lệnh (1) sử dụng chế độ địa chỉ thanh ghi. Lệnh (2)
sử dụng chế độ địa chỉ gián tiếp thanh ghi.
Nhớ lại rằng: Trong chế độ địa chỉ gián tiếp thanh ghi, các thanh ghi chỉ có thể là BX, DI, SI (địa chỉ
đoạn chứa trong DS) hay BP (địa chỉ đoạn chứa trong SS). Như vậy lệnh (2) tư¢ng đư¢ng với lệnh (3) nhưng khác lệnh (4): - Mov Ax, DS:[DI] ; (3) - Mov Ax, ES:[DI] ; (4) Ví dā 3: - Mov Ax, [SI]
; đặt nội dung ô nhớ được chỉ bởi SI vào thanh ghi Ax - Mov [DI], Bx
; đặt giá trị của thanh ghi bx vào ô nhớ được chỉ bởi DI - Mov [DI], [SI]
; [DI] ß [SI] : lệnh không hợp lệ, vì: không thể chuyển
; nội dung của ô nhớ vào một ô nhớ một cách trực tiếp - Mov Var1, Ax
; Var1 ß Ax : đặt giá trị t/ghi Ax vào biến word Var1 Chú ý: -
Lệnh Mov không làm ảnh hưởng đến các cờ. - Mov DS:[DI], ES:[SI]
; lệnh không hợp lệ, vì: không thể chuyển dữ liệu
; trực tiếp giữa hai toán hạng bộ nhớ với nhau - Mov DS, ES
; DS ß ES: lệnh không hợp lệ, - Mov ES, 0100
; lệnh không hợp lệ, vì: không thể chuyển
; trực tiếp một hằng số vào thanh ghi đoạn.
Để chuyển giá trị của hai thanh ghi đoạn hay nội dung của hai ô nhớ ta có thể mượn một thanh ghi đa năng làm trung gian: - Mov Ax, ES
; hai lệnh này chuyển nội dung của thanh ghi đoạn ES Mov DS, Ax
; vào thanh ghi đoạn DS thông qua thanh ghi Ax lOMoAR cPSD| 36066900
Theo cách thông thường, để hoán đổi giá trị của hai thanh ghi đoạn hay nội dung của hai ô nhớ
người ta thường sử dụng hai thanh ghi đa năng làm trung gian: - Mov Ax, [DI]
; lưu tạm nội dung ô nhớ được chỉ bởi DI và Ax Mov Bx, [SI]
; lưu tạm nội dung ô nhớ được chỉ bởi SI và Bx Mov [DI], Bx
; chuyển giá trị của t/ghi Bx và ô nhớ được chỉ bởi DI Mov [SI], Ax
; chuyển giá trị của t/ghi Ax và ô nhớ được chỉ bởi SI
Bốn lệnh trên có tác dụng hoán đổi nội dung của hai ô nhớ trong đoạn Data (DS) được chỉ bởi DI và
SI (DI và SI chứa địa chỉ Offset của các ô nhớ). -
Không thể dùng thanh ghi đoạn CS làm [Toán hạng đích] trong lệnh Mov.
2. Các lßnh Inc – Dec – Add và Sub Cú pháp lßnh: Inc
[Toán hạng đích] Add
[Toán hạng đích],[Toán hạng nguồn] Dec
[Toán hạng đích] Sub
[Toán hạng đích],[Toán hạng nguồn]
Trong đó: [Toán hạng đích], [Toán hạng nguồn]: tư¢ng tự lệnh Mov. Tác dāng:
• Lệnh Inc (Increment): làm tăng giá trị của [Toán hạng đích] lên 1 đ¢n vị.
• Lệnh Dec (Decrement): làm giảm giá trị của [Toán hạng đích] xuống 1 đ¢n vị.
• Lệnh Add (Addition): lấy giá trị/nội dung của [Toán hạng nguồn] cộng vào giá trị/nội dung của [Toán hạng
đích], kết quả này đặt vào lại [Toán hạng đích].
• Lệnh Sub (Subtract): lấy giá trị/nội dung của [Toán hạng đich] trừ đi giá trị/nội dung của [Toán hạng nguồn],
kết quả này đặt vào lại [Toán hạng đích]. Ví dā 1: Mov Ax, 121
; đặt giá trị 121 vào thanh ghi Ax Mov Bx, 223
; đặt giá trị 232 vào thanh ghi Bx Inc Ax
; Ax = Ax + 1: tăng Ax lên 1 đ¢n vị (Ax = 122) Dec Bx
; Bx = Bx + 1: giảm Bx xuống 1 đ¢n vị (Bx = 222) Sub Ax, Bx ; Ax = Ax – Bx : Ax = -100 lOMoAR cPSD| 36066900 Add Ax, 120 ; Ax = Ax + 120 : Ax = 20 Mov Cx, Ax ; Cx= Ax : Cx = 20
Dãy lệnh trên, đặt giá trị cuối cùng của thanh ghi Ax vào thanh ghi Cx (Cx = 20). Ví dā 2: - Inc Spt
; Spt = Spt + 1; tăng giá trị biến Spt lên 1 đ¢n vị - Inc DS:[SI]
; tăng ndung ô nhớ được chỉ bởi DS:SI lên 1 đ¢n vị - Add Ax, Var1
; Ax = Ax + Var1; cộng giá trị biến Var1 vào Ax - Add Var2, Dx
; Var2 = Var2 + Dx. Biến Var2 là biến dạng word - Add Dx, [SI]
; cộng thêm nội dung ô nhớ được chỉ bởi SI vào Dx - Add [DI], [SI]
; [DI] = [DI] + [SI] : lệnh không hợp lệ, vì: không thể
; cộng trực tiếp nội dung hai ô nhớ với nhau.
; Yêu cầu của lệnh trên có thể được viết lại như sau: Mov Ax, [SI]
; lưu tạm nội dung ô nhớ được chỉ bởi SI và Ax Mov Bx, [DI]
; lưu tạm nội dung ô nhớ được chỉ bởi DI và Bx Add Bx, Ax
; cộng Ax và Bx, kết quả chứa ở Bx Mov [DI], Bx
; đặt kết quả phép cộng vào lại ô nhớ được chỉ bởi DI
Ví dā 3: Cộng thêm giá trị của thanh ghi Ax vào nội dung của ô nhớ tại địa chỉ offset 0100 trong đoạn DS: Mov DI, 0100
; trỏ DI về ô nhớ offset 0100 Mov Bx, DS:[DI]
; lưu tạm ndung ô nhớ DS:DI vào thanh ghi Bx Add Bx, Ax ; cộng thêm Ax vào Bx Mov DS:[DI], Bx
; đặt kết quả vào lại ô nhớ DS:DI (DS:0100)
Trong trường hợp này ta có thể sử dụng lệnh Add DS:[DI],Ax.
Ví dā 4: Giả sử tại ô nhớ 0B800:0100 trong bộ nhớ có chứa một word dữ liệu. Hãy tăng nội dung của
ô nhớ này lên một đ¢n vị. Mov Ax, 0B800h
; mượn thanh ghi Ax làm trung gian để chuyển Mov ES, Ax
; địa chỉ đoạn của ô nhớ cần truy xuất vào ES Mov DI, 01
; đặt địa chỉ offset của ô nhớ cần truy xuất vào DI
; --------------------------- ; (gọi ngắn gọn: trỏ ES:DI về ô nhớ cần truy xuất) Mov Dx, ES:[DI]
; chuyển tạm nội dung ô nhớ cần tăng vào Dx Inc Dx
; tăng giá trị thanh ghi Dx lên 1 đơn vị Mov ES:[DI], Dx
; đặt giá trị Dx đã tăng vào lại ô nhớ cần tăng lOMoAR cPSD| 36066900
Ví dā 5: Giả sử tại địa chỉ 0A00:0100 trong bộ nhớ có chứa một byte dữ liệu. Hãy chuyển nội dung
của ô nhớ này vào thành ghi AL. Mov Ax, 0A00h
; (1); Các lệnh (1), (2), (3) trỏ cặp thanh Mov ES, Ax
; (2); ghi ES:DI về ô nhớ có địa chỉ 0A00:0100 Mov DI, 0100h
; (3); trong đó 0A00 là địa chỉ Segment và ;-------------------------
; 0100 là địa chỉ Offset. Lệnh (4) chuyển nội Mov Al, ES:[DI]
; (4); dung ô nhớ được chỉ bởi ES:DI vào Al.
Ví dā 6: Giả sử tại địa chỉ 0100:0100 trong bộ nhớ có chứa 2 word dữ liệu liên tiếp (hai ô nhớ liên
tiếp). Hãy tính tổng nội dung hai word nhớ này, rồi lấy kết quả ghi vào ô nhớ tại địa chỉ 0100:0120. Mov Ax, 0100 Mov ES, Ax
; trỏ cặp thanh ghi ES:SI về đầu vùng nhớ Mov SI, 0100 ; cần truy xuất. Mov DI,0120
; trỏ cặp thanh ghi ES:DI về ô nhớ chứa kết quả ;-------------------------
; các ô nhớ này ở trong cùng một Segment Mov Ax, ES:[SI]
; lưu tạm nội dung ô nhớ đầu tiên vào Ax Add Ax, ES:[SI+2]
; cộng nội dung ô nhớ kế tiếp vào Ax Mov ES:[DI], Ax
; ghi kết quả vào ô nhớ 0100:0120 Lệnh Add
Ax, ES:[SI+2] ở trên sử dụng chế độ định địa chỉ bộ nhớ gián tiếp, cụ thể là định địa
chỉ chỉ mục (sử dụng thanh ghi chỉ mục SI).
Qua 3 ví dụ 4, 5, 6 ta có thể rút ra nguyên tắc c¢ bản khi truy xuất dữ liệu/nội dung của một ô nhớ là:
Sử dụng một cặp thanh ghi thích hợp (DS:DI, DS:SI, ES:DI, ES:SI,...) để chứa địa chỉ logic (gồm cả
Segment và Offset) của ô nhớ cần truy xuất. Thao tác này thường gọi là trỏ về ô nhớ cần truy xuất.
Sau đó sử dụng cặp thanh ghi này để ghi/đọc nội dung của ô nhớ đã được trỏ tới.
Ngoài ra, khi truy xuất ô nhớ cần phải xác định dữ liệu/nội dung tại đó là một Byte hay một Word và
nếu là truy xuất đọc thì kết quả sẽ được lưu vào đâu (thanh ghi hay ô nhớ). Chú ý 1:
• Không thể cộng trực tiếp hai thanh ghi đoạn. Trong trường hợp này phải sử dụng các thanh ghi đa năng làm trung gian.
• Lệnh Add thực hiện phép cộng không nhớ. Để thực hiện phép cộng có nhớ (cộng thêm giá trị của cờ nhớ
(CF) hiện tại vào kết quả) phải sử dụng lệnh ADC (ADD with Carry) [2 - 171]. Tư¢ng tự với lệnh Sub và SBB [2 - 180].
• Để thực hiện phép cộng trên các số/giá trị BCD (Binary Coded Decimal) ta phải sử dụng các lệnh
cộng AAA (Ascii Adjust for Addition) và DAA (Decimal Adjust for Addition) để điều chỉnh (adjust) kết quả
cuối cùng [2 - 172]. Tư¢ng tự, với phép trừ trên các số BCD phải sử dụng lệnh AAS DAS [2 - 183]. Chú ý 2: lOMoAR cPSD| 36066900
• Các thanh ghi của vi xử lý Intel 8086/8088 đều là 16 bít, nên để chứa một đại lượng dữ liệu 32 bít nó phải
dùng 2 thanh ghi, thường là các thanh ghi đa năng (thanh ghi tích lũy): Ax, Bx, Cx, Dx. Cặp thanh ghi Dx:Ax
thường được sử dụng nhất, khi đó Ax chứa 16 bít thấp, Dx chứa 16 bít cao của đại lượng 32 bít.
• Để cộng/trừ trên các số 32 bít ta không thể sử dụng Add/Sub theo cách thông thường, mà phải thực hiện
như sau: Cộng/Trừ 16 bít thấp, sau đó Cộng/Trừ 16 bít cao. Nếu phép Cộng/Trừ trên 16 bít thấp xuất hiện
bít nhớ/bít mượn thì phải tiến hành điều chỉnh kết quả, nếu không kết quả sẻ sai. Sử dụng các phép kiểm
tra cờ để biết phép Cộng/Trừ có xuất hiện bít nhớ/bít mượn hay không [1 - 477]. 3. Lßnh LOOP Cú pháp: Loop
<Nhãn đích>
Trong đó: là một nhãn lệnh và nó phải đứng trước lệnh lặp Loop không quá 126 byte.
Tác dāng: Khi gặp lệnh này chư¢ng trình sẽ lặp lại việc thực hiện các lệnh sau đủ n
lần, với n được đặt trước trong thanh ghi CX. Sau mỗi lần lặp CX tự động giảm 1 đ¢n vị (Cx = Cx - 1)
và lệnh lặp sẽ dừng khi Cx = 0.
Lệnh Loop thường được sử dụng để cài đặt các đoạn chư¢ng trình lặp với số lần lặp xác định, được
cho trước trong thanh ghi Cx (tư¢ng tự các vòng lặp For trong các ngôn ngữ lập trình bậc cao).
Ví dā 1: Xem đoạn lệnh sau đây: Mov Ax, 6 Mov Cx, 4 ; lặp lại 4 lần Lap: Add Ax, 10 ; cộng thêm 10 vào Ax Loop Lap
; lặp lại việc cộng 10 vào Ax đủ 4 lần
Kết thúc đoạn lệnh trên: Ax = 46 (cụ thể: LÁn 1: Ax = 6 + 10; LÁn 2: Ax = 16 + 10; LÁn 3: Ax = 26 +
10; LÁn 4: Ax = 36 + 10 = 46).
Ví dā 2: Xem đoạn lệnh sau đây: Mov Ax, 6 Mov Bx, 3 Mov Cx, 4 ; lặp lại 4 lần Lap_TT: Add Ax, Bx
; cộng thêm giá trị thanh ghi Bx vào thanh ghi Ax Inc Bx ; tăng Bx lên 1 đ¢n vị Loop Lap_TT
; lặp lại các lệnh sau nhãn lệnh Lap_TT đủ 4 lần
;-----------------------------
; sau lệnh lặp này Ax = 24, Bx = 7 Mov Dx, Ax ; Dx ß Ax Mov Cx, Bx
; Cx = 7, sau Loop Cx = 0, được thay bằng Bx = 7 lOMoAR cPSD| 36066900
Kết thúc đoạn lệnh trên: Ax = 24 (LÁn 1: Ax = 6 + 3;LÁn 2: Ax = 9 + 4; LÁn 3: Ax = 13 + 5; LÁn 4: Ax = 18 + 6) và Dx = Ax = 24. Khi gặp lệnh Loop
Lap_TT chư¢ng trình sẽ quay lại (nếu Cx <> 0) thực hiện lệnh Add Ax,
Bx (Lap_TT là nhãn của lệnh này), tất nhiên khi đó nó cũng phải thực hiện lại lệnh Inc Bx. Dó đó,
có thể nói lệnh Loop này thực hiện vòng lặp cho cả hai lệnh Add và Inc. Đó cũng chính là lý do mà
người ta thường viết nhãn của các lệnh phải được lặp theo kiểu như trên (nhãn lệnh và lệnh không cùng trên một dòng).
Ví dā 3: Xem đoạn lệnh sau đây: Mov Dx, 6 Mov Cx, 5 ; lặp lại 5 lần TT: Add Dx, Cx
; cộng thêm giá trị thanh ghi Cx vào thanh ghi Dx Loop TT
; lặp lại các lệnh sau nhãn lệnh TT đủ 5 lần ; ; Mov Bx, Cx
Kết thúc đoạn lệnh trên Bx = Cx = 0 (khi Cx = 0 thì vòng lặpLoop TT kết thúc) và Dx = 21 (LÁn 1: Dx
= Dx + Cx = 6 + 5;LÁn 2: Dx = Dx + Cx = 11 + 4; LÁn 3: Dx = Dx + Cx = 15 + 3; LÁn 4: Dx = Dx + Cx
= 18 + 2;LÁn 5: Dx = Dx + Cx = 20 + 1 = 21).
Ví dā 4: Các lệnh sau đây thực hiện phép gán: Ax = 2 + 4 + ...+ 100 Mov Ax, 0 Mov Bx, 2 Mov Cx, 50 Lap_TT: Add Ax, Bx Add Bx, 2 Loop Lap_TT
Ví dā 5: Giả sử tại địa chỉ offset 100 trong đoạn nhớ Data (được chỉ bởi thanh ghi đọan DS) có chứa
một mảng dữ liệu, gồm 100 ô nhớ, mỗi ô là một byte. Hãy cộng thêm 50 đ¢n vị vào tất cả các ô nhớ trong mảng này. Mov DI, 0100
; trỏ cặp thanh ghi DS:DI về
; vùng nhớ cần truy xuất (DS:0100) ; Mov Cx, 100
; lặp 100 lần vì mảng gồm 100 ô nhớ lOMoAR cPSD| 36066900 Lap_TangThem: Mov Dl, DS:[DI]
; lấy nôi dung ô nhớ chỉ bởi DS:DI lưu vào DL Add Dl, 50 ; cộng thêm 50 vào Dl Mov DS:[DI], Dl
; đặt giá trị đã tăng thêm vào lại ô nhớ DS:DI Inc DI
; chỉ đến ô nhớ kế tiếp (vì ô nhớ byte nên tăng 1) Loop Lap_TangThem
; lặp lại đủ 100 lần (duyệt qua đủ 100 ô nhớ)
Trong trường hợp này ta có thể sử dụng lệnh Add DS:[DI], 50 để tăng trực tiếp nội dung của ô
nhớ, hợp ngữ cho phép điều này. Nhưng cách đã viết thường được áp dụng h¢n, vì tính tổng quát
của nó. Nói chung, chúng ta nên hạn chế tác động trực tiếp lên nôi dung của ô nhớ.
Ví dā 6: Giả sử tại địa chỉ 0100:0C00 trong bộ nhớ có chứa một xâu kí tự gồm 50 kí tự (tức là, gồm
50 ô nhớ, mỗi ô 1 byte). Hãy copy xâu kí tự này sang vùng nhớ bắt đầu tại địa chỉ 0200:0100. Mov Ax, 0100 Mov DS, Ax
; trỏ cặp thanh ghi DS:SI về Mov SI, 0C00
; đầu vùng nhớ chưa xâu cần copy (0100:0C00) Mov Ax, 0200 Mov ES, Ax
; trỏ cặp thanh ghi ES:DI về Mov DI, 0100
; vùng nhớ chứa xâu kết quả copy 0200:0100 ; Mov Cx, 50
; lặp 50 lần vì xâu gồm 50 kí tự Lap_Copy: Mov Bl, DS:[SI]
; mượn Bl để chuyển tường kí tự từ ô nhớ được Mov ES:[DI], Bl
; chỉ bởi DS:SI sang ô nhớ được chỉ bởi ES:DI Inc SI
; chuyển đến kí tự tiếp theo Inc DI Loop Lap_Copy
; lặp lại đủ 50 lần (để copy đủ 50 kí tự)
Trong ví dụ này, vùng nhớ chứa xâu kí tự cần copy (vùng nhớ nguồn) và vùng nhớ chứa kết quả
copy (vùng nhớ đích) nằm ở hai đoạn (segment) nhớ khác nhau, do đó, ta phải sử dụng hai thanh ghi
đoạn dữ liệu khác nhau: DS và ES.
Qua 2 ví dụ 5 và 6 ta có thể rút ra nguyên tắc c¢ bản để truy xuất dữ liệu trên một vùng nhớ/mảng nhớ:
Chú ý: Lệnh Loop thực hiện vòng lặp cho đến khi Cx = 0, vì thế nó được xem như lệnh lặp không
điều kiện. Thực tế, hợp ngữ còn có các lệnh lặp có điều kiện, nó cho phép kết thúc vòng lặp trước khi
Cx = 0 dựa vào một điều kiện nào đó. Cụ thể: lệnh LoopE (Loop while Equal): Chỉ lặp lại khi Cx <> 0 lOMoAR cPSD| 36066900
và cờ ZF = 1; lệnh LoopZ (Loop while Zero): tư¢ng tự LoopE; LoopNE (Loop while Not Equal): Chỉ
lặp lại khi Cx <> 0 và cờ ZF = 0;... [2 - 154]. 4. Lên
̣ h LEA (LoadEffectiveAddress) Cu´ pha´ p: LEA
[Toa´ n hang đi´ch],[Toa´ n haṇ g nguô` n]
Trong đo´ : [Toa´ n haṇ g đi´ch]: La` ca´ c thanh ghi 16 bi´t. [Toa´ n haṇ g nguô` n]: La` điạ chỉ củ a môṭ vu` ng
nh¢´ hay tên củ a môṭ biê´n. Ta´ c dun
g: Lệnh LEA có tác dụng chuyển điạ chỉ offset củ a [Toa´ n haṇ g nguô` n] va` o [Toa´ n g đi´ch]. han
Lêṇ h na` y thư¢` ng đư¢̣c sử dụng để lâ´ y điạ chỉ offset củ a môṭ biê´n đã đư¢̣c khai ba´ o trong chư¢ng
tri`nh. Thanh ghi đư¢̣c sử dụng trong trư¢` ng h¢̣p na` y la` thanh ghi c¢ s¢̉ (BX) va` thanh ghi chỉ mục (SI va` DI). Vi´ dụ 1: Lea Bx, DS:[0100]
; chuyển tha` nh phâ` n điạ chỉ offset (0100) va` o Bx Lea DI, XauKT
; chuyển điạ chỉ offset củ a biê´n XauKT va` o DI
; thao ta´ c na` y thư¢` ng đư¢̣c goị la` trỏ DI va` đâ` u ; biến XauKT
Khi chư¢ng tri`nh đư¢̣c nap̣ va` o bộ nh¢´ để hoaṭ đôṇ g thi` ca´ c biê´n đư¢̣c khai ba´ o trong chư¢ng tri`nh
sẽ đư¢̣c điṇ h vi ̣(câ´ p pha´ t vu` ng nh¢´ ) taị môṭ điạ chỉ xa´ c điṇ h trong vu` ng nh¢´ Data. Tư` đây, để thao
ta´ c đê´n dữ liêụ trên ca´ c biê´ n củ a chư¢ng tri`nh thi` chư¢ng trinh` phả i xa´ c điṇ h đư¢̣c điạ chỉ segment
va` o offset (hai tha` nh phâ` n củ a điạ chỉ logic) củ a biê´ n. Lêṇ h LEA ¢̉ trên chỉ lâ´ y đư¢̣c điạ chỉ offset củ a
biê´ n, để lâ´ y đư¢̣c điạ chỉ segment củ a no´ ta co´ thể sử dụng lêṇ h Mov v¢´ i toa´ n tử Seg (tư¢ng tự co´ thể
sử dụng lêṇ h Mov v¢´ i toa´ n tử Offset để lâ´ y điạ chỉ offset củ a biê´n). Vi´ dụ: Ca´ c lêṇ h sau lâ´ y điạ chi
Segment:Offset củ a biê´n XauKT (hay trỏ DS:SI vê` đâ` u biê´ n XauKT): Mov Ax, Seg XauKT
; đưa điạ chỉ Segment củ a biê´n XauKT Mov DS, Ax ; va` o thanh ghi DS Mov SI, Offset XauKT
; đưa điạ chỉ Offset củ a biê´ n XauKT va` o SI
Vi´ dụ 2: Giả sử biê´n TenGom (la` biê´ n kiểu byte) đã đư¢̣c khai ba´ o như sau: TenGom DB 8Nguyen Kim Le Tuan9
Xem ca´ c lêṇ h sau đây (1): Mov Bx, 0 Mov Al, TenGom[Bx] ; Al =8N9 Add Bx, 7 ; Mov Bl, TenGom[Bx] ; Bl =8K9
Xem ca´ c lêṇ h sau đây (2): Lea DI, TenGom lOMoAR cPSD| 36066900 Mov Al, [DI] ; Al =8N9 Mov Bl, [DI + 7] ; Bl =8K9
Ta co´ thể thâ´ y, nho´ m ca´ c lêṇ h (1) va` nho´ m ca´ c lêṇ h (2) la` tư¢ng đư¢ng nhau vê` ta´ c dụng củ a no´ ,
nhưng (1): sử dụng trực tiê´ p tên biê´n để truy xuâ´ t đê´n ca´ c phâ` n tử củ a no´ ; (2): sử dụng thanh ghi chi
muc̣ DI để truy xuâ´ t đê´ n ca´ c phâ` n tử củ a biê´ n. Trong trư¢` ng h¢̣p na` y điạ chỉ segment điṇ h đư¢̣c măc̣
chỉ b¢̉ i DS, điê` u na` y phu` h¢̣p v¢´ i viêc̣ sử dụng điạ chỉ gia´ n tiê´p thanh ghi chỉ mục.
Vi´ dụ 3: Giả sử taị điạ chỉ 0100:0C00 trong bộ nh¢´ co´ chư´ a môṭ xâu ki´ tự gô` m 50 ki´ tự (tư´ c la` , gô` m
50 ô nh¢´ , mỗi ô 1 byte). Hãy copy xâu ki´ tự na` y va` o môṭ biê´n trong chư¢ng tri`nh.
V¢´ i yêu câ` u na` y chư¢ng tri`nh phả i khai ba´ o môṭ biê´n byte co´ độ l¢´ n 50 byte: LuuTru DB 50 Dup (8 8) Mov Ax, 0100 Mov DS, Ax
; trỏ căp̣ thanh ghi DS:SI vê Mov SI, 0C00
; đâ` u vu` ng nh¢´ chưa xâu câ` n copy (0100:0C00) ; Mov Ax, Seg LuuTru
; trỏ căp̣ thanh ghi ES:DI vê Mov ES, Ax ; đâ` u biê´ n LuuTru Lea DI, LuuTru ; Mov Cx, 50 Lap_Copy: Mov Bh, DS:[SI]
; mư¢̣n Bh để chuyển tư¢` ng ki´ tự tư` ô nh¢´ đư¢̣c Mov ES:[DI], Bh
; chỉ b¢̉ i DS:SI sang ô nh¢´ đư¢̣c chỉ b¢̉ i ES:DI Inc SI
; chuyển đê´n ki´ tự tiê´ p theo Inc DI Loop Lap_Copy
; lăp̣ laị đủ 50 lâ` n (để copy đủ 50 ki´ tự)
Chu´ y´ : H¢̣p ngữ co` n cung câ´ p ca´ c lêṇ h LDS (Load Pointer use DS) để lâ´ y nôị dungtoa´ n haṇ g bộ
nh¢´ 32 bi´t đưa va` o ca´ c thanh ghi 16 bi´t (măc̣ điṇ h 16 bi´t cao va` o thanh ghi đoaṇ dữ liêụ DS); va` lêṇ h
LES (Load Pointer use DS) tư¢ng tự LDS nhưng măc̣ điṇ h 16 bi´t cao va` o thanh ghi đoaṇ dữ liêụ (thư´ hai) ES [2 - 137]. 5. Lên ̣ h Mul va` Div Cu´ pha´ p:
Mul [Toa´ n haṇ g nguô` n] lOMoAR cPSD| 36066900
IMul [Toa´ n hạng nguô` n] Div
[Toa´ n hạng nguô` n]
IDiv [Toa´ n hạng nguô` n]
Trong đo´ : [Toa´ n haṇ g nguô` n]co´ thể la` thanh ghi hay ô nh¢´ . V¢´ i ca´ c lêṇ h nhân: [Toa´ n haṇ g đi´ch]
ngâ` m điṇ h la` thanh ghi Al
Ax. V¢´ i ca´ c lêṇ h chia: [Toa´ n haṇ g đi´ch] la` môṭ trong ca´ c thanh ghi đa hoăc̣ năng Ax, Bx,... Ta´ c dung: -
Lêṇ h Mul (Multiply): Thực hiêṇ phe´ p nhân trên sô´ không dâ´ u. Nê´u [Toa´ n haṇ g nguô` n] la` toa´ n
haṇ g 8 bi´t thi` lêṇ h sẽ nhân nôị dung củ a [Toa´ n han g nguô` n] v¢´ i gia´ tri ̣thanh ghi AL, kê´t quả 16 bi´t chư´ a ¢̉ thanh ghi Ax.
Nê´u [Toa´ n haṇ g nguô` n] la` toa´ n haṇ g 16 bi´t thi` lêṇ h sẽ nhân nôị dung củ a [Toa´ n haṇ g nguô` n] v¢´ i gia
tri ̣thanh ghi Ax, kê´t quả 32 bi´t chư´ a ¢̉ căp̣ thanh ghi Dx:Ax, phâ` n thâ´ p ¢̉ Ax, phâ` n cao ¢̉ Dx. Nê´ u
phâ` n cao củ a kê´t quả (AH hoăc̣ DX) bă` ng 0 thi` ca´ c c¢` CF = 0 va` OF = 0.
- Lêṇ h IMul (Interger Multiply): Tư¢ng tự lêṇ h Mul nhưng thực hiêṇ phe´p nhân trên hai sô´ co´ dâ´ u.
Kê´t quả cũng la` môṭ sô´ co´ dâ´ u.
- Lêṇ h Div (Divide): Thực hiêṇ phe´p chia trên sô´ không dâ´ u. Nê´u [Toa´ n haṇ g nguô` n] la` toa´ n
haṇ g 8 bi´t thi` lêṇ h sẽ lâ´ y gia´ tri ̣củ a thanh ghi Ax (sô´ bi ̣chia) chia cho [Toa´ n han g nguô` n] (sô´ chia),
kê´t quả thư¢ng sô´ chư´ a trong thanh ghi Al, sô´ dư chư´ a trong thanh ghi Ah.
Nê´u [Toa´ n haṇ g nguô` n] la` toa´ n haṇ g 16 bi´t thi` lêṇ h sẽ lâ´ y gia´ tri ̣củ a
thanh ghi Dx:Ax (sô´ bi ̣chia) căp̣
chia cho [Toa´ n haṇ g nguô` n] (sô´ chia), kê´t quả thư¢ng sô´ chư´ a trong thanh ghi Ax, sô´ dư chư´ a trong thanh ghi Dx.
Nê´u phe´p chia cho 0 xả y ra hay thư¢ng sô´ vư¢̣t qua´ gi¢´ i haṇ củ a thanh ghi AL (chia 8 bi´t) hay Ax
(chia 16 bi´t) thi` CPU sẽ pha´ t sinh lỗi - Lêṇ h Idiv (Integer Divide): Tư¢ng tự lêṇ h Div nhưng thực hiêṇ phe´p chia trên hai sô´ co´ dâ´ u. Kê´t
quả cu` ng la` ca´ c sô´ co´ dâ´ u. Vi´ dụ 1: - Mul Bl
; Ax ßAL * Bl: sô´ bi ̣nhân ngâ` m điṇ h trong Al - Mul Bx
; Dx:Ax ßAx * Bx: sô´ bi ̣nhân ngâ` m điṇ h trong Ax - Idiv Bl
; Ax/Bl, thư¢ng sô´ chư´ a trong Al, sô´ dư chư´ a trong Ah - Idiv Bx
; Dx:Ax/Bx, thư¢ng sô´ chư´ a trong Ax, sô´ dư trong Dx
Vi´ dụ 2: Dãy ca´ c lêṇ h dư¢´ i đây sẽ thực hiêṇ phe´p ga´ n A = 4*A – 3*B, trong đo´ A va` B la` ca´ c biê´n kiểu word: Mov Ax, 4
; sô´ nhân phả i đư¢̣c chư´ a trong Ax IMul A
; thực hiêṇ phe´p nhân Mov Bx, Ax ; lưu tam ̣ kê´t quả va` o Bx lOMoAR cPSD| 36066900 Mov Ax, 3 ; Ax = 3 Imul B ; Ax = Ax * B Sub Bx, Ax Mov A, Bx
; đăṭ kê´t quả cuô´ i cu` ng va` o A
Trong trư¢` ng h¢̣p na` y ta đã giả sử tư¢̣ng tra` n đã không xả y ra va` kê´t quả phe´ p nhân chỉ chư´ a hiêṇ trong thanh ghi Ax.
Vi´ dụ 3: Ca´ c lêṇ h sau đây thực hiêṇ phe´p: chia -123 cho 24: Mov Ax, -123
; đăṭ sô´ bi ̣chia va` o Ax Mov Bl, 24
; đăṭ sô´ chia va` o Bl (thanh ghi 8 bi´t) Idiv Bl
; chia Ax cho Bl, kê´t quả chư´ a ¢̉ Al va` Ah
Vi´ dụ 4: Dãy lêṇ h dư¢´ i đây sẽ thực hiêṇ phe´ p ga´ n A = N! (ti´nh N giai thư` a). A la` môṭ biê´n word: Mov Ax, 1
; chuẩ n bi ̣Ax để lưu kê´t quả Mov Cx, N ; ti´nh N! LapNhan: Mul Cx ; Ax ßAx * Cx Loop LapNhan ; Mov A, Ax
; trả kê´t quả va` o biê´n A
Trong trư¢` ng h¢̣p na` y chu´ ng ta giả sử kê´t quả không vư¢̣t qua´ g¢´ i 16 bi´t. haṇ
Chu´ ng ta đã biê´ t: N! = 1 nê´ u N = 1, N! = N*(N-1)*(N-2)*...*1 nê´u N>1, điê` u na` y hoa` n toa` n phu` h¢̣p v¢´ i
sự thay đổ i củ a thanh ghi CX trong lêṇ h lăp̣ Loop. Do đo´ , ¢̉ đây ta co´ thể sử dụng CX như la` N trong
biểu thư´ c ti´nh giai thư` a.
Chu´ y´ : H¢̣p ngữ cung câ´ p lêṇ h AAM (Asci Adjust for Multiple) để điê` u chinh kê´t quả phe´ p nhân trên
2 sô´ BCD dan g không dô` n. Va` lêṇ h AAD (Asci Adjust for Division) để điê` u h kê´ t quả phe´p chia chin
trên 2 sô´ BCD dan g không dô` n. Ngoa` i ra co` n co´ lêṇ h CBW (Convert Byte to Word) va` lêṇ h CWD
(Convert Word to Doubleword) để hỗ tr¢̣ cho phe´ p chia trên ca´ c sô´ co´ dâ´ u [2 – 187-200].
Lêṇ h IMul củ a vi xử ly´ Intel 80286 cho phe´ p ghi rõ [Toa´ n hang đi´ch], [Toa´ n haṇ g nguô` n] trong câu
lêṇ h, ca´ c lêṇ h na` y co´ thể co´ đê´ n 3 toa´ n han g [1 - 541]. 6. Lên
̣ h logic: NOT – AND – OR – XOR – TEST Trư¢´ c khi tim
hiểu vê` ca´ c lêṇ h logic chu´ ng ta xem laị kê´t quả thực hiêṇ ca´ c phe´ p ti´nh logic trên 2 bi´t
nhi ̣phân A va` B thông qua bả ng sau đây: A B A And B A Or B A Xor B NotA lOMoAR cPSD| 36066900 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 1 1 1 1 0 0
Bả ng trên cho thâ´ y: V¢´ i phe´p And: kê´t quả = 1 chỉ khi cả hai bi´t = 1; V¢´ i phe´p Or: kê´t quả = 0 chỉ khi
cả hai bi´t = 0; V¢´ i phe´p Xor: kê´t quả = 0 khi hai bi´t giô´ ng nhau, kê´t quả = 1 khi hai bi´t kha´ c nhau. V¢´ i
phe´p Not: 0 tha` nh 1, 1 tha` nh 0. Cu´ pha´ p:
Not [Toa´ n hạng đi´ch]
And [Toa´ n hạng đi´ch], [Toa´ n hạng nguô` n] Or
[Toa´ n haṇ g đi´ch], [Toa´ n hạng nguô` n]
Xor [Toa´ n hạng đi´ch], [Toa´ n hạng nguô` n]
Test [Toa´ n hạng đic´ h], [Toa´ n hạng nguô` n]
Trong đo´ : [Toa´ n haṇ g đi´ch], [Toa´ n hang nguô` n] co´ thể la` hă` ng sô´ (trực hă` ng), biê´ n, thanh ghi hay
điạ chỉ ô nh¢´ . [Toa´ n haṇ g đi´ch] không thể la` hă` ng sô´ . Ta´ c dun g: Mỗi lên
̣ h logic thực hiêṇ phe´p ti´nh logic tư¢ng ư´ ng trên ca´ c bi´t (tư¢ng ư´ ng vê` vi ̣tri´) củ a
[Toa´ n haṇ g đi´ch] va` [Toa´ n haṇ g nguô` n], kê´t quả đư¢̣c ghi va` o laị [Toa´ n haṇ g đi´ch]. Riêng lêṇ h Not,
thực hiêṇ phe´p đả o bi´t ngay trên ca´ c bi´t củ a [Toa´ n han g đi´ch]. Hâ` u hê´t ca´ c lêṇ h logic đê` u ả nh hư¢̉ ng
đê´n ca´ c c¢` CF, OF, ZF,... -
Lêṇ h Not (Logical Not): Thực hiêṇ viêc̣ đả o ngư¢̣c tư` ng bi´t trong nôị dung củ a [Toa´ n haṇ g đi´ch].
Lêṇ h na` y không la` m ả nh hư¢̉ ng đê´n ca´ c c¢` .
Lêṇ h Not thư¢` ng đư¢̣c sử dụng để taọ daṇ g bu` 1 củ a [Toa´ n haṇ g đi´ch]. -
Lêṇ h And (Logical And): Thực hiêṇ phe´p ti´nh logic And trên tư` ng căp̣ bi´t (tư¢ng ư´ ng vê` vi ̣tri´)
củ a [Toa´ n hang nguô` n] v¢´ i [Toa´ n haṇ g đi´ch], kê´t quả lưu va` o [Toa´ n haṇ g đi´ch].
Lêṇ h And thư¢` ng đư¢̣c sử dụng để xo´ a (= 0) môṭ hoăc̣ nhiê` u bi´t xa´ c điṇ h na` o đo´ trong môṭ thanh ghi. -
Lêṇ h Or (Logical Inclusive Or):Thực hiêṇ phe´ p ti´nh logic Or trên tư` ng căp̣ bi´t (tư¢ng ư´ ng vê` vi ̣tri´)
củ a [Toa´ n hang nguô` n] v¢´ i [Toa´ n haṇ g đi´ch], kê´t quả lưu va` o [Toa´ n haṇ g đi´ch].
Lêṇ h Or thư¢` ng du` ng để thiê´t (= 1) môṭ hoăc̣ nhiê` u bi´t xa´ c điṇ h na` o đo´ trong môṭ thanh ghi. lâp̣ -
Lêṇ h Xor (eXclusive OR):Thực hiêṇ phe´p ti´nh logic Xor trên tư` ng căp̣ bi´t (tư¢ng ư´ ng vê` vi ̣tri´) củ a
[Toa´ n haṇ g nguô` n] v¢´ i [Toa´ n haṇ g đi´ch], kê´t quả lưu va` o [Toa´ n hang đi´ch]. lOMoAR cPSD| 36066900
Lêṇ h Xor thư¢` ng du` ng để so sa´ nh (bă` ng nhau hay kha´ c nhau) gia´ tri ̣củ a hai toa´ n haṇ g, no´ cũng giu´ p
pha´ t hiêṇ ra ca´ c bi´t kha´ c nhau giữa hai toa´ n haṇ g na` y. -
Lêṇ h Test: Tư¢ng tự như lêṇ h And nhưng không ghi kê´t quả va` o laị [Toa´ n haṇ g đi´ch], no´ chỉ ả nh
hư¢̉ ng đê´ n ca´ c c¢` CF, OF, ZF,... Vi´ dụ 1: Mov Al,0 ; Al ß0 Not Al
; Al = Not Al. Tư´ c la` Al = 0FFh
Vi´ dụ 2: Cho AL = (10010011)2, BL = (11001100)2. - And Al, Bl
; Al ß 10010011 And 11001100. Al = - And Al, 0 ; Al ß 10010011 And 0. Al = - Or Bl, Al
; Bl ß 11001100 Or 10010011. Al = - Or Bl, 4 ; Bl ß 11001100 Or 100. Al = - Xor Al, Bl
; Al ß 10010011 Xor 11001100. Al = - Xor Bl, Bl
; Bl ß 11001100 Xor 11001100. Bl = 00000000
Vi´ dụ 3: Để xo´ a nôị dung thanh ghi na` o đo´ , trong h¢̣p ngữ ta co´ thể sử dụng môṭ trong ca´ c lêṇ h sau đây: - Mov Ax, 0 - Sub Ax, Ax - Xor Ax, Ax
; ca´ c căp̣ bi´t giô´ ng nhau thi` đê` u = 0
Vi´ dụ 5: Lêṇ h sau đây sẽ xo´ a (= 0) ca´ c bi´t 3 va` 6 củ a thanh ghi AL, ca´ c bi´t kha´ c giữ nguyên gia´ tri:̣ - And AL, 10110111b
; AL ßAL And 10110111
Trong trư¢` ng h¢̣p na` y: dãy bi´t 10110111 đư¢̣c goị la` dãy bi´t măṭ na,̣ ca´ c bi´t 3 (= 0) va` 6 (= 0) đư¢̣c
goị la` ca´ c bi´t măṭ na.̣ Như vâỵ muô´ n la` m cho bi´t na` o = 0 ta cho bi´t măṭ nạ tư¢ng ư´ ng v¢´ i no´ = 0, ca´ c
bi´t co` n laị trong dãy bi´t măṭ nạ đê` u = 1.
Vi´ dụ 6: Lệnh sau đây sẽ thiê´t lâp
̣ (= 1) ca´ c bi´t 3 va` 6 củ a thanh ghi AL, ca´ c bi´t kha´ c giữ nguyên gia tri:̣ - Or AL, 01001000b
; AL ßAL Or 01001000
Trong trư¢` ng h¢̣p na` y: dãy bi´t 01001000 đư¢̣c goị la` dãy bi´t măṭ na,̣ ca´ c bi´t 3 (= 1) va` 6 (= 1) đư¢̣c
goị la` ca´ c bi´t măṭ na.̣ Như vâỵ muô´ n la` m cho bi´t na` o = 1 ta cho bi´t măṭ nạ tư¢ng ư´ ng v¢´ i no´ = 1, ca´ c
bi´t co` n laị trong dãy bi´t măṭ nạ đê` u = 0.
Vi´ dụ 7: Lêṇ h sau đây sẽ kiểm tra bi´t 12 củ a thanh ghi AX la` = 0 hay = 1: - And AX, 0001000000000000b
; AX ßAX And 0001000000000000
V¢´ i dãy bi´t măṭ nạ như trên, nê´u bi´t 12 củ a Ax = 0 thi` kê´t quả : Ax = 0, nê´u bi´t 12 củ a Ax = 1 thi` kê´t quả : Ax <> 0. lOMoAR cPSD| 36066900
Ca´ ch du` ng lêṇ h And như trên để kiểm tra bi´t i´t đư¢̣c sử dụng, vi` no´ la` m thay đổi gia´ tri ̣củ a thanh ghi
câ` n kiểm tra (điều này có thể khắc phục bằng lệnh Test) va` phả i thêm bư¢´ c kiểm tra gia´ tri ̣củ a Ax (=
0 hay <> 0) m¢´ i biê´t đư¢̣c kê´t quả kiểm tra. Ngoa` i ra, no´ cũng chỉ kiểm tra đư¢̣c 1 bi´t.
Trong thực tê´ ngư¢` i ta thư¢` ng sử dụng kê´t h¢̣p giữ a ca´ c lêṇ h dic̣ h bi´t, lêṇ h quay bi´t, lêṇ h nhả y,... để
kiểm tra ca´ c bi´t trong môṭ thanh ghi. 7. Lên
̣ h chuyể n dũ liêu qua cổ ng: IN và OUT Cu´ pha´ p: IN
AL, <Địa chỉ cổng> OUT
<Địa chỉ cổng>, AL
Trong đo´ :<Địa chỉ cổng> chính là số hiệu cổng (port) mà lệnh nhận nhiệm vụ trao đổi dữ liệu qua nó.
Địa chỉ cổng có thể được ghi trực tiếp dưới dạng một hằng số hoặc được ghi thông qua thanh ghi Dx. Ta´ c dung: -
LênhIn (Input): Đọc một lượng dữ liệu 8 bít từ cổng được chỉ ra ở <Địa chỉ cổng> đưa vào lưu trữ trong thanh ghi AL.
Nếu địa chỉ cổng nằm trong giới hạn từ 0 đến FF (hệ thập lục phân) thì có thể viết trực tiếp trong câu
lệnh, nếu địa chỉ cổng lớn h¢n FF thì ta phải dùng thanh ghi Dx để chỉ định địa chỉ cổng.
- LệnhOut (Output): Gởi một lượng dữ liệu 8 bít từ thanh ghi AL ra cổng được chỉ ra ở <Địa chỉ
cổng>. Tư¢ng tự lệnh In, địa chỉ cổng có thể được viết trực tiếp trong câu lệnh hoặc thông qua thanh ghi Dx. Vi´ dụ 1: - In Al, 40h ; - Mov Dx, 3B0h ; In Al, Dx ; Ví dā 2: - Out 40h, Al ; - Mov Dx, 3B0h ; Out Dx, Al ; Ví dā 3: Các khai báo hằng: DAT EQU 13h ; POR EQU 7Ch ; Các lệnh: Mov Al, POR ; lOMoAR cPSD| 36066900 Mov Bl, DAT ; Out Bl, Al ;
Vi´ dụ 1: Giả sử taị điạ chỉ 0100:0120 trong bộ nh¢´ co´ chư´ a môṭ mả ng dữ liêụ , gô` m 100 ô nh¢´ , mỗi ô
la` 1 word. Hãy ti´nh tổ ng nôị dung củ a ca´ c ô nh¢´ na` y, kê´t quả chư´ a trong thanh ghi Dx. Mov Ax, 0100 Mov DS, Ax
; trỏ cẳp thanh ghi DS:DI vể Mov DI, 0120
; đẩu vủng nhở cẩn truy xuẩt (0100:0120) ; Mov Dx, 0
; chuẩn bỉ Dx để lưu tổng Mov Cx, 100
; lẳp 100 lẩn vỉ mảng gổm 100 ô nhở Lap_TT: Add Dx, DS:[DI]
; cổng thêm n/dung ô nhở chỉ bởi DS:DI vảo Dx nên Add DI, 2
; chỉ đển ô nhở kể tiểp (vỉ ô nhở word tăng 2) Loop Lap_TT
; lẳp lải đủ 100 lẩn (duyểt qua đủ 100 ô nhở) ;
Kê´t thu´ c đoaṇ lêṇ h trên tổ ng nôị dung củ a 100 word nh¢´ bă´t đâ` u taị điạ chỉ 0100:0120 trong bộ nh¢´
đư¢̣c lưu va` o thanh ghi Dx. ¡̉ đây chu´ ng ta bỏ qua khả năng tra` n dữ liêụ trong thanh ghi kê´t quả Dx.
Ví dā 2: Các lệnh sau đây sẽ copy 100 word dữ liệu từ vùng nhớ bắt đầu tại địa chỉ 0100:0120 sang
vùng nhớ bắt đầu tại 0100:0500: Mov Ax, 0100 Mov DS, Ax Mov SI, 0120
; trỏ DS:SI về vùng nhớ nguồn 0100:0120 Mov DI, 0500
; trỏ DS:DI về vùng nhớ địch 0100:0500 ; Mov Cx, 100 Lap_Copy: Mov Ax, DS:[SI]
; lưu tạm nội dụng word nhớ tại DS:SI vào Ax Mov DS:[DI], Ax
; ghi giá trị Ax và word nhớ tại DS:DI Add SI, 2
; đến word nhớ tiếp theo Add DI, 2 lOMoAR cPSD| 36066900 Loop Lap_Copy ;
Hai vùng bộ nhớ đã cho đều ở trong cùng một segment nên ở đây ta chỉ cần sử dụng một thanh ghi đoạn dữ liệu DS.
Vi´ dụ 3: Các lệnh sau đây sẽ tính tổng nội dung của 100 ô nhớ (100 byte nhớ) trong bộ nhớ, bắt đầu
tại địa chỉ 0A00:0120. Kết quả được lưu vào word nhớ ngay trước vùng nhớ này: Mov Ax, 0A00h Mov ES, Ax Mov SI, 0120h
; trỏ DS:SI về vùng nhớ nguồn 0A00:0120 Mov DI, SI
; trỏ DS:DI về vùng nhớ nguồn 0A00:0120 Sub DI,2
; trỏ DS:DI về word nhớ trước vùng nhớ nguồn ; Mov Cx, 100 Mov Dx, 0 ; DX chứa tổng TTong: Add Dx, Byte PTR ES:[SI]
; cộng n.d của byte nhớ tại ES:SI vàoDX Inc SI ; ô nhớ byte Loop TTong ; Mov Word PTR ES:[DI], DX ;
Trong đoạn lệnh trên chúng ta sử dụng toán tử PTR để định kiểu ô nhớ cần truy xuất.
Lệnh Add Dx, Byte PTR ES:[SI]: lấy nội dung của byte nhớ tại ô nhớ được chỉ bởi ES:SI cộng
thêm vào thanh ghi DX. Nếu ta viết Add Dx, ES:[SI] thì hệ thống lấy giá trị cả 1 word tại ES:SI
cộng thêm vào DX (vì DX là thanh ghi word (16 bít), điều này không đúng với thực tế, vì chúng ta
đang cần truy xuất đến các byte nhớ. Trong trường hợp này, nếu không dùng toán tử PTR thì lệnh
Add phải viết như sau: Add DL, ES:[SI], khi đó hệ thống chỉ lấy giá trị cả 1 byte tại ES:SI cộng
thêm vào DL (vì DL là thanh ghi byte: 8 bít),
Ví dā 4: Các lệnh sau đây sẽ copy toàn bộ 20 kí tự Ascii từ biến Xau1 vào biến Xau2. Giả sử Xau1
và Xau2 đã được khai báo trước như sau: Xau1 DB 8Khoa CNTT – DHKH Hue9 Xau2 DB 20 Dup (8 9) Các lệnh: Mov Ax, @Data lOMoAR cPSD| 36066900 Mov DS, Ax Lea SI, Xau1 Lea DI, Xau2 ; Mov Cx, 20 Lap_Copy: Mov Al, Byte PTR DS:[SI] Mov Byte PTR DS:[DI], Al Inc SI Dec DI Loop Lap_Copy ;
Các biến của chư¢ng trình h¢̣p ngữ được khai báo trong đoạn Data. Hai lệnh đầu tiên ở trên có tác
dụng lấy địa chỉ segment của đoạn Data đưa vào thanh ghi đoạn DS. Do đó, DS sẽ chứa địa chỉ
segment của hai biến Xau1 và Xau2. Hay cụ thể: DS:SI trỏ về biến Xau1 và DS:DI trỏ về Xau2.
Ví dā 5: Chư¢ng trình sau đây: Để in một xâu kí tự từ trong chư¢ng trình ra màn hình văn bản đ¢n sắc (môi trường MSDOS). Chú ý:
- BIOS và MSDOS đã cung cấp nhiều hàm/ngắt để chư¢ng trình h¢̣p ngữ ghi một kí tự hoặc một
xâu kí tự ra màn hình, tại vị trí hiện tại của con trỏ màn hình hoặc tại một tọa độ màn hình xác định
nào đó. Kỹ thuật này được gọi là kỹ thuật ghi ra màn hình gián tiếp thông qua các hàm/ngắt màn hình.
- Biết rằng, tất cả những thông tin mà chúng ta thấy được trên màn hình của một máy tính đều
được lưu trữ trong bộ nhớ màn hình của máy tính đó, theo một cách nào đó. Tức là, nọi thao tác
ghi/đọc trên màn hình đều phải thông qua bộ nhớ màn hình. Như vậy: Muốn ghi một xâu kí tự ra màn
hình chư¢ng trình có thể ghi nó vào bộ nhớ màn hình. Muốn đọc một xâu kí tự từ màn hình chư¢ng
trình có thể đọc nó từ bộ nhớ màn hình. Kỹ thuật này được gọi là kỹ thuật truy xuất trực tiếp bộ nhớ màn hình.
- Mỗi hệ điều hành, mỗi chế độ màn hình sử dụng một đoạn bộ nhớ xác định (thường là khác
nhau) cho bộ nhớ màn hình. Và cách tổ chức lưu trữ thông tin trên màn hình trong bộ nhớ màn hình
cũng khác nhau với các hệ điều hành, các chế độ màn hình khác nhau.
- Trên môi trường hệ điều hành MSDOS, bộ nhớ màn hình của chế độ nàm hình đ¢n sắc 25 dòng
(0 đến 24) x 80 cột (0 đếm 79) được lưu trữ tại segment nhớ 0B800, bắt đầu tại offset 0000.
- Tổ chức lưu trữ thông tin trên màn hình trong bộ nhớ màn hình loại này như sau: Mỗi kí tự trên
nàm hình chiếm 1 word trong bộ nhớ màn hình: byte thấp chứa mã ASCII của kí tự, byte cao chứa
thuộc tính (màu chữ, màu nền,...) của kí tự đó. Từng dòng kí tự trên màn hình, từ trái sang phải (từ
cột 0 đến cột 79), được lưu tữ lần lượt tại các offset liên tiếp nhau trong bộ nhớ màn hình: 80 kí tự lOMoAR cPSD| 36066900
của dòng 0 được lưu trữ tại 80 word đầu tiên, 80 kí tự của dòng 1được lưu trữ tại 80 word tiếp
theo,... , 80 kí tự của dòng 79ược lưu trữ tại 80 word cuối cùng trong bộ nhớ nàm hình. Như vậy ta
dễ dàng tính ra được offset trong bộ nhớ màn hình, tư¢ng ứng với một kí tự trên màn hình khi ta biết
được tọa độ (dòng, cột) của nó. Cụ thể, offset của kí tự tạo tọa độ (Dòng, Cßt) được tính theo công thức sau:
(80*(Dong - 1) + (Cot - 1))*2 -
Bộ nhớ màn hình loại này có kích thước là 25 x 80 x 2 (byte) = 40000 byte. lOMoAR cPSD| 36066900
NG¾T TRONG CH¯¡NG TRÌNH ASSEMLBLY
Ngắt (Interrupt) là các tín hiệu mà các thành phần trong hệ thống, như: thiết bị ngoại vi, hệ điều hành,
chư¢ng trình người sử dụng, ..., gửi đến vi xử lý (họ Intel) mỗi khi nó cần trao đổi thông tin với vi xử
lý hay cần được sự phục vụ từ vi xử lý. Ngắt cũng có thể phát sinh từ chính bên trong vi xử lý khi nó
phát hiện một lỗi nghiêm trong xảy ra trong quá trình xử lý của nó. Khi nhận được một tín hiệu yêu
cầu ngắt vi xử lý sẽ dừng ngay thao tác (lệnh) hiện tại để xem xét và đáp ứng yêu cầu ngắt đó, sau
đo mới tiếp tục lại từ thao tác (lệnh) mà nó bị dừng trước đó.
Các máy IBM_PC, sử dụng vi xử lý Intel, bao gồm nhiều loại ngắt: Ngắt phần cứng, ngắt phần mềm,
ngắt bên trong, ngắt không chắn được (ngắt có độ ưu tiên cao nhất). Trong đó ngắt phần mềm là các
ngắt được phát sinh từ hệ điều hành và chư¢ng trình của người sử dụng, điều này thường thấy trong
các chư¢ng trình h¢̣p ngữ .
Hệ thống các ngắt mềm bên trong máy tính IBM_PC được cung cấp bởi BIOS và hệ điều hành, gồm
256 ngắt, chúng được đánh số từ 0 đến 255 và được gọi là số hiêu ngắt. Mỗi ngắt mềm tư¢ng ứng
với một chư¢ng con được gọi là chư¢ng trình con phục vụ ngắt, tức là, để đáp ứng một yêu cầu ngắt
mềm thì hệ thống sẽ phải thực hiện một chư¢ng trình con phục vụ ngắt tư¢ng ứng.
H¢̣p ngữ cung cấp lệnh Int để các chư¢ng trình gọi một ngắt mềm khi cần. Khi gọi ngắt mềm chư¢ng
trình phải chỉ ra số hiệu ngắt cần gọi, khi đó hệ thống sẽ phải gọi thực hiện chư¢ng trình con phục vụ
ngắt tư¢ng ứng để đáp ứng yêu cầu gọi này.
Trong môi trường hệ điều hành 16 bít MSDOS, ngay sau khi khởi động, hệ điều hành nạp tất cả 256
chư¢ng trình con phục vụ ngắt vào bộ nhớ. Khi đó 256 địa chỉ (Segment:Offset) các vùng nhớ,
n¢i định vị của 256 chư¢ng trình con phục vụ ngắt, sẽ được lưu trữ tại một không gian nhớ đặc biệt
trong bộ nhớ, vùng nhớ này được gọi là bảng vector ngắt (mỗi địa chỉ định vị của một chư¢ng trình
con phục vụ ngắt được gọi là một vector ngắt.
Như vậy khi hệ thống nhận được một yêu cầu ngắt n (Int n) từ chư¢ng trình thì nó phải: 1. Dừng
lệnh hiện tại, đưa giá trị con trỏ lệnh CS:IP hiện tại (đó chính là địa chỉ của lệnh sau lệnh gọi ngắt)
vào lưu trữ ở hai phần tử trên đỉnh Stack; 2. Xác định phần tử (địa chỉ) trong bảng vector ngắt chứa
vector ngắt của ngắt n, lấy giá trị tại đây (2 phần tử liên tiếp) để đưa vào cặp thanh ghi con trỏ lệnh
CS:IP (đây chính là địa chỉ của lệnh đầu tiên của chư¢ng trình con phục vụ ngắt n trong bộ nhớ); 3.
Bắt đầu thực hiện chư¢ng trình con phục vụ ngắt cho đến khi gặp lệnh kết thúc chư¢ng trình này, đó
là lệnh Iret; 4. Lấy nội dung của hai phần tử trên đỉnh Stack đặt vào lại cặp thanh ghi con trỏ lệnh để
quay trở lại tiếp tục thực hiện lệnh sau lệnh gọi ngắt trong chư¢ng trình.
Những vấn đề liên quan đến Stack và cơ chế của một lßi gọi ngắt sẽ được chúng tôi làm rõ hơn á
phần sau của tài liệu này. 1.Lên ̣ h Int Cu´ pha´ p: Int <n>
Trong đo´ : Trong đó là số hiệu ngắt của một ngắt mềm cần gọi. Tức là, n có thể là một trong các
giá trị từ 0 đến 255, đó chính là số hiệu ngắt của 256 ngắt mềm mà BIOS và MSDOS cung cấp. lOMoAR cPSD| 36066900 Ta´ c dun
g: Lệnh Int (Interrupt) được sử dụng để gọi một ngắt mềm (của BIOS hoặc MSDOS) trong
chư¢ng trình h¢̣p ngữ. Khi một ngắt mềm được gọi thì hệ thống sẽ thực hiện chư¢ng trình con phục
vụ ngắt tư¢ng ứng với nó. Ví dā 1: Int 10h ; gọi ngắt 10h của BIOS Int 20h
; gọi ngắt 20h của MSDOS
Một ngắt mềm, hay chính xác h¢n là một chư¢ng trình con phục vụ ngắt, có thể thực hiện nhiều chức
năng khác nhau, mỗi chức năng này được thể hiện thông qua một con số, được gọi là số hiệu hàm
của ngắt. Do đó, trước khi gọi ngắt chư¢ng trình phải chỉ rõ gọi ngắt với hàm nào, bằng cách đặt số
hiệu hàm cần gọi vào thanh ghi AH. Ví dā 2: Mov Ah, 01
; gọi ngắt 21h với hàm 01, Hay nói ngược lại: gọi hàm Int 21h ; 01 của ngắt 21h
Trước khi gọi hàm/ngắt chư¢ng trình cần cung cấp đầy đủ dữ liệu vào (nếu có) cho nó, sau khi
hàm/ngắt được thực hiện chư¢ng trình cần xác định rõ nó có trả về dữ liệu kết quả (dữ liệu ra) hay
không, nếu có thì chứa ở đâu: thanh ghi hay ô nhớ, và có tác động đến các cờ hiệu hay không. Vi´ dụ 3: Mov Ah, 02
; đặt số hiệu hàm cần gọi vào AH Mov DH, 10
; cung cấp dữ liệu vào thứ nhất vào DH Mov DL, 20
; cung cấp dữ liệu vào thứ hai vào DL Int 10h
; gọi ngắt 10h với hàm 02. Hàm/ngắt này không
; trả về dữ liệu kết quả.
Dãy lệnh trên thực hiện việc gọi hàm 02 của ngắt 10h (ngắt của BIOS), nó thực hiện việc dịch chuyển
con trỏ đến dòng 10 cột 20 của màn hình văn bản. Ví dā 4: Mov Ah, 2Bh ; gọi ngắt 21h với Int 21h ; hàm 2Bh
Hàm này trả về ngày-tháng-năm hiện tại (theo đồng hồ hệ thống trên máy tính). Cụ thể: Thanh ghi CX
(1980-2099) chứa năm hiện tại, thanh ghi DH (1-12) chứa tháng hiện tại, thanh ghi DL (1-31) chứa
ngày hiện tại. Đồng thời AL cho biết ngày trong tuần (0 : chủ nhật, 6 : thứ 7).
Môt sô´ ha` m củ a ngă´t 21h (MSDOS)
Ngắt 21h của MSDOS là ngắt thưßng được sử dụng nhất, nên á đây chúng tôi chọn giới thiệu
về ngắt này, nhưng chỉ với các hàm vào/ra kí tự/xâu kí tự cơ bản. Chức năng của mỗi ngắt, chức lOMoAR cPSD| 36066900
năng của các hàm trong một ngắt, các yêu cầu dữ liệu vào/ra của từng hàm trong mỗi ngắt,... dễ
dàng tìm thấy trong các tài liệu về lập trình hệ thống.

Ha` m 02 cũa ng¿t 21h: Ta´ c dun
g: In một kí tự ra màn hình. Kí tự (hoặc mã ASCII của kí tự) cần in được đặt trước trong
thanh ghi DL. Kí tự ở đây có thể là kí tự thường hoặc kí tự điều khiển. Sủ dung: Va` o: Ah = 02 Dl = Ra: Không có
Vi´ dụ 1: Các lệnh sau đây in ra màn hình kí tự A: Mov Ah, 02 Mov Dl, 8A9
;có thể viết lệnh Mov Dl, 41h Int 21h
; 41h là mã ASCII của kí tự A
Ví dā 2: Các lệnh sau đây in ra màn hình 10 kí tự, bắt đầu từ kí tự A: Mov Cx, 10 Mov Ah, 02 Mov Dl, 8A9 Lap_In: Int 21h INC DL Loop Lap_In
Ví dā 3: Các lệnh sau đây in xâu kí tự từ trong biến TieuDe ra màn hình. Giả sử rằng biến TieuDe đã được khai báo như sau: TieuDe DB 8Khoa CNTT Truong DHKH Hue9 Các lệnh: Lea DI, TieuDe Mov Cx, 25 Mov Ah, 02 Lap_In: Mov Dl, Byte PTR [DI] Int 21h INC DI lOMoAR cPSD| 36066900 Loop Lap_In ;
Ví dā 4: Giả sử tại địa chỉ 0A00:0100 trong bộ nhớ có chứa một xâu kí tự ASCII, gồm 50 kí tự. Các
lệnh sau đây sẽ in xâu kí tự nói trên ra màn hình. Mov Ax, 0A00h Mov ES, Ax Mov DI, 0100h ; Mov Cx, 50 Mov Ah, 02 Lap_In: Mov Dl, Byte PTR ES:[DI] Int 21h INC DI Loop Lap_In ;
Ha` m 09 cũa ng¿t 21h: Ta´ c dun
g: In một dãy kí tự (một xâu kí tự) ra màn hình. Địa chỉ của xâu cần in này phải được chỉ bởi
cặp thanh ghi DS:DX và xâu phải được kết thúc bởi dấu $. Sủ dung: Va` o: Ah = 09 DS:DX = Ra: Không có
Vi´ dụ 1: Giả sử chư¢ng trình đã khai báo biến TieuDe. Viết lệnh in nội dung của biến TieuDe ra màn hình: -
Trong trường hợp này biến TieuDe phải được khai báo trước như sau: TieuDe DB 8Truong DH Khoa hoc Hue$9 -
Và đoạn lệnh gồm các lệnh sau: Mov Ah, 09 Mov Ax, Seg TieuDe Mov DS, Ax Mov Dx, Offset TieuDe
; có thể dùng lệnh Lea TieuDe lOMoAR cPSD| 36066900 Int 21h
Trong thự tế, với các chư¢ng trình h¢̣p ngữ viết ở dạng đoạn giản đ¢n, thì không cần đưa địa chỉ
Segment của biến cần in vào DS. Bởi vì: -
Đối với các chư¢ng trình dạng COM: -
Đối với các chư¢ng trình dạng EXE:
Ví dā 2: Giả sử biến TieuDe đã được khai báo như sau: TieuDe DB 8Khoa CNTT Truong DHKH Hue$9
Các lệnh sau chỉ in các kí tự Mov Ax, Segment TieuDe Mov DS, Ax Mov Dx, TieuDe Add Dx, 11 Mov Ah, 09 Int 21h
Các lệnh sau chỉ in các kí tự Mov Ax, Segment TieuDe Mov DS, Ax Mov Dx, TieuDe Mov DI, Dx Add DI, 10 Mov Byte PTR DS:[DI], 8$9 Mov Ah, 09 Int 21h
Ví dā 3: Giả sử tại địa chỉ 0A00:0100 trong bộ nhớ có chứa một xâu kí tự ASCII, gồm 50 kí tự. Các
lệnh sau đây sẽ in xâu kí tự nói trên ra màn hình. Mov Ax, 0A00h Mov DS, Ax Mov Dx, 0100h ; Mov DI, Dx Mov Cx, 50 Add DI, Cx lOMoAR cPSD| 36066900 Mov Byte PTR DS:DX, 8$9 ; Mov Ah, 09 Int 21h ;
Ha` m 01 cũa ng¿t 21h: Ta´ c dun
g:Nhập một kí tự từ bàn phím vào lưu trong thanh ghi AL. Cụ thể là, AL sẽ chứa mã ASCII
của kí tự ghi trên phím nhập. Sủ dung: Va` o: Ah = 01 Ra:
Al = 0: nếu phím nhập là một trong các phím chức năng
Al = < mã ASCII của kí tự ghi trên phím nhập>
Cụ thể như sau: Khi chư¢ng trình gọi ngắt 21h với hàm 01 thì màn hình sẽ xuất hiện một con trỏ
nhập, để người sử dụng nhập vào một kí tự từ bàn phím. Khi đó, nếu người sử dụng gõ một trong
các phím chức năng thì AL nhận được giá trị 0, nếu người sử dụng gõ một phím kí tự nào đó thì AL
nhận được mã ASCII của kí tự đó.
Chú ý: Hàm 08 của ngắt 21h có chức năng tư¢ng tự hàm 01 ngắt 21h nhưng kí tự trên phím gõ
không xuất hiện trên màn hình, tất cả đều được xuất hiện bởi kí tự 8*9. Vi´ dụ 1: Mov Ah, 01
; với hai lệnh này màn hình sẽ xuất hiện con trỏ Int 21h
; nhập để người sử dụng nhập một kí tự vào AL
Ví dā 2: Các lệnh sau đây cho phép nhập một xâu kí tự, với số lượng kí tự được ấn định trước, vào
biến LuuXau đã khai báo trước trong chư¢ng trình
Giả sử biến LuuXau được khai báo như sau: LuuXau DB 30 Dup (8 8) Các lệnh: Mov Ax, Seg LuuXau Mov DS, Ax Lea DI, LuuXau ; Mov Cx, 30 Mov Ah, 01 Nhap_Xau: lOMoAR cPSD| 36066900 Int 21h Mov Byte PTR DS:[DI], Al INC DI Loop Nhap_Xau ;
Trong trường hợp này chúng ta đã giả sử: Người sử dụng chỉ nhập các kí tự (gõ phím kí tự để nhập),
không nhập các phím chức năng.
Trong thực tế, không bao giờ chúng ta sử dụng hàm 01 ngắt 21h để nhập xâu, vì nó tồn tại hai hạn
chế: không thể kết thúc nhập bằng cách gõ phím Enter; số kí tự của xâu nhập phải được ấn định
trước trong chư¢ng trình. Để khắc phục, MSDOS cung cấp hàm 0Ah của ngắt 21h để hỗ trợ nhập xâu kí tự.
Ha` m 0Ah cũa ng¿t 21h: Ta´ c dun
g:Nhập một xâu kí tự vào một biến đệm cho trước trong chư¢ng trình, biến này phải được
chỉ bởi cặp thanh ghi DS:DX. Và biến đệm phải có dạng như sau: -
Byte 0: chứa số kí tự tối đa của xâu nhập vào -
Byte 1: chứa một trị không (= 0) -
Byte 2, byte 3, byte 4, ... chứa một trị rỗng (để trống), để chứa các kí tự sẽ được nhập vào sau
này (khi chư¢ng trình thực hiện).
Để có được một biến như trên chư¢ng trình phải khai báo biến (tên biến là Xau_Nhap) như sau: Xau_Nhap DB 256, 0, 256 Dup (8 8)
Như vậy Xau_Nhap là một biến kiểu byte, gồm 258 byte. Byte đầu tiên (byte) chứa trị 256, byte 1
chứa trị 0, 256 byte tiếp theo chứa kí tự trống, được sử dụng để chứa các kí tự sẽ được nhập sau
này. Xau_Nhap chứa tối đa 256 kí tự.
Cũng có thể sử dụng hàm 0Ah/21h để nhập một xâu kí tự vào vùng nhớ có địa chỉ xác định trong bô nhớ. Sủ dung: Va` o: Ah = 0Ah
DS:DX = <Địa chỉ Segment:Offset của xâu nhập> Ra: DS:DX không thay đổi
Biến đệm bây giờ có dạng như sau: - Byte 0: không thay đổi -
Byte 1: chứa tổng số kí tự đã được nhập vào -
Byte 2, byte 3, byte 4, ... chứa các kí tự đã được nhập vào. lOMoAR cPSD| 36066900
Vi´ dụ 1: Với khai báo biến đệm Xau_Nhap như trên, nếu sau này chư¢ng trình nhập vào xâu: hoc= thì: - Byte 0: vẫn chứa số 256 -
Byte 1: chứa giá trị 7, đó chính là 7 kí tự trong xâu -
Từ byte 2 đến 8 chứa lần lượt các kí tự trong xâu
Ví dā 2: Giả sử chư¢ng trình đã khai báo xâu TieuDe như sau: TieuDe DB 100, 0, 100 Dup (8 8)
Các lệnh sau đây sử dụng hàm 0Ah/21h để nhập một xâu kí tự vào biến TieuDe: Mov Ax, Seg TieuDe Mov Ds, Ax Lea Dx, TieuDe Mov Ah, 0Ah Int 21h
Các lệnh sau đây lấy số kí tự thực sự nhập đưa vào lưu trữ trong thanh ghi Cx: Mov Cx, 0 Mov Cl, TieuDe[1]
Các lệnh sau đây sử dụng hàm 02/21h để in xâu kí tự vừa nhập ra lại màn hình: Lea DI, TieuDe Mov Cx, 0 Mov Cl, TieuDe[1] Add DI, 2 Mov Ah, 02 Lap_In: Mov Dl, DS:[DI] Int 21h INC DI Loop Lap_In
Các lệnh sau đây sử dụng hàm 09/21h để in xâu kí tự vừa nhập ra lại màn hình: Mov Ax, Seg TieuDe Mov Ds, Ax Lea Dx, TieuDe lOMoAR cPSD| 36066900 Add Dx, 2 Mov DI, Dx Mov Cx, 0 Mov Cl, TieuDe[1] Add DI, Cx Mov Byte PTR DS:[DI], 8$9 Mov Ah, 09h Int 21h
Ví dā 3: Chư¢ng trình dạng COM sau đây sử dụng hàm 0Ah ngắt 21h để nhập một xâu kí tự vào
biến Buff. Sau đó sử dụng hàm 09h ngắt 21h để in xâu kí tự vừa nhập ra lại màn hình.
Để đ¢n giản, chư¢ng trình khai báo biến Buff gồm toàn kí tự 8$9, nhờ đó, khi dùng hàm 09h/21h để
in ra chư¢ng trình không cần đưa thêm kí tự 8$9 vào cuối xâu nhập, mà chỉ cần trỏ DS:DX về đầu
vùng/xâu kí tự cần in ra. .Model small .Code ORG 100h Start: JMP Main
TBN DB 'Nhap vao mot xau ki tu: $'
TBX DB 0Ah,0Dh,'Xau vua nhap: $' Buff DB 100,0,100 Dup ('$') Main Proc Mov Ah, 09h Lea Dx, TBN Int 21h ; Mov Ah, 0Ah Lea Dx, Buff Int 21h ; Mov Ah, 09h Lea Dx, TBX lOMoAR cPSD| 36066900 Int 21h ; Mov Ah, 09h Lea Dx, Buff Add Dx, 2 Int 21h ; Int 20h Main Endp End Start Mßt sß ví dā:
Vi´ dụ 1: Giả sử hàm X của ngắt Y khi được gọi sẽ trả về trong cặp thanh ghi ES:SI địa chỉ của vùng
nhớ chứa tên của nhà sản xuất (nhãn hiệu) của vi xử lý đang sử dụng trên máy tính hiện tại, tên này dài không quá 8 kí tự.
Các lệnh sau đây sẽ in tên nhà sản xuất nói trên ra màn hình: Mov Ah, X
; hàm cần gọi được đưa vào thanh ghi ah Int Y ; gọi ngắt Y với hàm X ; Mov Cx, 8
; tên dài không quá 8 kí tự Mov Ah, 02
; dùng hàm 02/21h để in kí tự ra nàm hình LapIn: Mov Dl, Byte PTR ES:[SI] Int 21h INC SI ; đến kí tự tiếp theo Loop LapIn ;
Ví dā 2: Giả sử hàm X của ngắt Y khi được gọi với AL = 1 (được gọi là hàm con) sẽ trả về trong cặp
thanh ghi ES:DI địa chỉ của vùng nhớ chứa ngày-tháng-năm sản xuất ROM-BIOS đang sử dụng trên
máy tính hiện tại. Đồng thời hàm/ngắt này cũng cho biết số kí tự trong xâu ngày-tháng-năm trong thanh ghi BX.
Các lệnh sau đây sẽ in xâu ngày-tháng-năm nói trên ra màn hình: Mov Ah, X
; hàm cần gọi được đưa vào thanh ghi ah Mov Al, 1 ; gọi hàm X với Al = 1 lOMoAR cPSD| 36066900 Int Y ; gọi ngắt Y với hàm X ; Mov Cx, Bx
; đưa số kí tự của xâu ngày-tháng-nămvào Cx Mov Ah, 02
; dùng hàm 02/21h để in kí tự ra nàm hình LapIn: Mov Dl, Byte PTR ES:[DI] Int 21h INC DI ; đến kí tự tiếp theo Loop LapIn ;
Ví dā 3: Hàm 39h của ngắt 21h được sử dụng để tạo thư mục con trên đĩa. Hàm này quy định:
DS:DX chứa xâu tên thư mục cần tạo, bao gồm cả đường dẫntìm đến thư mục này, xâu này kết thúc
bởi trị 0. Nếu việc tạo không thành công thì Cf = 1, khi đó thanh ghi Ax sẽ chứa mã lỗi.
Các lệnh sau đây sẽ tạo ra thư mục con BTCB trong thư mục ASSEM trên thư mục gốc ổ đĩa D.
Chư¢ng trình phải khai báo biến TenTM, chứa xâu tên thư mục cần tạo như sau: TenTM DB 8D:\ASSEM\BTCB9,0 Các lệnh: Mov Ax, Seg TenTM Mov DS, Ax Mov Dx, Offset TenTM Mov Ah, 39h Int 21h ; Jc TB_Loi
; nếu CF = 1 thì việc tạo bị lỗi Jmp KetThuc TB_Loi: KetThuc: ... ; MÞT SÞ VÍ DĀ lOMoAR cPSD| 36066900
Ví dā 1: Giả sử hàm X của ngắt Y khi được gọi sẽ trả về trong cặp thanh ghi ES:SI địa chỉ của vùng
nhớ chứa tên của nhà sản xuất (nhãn hiệu) của vi xử lý đang sử dụng trên máy tính hiện tại, tên này dài không quá 8 kí tự.
Các lệnh sau đây sẽ in tên nhà sản xuất nói trên ra màn hình: Mov Ah, X
; hàm cần gọi được đưa vào thanh ghi ah Int Y ; gọi ngắt Y với hàm X ; Mov Cx, 8
; tên dài không quá 8 kí tự Mov Ah, 02
; dùng hàm 02/21h để in kí tự ra nàm hình LapIn: Mov Dl, Byte PTR ES:[SI] Int 21h INC SI ; đến kí tự tiếp theo Loop LapIn ;
Ví dā 2: Giả sử hàm X của ngắt Y khi được gọi với AL = 1 (được gọi là hàm con) sẽ trả về trong cặp
thanh ghi ES:DI địa chỉ của vùng nhớ chứa ngày-tháng-năm sản xuất ROM-BIOS đang sử dụng trên
máy tính hiện tại. Đồng thời hàm/ngắt này cũng cho biết số kí tự trong xâu ngày-tháng-năm trong thanh ghi BX.
Các lệnh sau đây sẽ in xâu ngày-tháng-năm nói trên ra màn hình: Mov Ah, X
; hàm cần gọi được đưa vào thanh ghi ah Mov Al, 1 ; gọi hàm X với Al = 1 Int Y ; gọi ngắt Y với hàm X ; Mov Cx, Bx
; đưa số kí tự của xâu ngày−tháng−nămvào Cx Mov Ah, 02
; dùng hàm 02/21h để in kí tự ra nàm hình LapIn: Mov Dl, Byte PTR ES:[DI] Int 21h INC DI ; đến kí tự tiếp theo Loop LapIn ; lOMoAR cPSD| 36066900
Ví dā 3: Hàm 39h của ngắt 21h được sử dụng để tạo thư mục con trên đĩa. Hàm này quy định:
DS:DX chứa xâu tên thư mục cần tạo, bao gồm cả đường dẫntìm đến thư mục này, xâu này kết thúc
bởi trị 0. Nếu việc tạo không thành công thì Cf = 1, khi đó thanh ghi Ax sẽ chứa mã lỗi.
Các lệnh sau đây sẽ tạo ra thư mục con BTCB trong thư mục ASSEM trên thư mục gốc ổ đĩa
D. Chư¢ng trình phải khai báo biến TenTM, chứa xâu tên thư mục cần tạo như sau: TenTM DB 8D:\ASSEM\BTCB9,0 Các lệnh: Mov Ax, Seg TenTM Mov DS, Ax Mov Dx, Offset TenTM Mov Ah, 39h Int 21h ; Jc TB_Loi
; nếu CF = 1 thì việc tạo bị lỗi
‹In ra thong bao hoan thanh> Jmp KetThuc TB_Loi:
‹In ra thong bao khong tao duoc thu muc> KetThuc: ... ;
Ví dā 4: Sau đây là chư¢ng trình dạng COM: In ra tất cả (256) các kí tự có trong bảng mã ASCII: .Model Small .Code ORG 100h Start: Jmp Main TB
DB 'Noi dung Bang ma ASCII:',0Ah,0Dh,'$' Main Proc Mov Ah, 09h Lea Dx, TB Int 21h lOMoAR cPSD| 36066900 ; Mov Cx, 256 Mov Ah, 02 Mov Dl, 0 LapIn: Int 21h ; Mov Bl, Dl Mov Dl, ' ' Int 21h Mov Dl, Bl ; INC Dl Loop LapIn ; Int 20h Main Endp End Start
Ví dā 5.1: Sau đây là chư¢ng trình dạng COM: Nhập vào một xâu kí tự bất kỳ. Sau đó in ra lại chính
xâu kí tự vừa được nhập vào nhập. Sử dụng hàm 09/21h để in ra. .Model Small .Code ORG 100h Start: JMP Main TBN
DB 'Nhap vao mot xau ki tu: $' TBX DB 0Ah,0Dh,'Xau vua nhap: $' Buff DB 100,0,100 Dup (' ') Main Proc Mov Ah, 09h lOMoAR cPSD| 36066900 Lea Dx, TBN Int 21h ; Mov Ah, 0Ah Lea Dx, Buff Int 21h ; Mov Cx, 0 Mov Cl, Buff[1] Add Dx, 2 Mov DI, Dx Add DI, Cx Mov Byte PTR [DI], 8$9 ; Mov Ah, 09h Lea Dx, TBX Int 21h ; Mov Ah, 09h Lea Dx, Buff Add Dx, 2 Int 21h ; Int 20h Main Endp End Start
Ví dā 5.2: Sau đây là chư¢ng trình dạng EXE: Nhập vào một xâu kí tự bất kỳ. Sau đó in ra lại chính
xâu kí tự vừa được nhập vào nhập. Sử dụng hàm 02/21h để in ra. .Model Small .Stack 100h lOMoAR cPSD| 36066900 .Data TBN
DB 'Nhap vao mot xau ki tu: $' TBX DB 0Ah,0Dh,'Xau vua nhap: $' Buff DB 100,0,100 Dup (' ') .Code Main Proc Mov Ax,@Data Mov DS, Ax ; Mov Ah, 09h Lea Dx, TBN Int 21h ; Mov Ah, 0Ah Lea Dx, Buff Int 21h ; Mov Cx, 0 Mov Cl, Buff[1] Add Dx, 2 Mov DI, Dx ; Mov Ah, 09h Lea Dx, TBX Int 21h ; Mov Ah, 2 Lap_In: Mov Dl, [DI] Int 21h INC DI lOMoAR cPSD| 36066900 Loop Lap_In ; Mov Ah, 4Ch Int 21h Main Endp End
Ví dā 6: Sau đây là chư¢ng trình dạng COM: Nhập vào một kí tự thường, chư¢ng trình sẽ in ra kí tự in hoa tư¢ng ứng. .Model Small .Code ORG 100h Start: Jmp Main TB1
DB 'Nhap vao mot ki tu thuong: $' TB2
DB 0Ah,0Dh,'Ki tu hoa tuong ung: $' Main Proc Mov Ah, 09h Lea Dx, TB1 Int 21h ; Mov Ah, 01 Int 21h Mov Bl, Al ; Mov Ah, 09h Lea Dx, TB2 Int 21h ; Mov Ah, 02 Mov Dl, Bl Sub Dl, 20h lOMoAR cPSD| 36066900 Int 21h ; Int 20h Main Endp End Start
Ví dā 7: Sau đây là chư¢ng trình dạng COM: Nhập vào một xâu kí tự sau đó in ra lại xâu đã nhập
theo thứ tự đảo ngược. .Model Small .Code ORG 100h Start: JMP Main TBN
DB 'Nhap vao mot xau ki tu: $' TBX DB 0Ah,0Dh,'Xau vua nhap: $' Buff DB 100,0,100 Dup (' ') Main Proc Mov Ah, 09h Lea Dx, TBN Int 21h ; Mov Ah, 0Ah Lea Dx, Buff Int 21h ; Mov Cx, 0 Mov Cl, Buff[1] ; Mov Ah, 09h Lea Dx, TBX Int 21h ; lOMoAR cPSD| 36066900 Lea Dx, Buff Add Dx, 2 Mov DI, Dx Add DI, Cx Dec DI Mov Ah, 02 Lap_In_Nguoc: Mov Dl, [DI] Int 21h DEC DI Loop Lap_In_Nguoc ; Int 20h Main Endp End Start
Ví dā 8:,Sau đây là chư¢ng trình dạng COM: Nhập vào hai số (số thứ nhất: nhỏ h¢n 5; số thứ hai:
nhỏ h¢n hoặc bằng 5), sau đó in ra tổng của hai số vừa nhập. .Model Small .Code ORG 100h Start: Jmp Main TBN1 DB
'Nhap so hang thu nhat (nho hon 5): $' TBN2 DB
0Ah,0Dh,'Nhap so hang thu hai (nho hon bang 5): $' TBX DB
0Ah,0Dh,'Tong cua hai so la: $' Main Proc Mov Ah, 09h Lea Dx, TBN1 Int 21h Mov Ah, 01 lOMoAR cPSD| 36066900 Int 21h Mov Bl, Al Sub Bl, 30h ; Mov Ah, 09h Lea Dx, TBN2 Int 21h Mov Ah, 01 Int 21h Sub Al, 30h Add Bl, Al ; Mov Ah, 09h Lea Dx, TBX Int 21h Mov Ah, 02 Mov Dl, Bl Add Dl, 30h Int 21h ; Int 20 Main Endp End Start lOMoAR cPSD| 36066900
TẬP LÞNH ASSEMBLY CŨA INTEL 8088/8086 - (Tiếp theo) 8. Lßnh so sánh: Cu´ pha´ p: Cmp
[Toa´ n haṇ g đi´ch], [Toa´ n haṇ g nguô` n]
Trong đo´ : [Toa´ n hạng đic´ h], [Toa´ n hạng nguô` n] có thể là hằng, biến, thanh ghi hay ô nhớ. [Toa´ n hạng đic´ h]
không thể là hằng số. [Toa´ n hạng đic´ h] và [Toa´ n haṇ g nguô` n] không thể đồng thời là ô nhớ.
Ta´ c duṇ g: Lệnh Cmp (Compare) được sử dụng để so sánh giá trị/nội dung của [Toa´ n haṇ g đi´ch] so với
[Toa´ n hạng nguô` n]. Tư¢ng tự như lệnh Sub, nó lấy [Toa´ n haṇ g đic´ h] trừ đi [Toa´ n hạng nguô` n] nhưng kết
quả không làm thay đổi [Toa´ n hạng đi´ch] mà chỉ làm thay đổi giá trị của một số cờ hiệu: CF, ZF, OF,...
Kết quả so sánh của lệnh Cmp là: [Toa´ n hang đi´ch] > [Toa´ n haṇ g nguô` n]; [Toa´ n haṇ g đi´ch] g[Toa´ n
haṇ g nguô` n]; [Toa´ n haṇ g đi´ch] < [Toa´ n han g nguô` n]; [Toa´ n haṇ g đi´ch] f[Toa´ n han g nguô` n]; [Toa´ n
haṇ g đi´ch] = [Toa´ n han g nguô` n]; [Toa´ n han g đi´ch] ≠ [Toa´ n haṇ g nguô` n];... mỗi kết quả sẽ tác động (0
→1, 1→0) đến một cờ tư¢ng ứng cụ thể nào đó.
Do đó, để biết được kết quả so sánh chư¢ng trình phải sử dụng các lệnh kiểm tra cờ (đó là cá lệnh
nhảy), và chúng phải được đặt ngay sau lệnh so sánh. Như vậy lệnh Cmp sẽ không có ý nghĩa khi nó đứng độc lập.
Có thể nói ngược lại, lệnh Cmp được sử dụng để cung cấp điều kiện nhảy (thay đổi giá trị các cờ)
cho các lệnh nhảy có điều kiện. Vi´ dụ 1: • Cmp Ax, Bx
; so sánh giá tị thanh ghi Ax với Bx • Cmp Ax, 20
; so sánh giá trị thanh ghi Ax với 20 • Cmp Ax, [SI]
; so sánh Ax với nội dung ô nhớ được chỉ bởi SI Ví dā 2: • Cmp Al, 8A9
; so sánh giá trị thanh ghi Al với 8A9 • Cmp Al, Var1
; so sánh giá trị thanh ghi Al với giá trị biến Var1
Tất cả cá lệnh Cmp ở trên điều không có ý nghĩa, vì nó không cho biết kết quả so sánh một cách trực
tiếp mà phải ánh thông qua các cờ.
Lệnh Cmp không thể sử dụng để so sánh hoặc kiểm tra giá trị của các cờ. 9. Các lßnh nhảy
Lßnh nhảy không điều kißn: Cu´ pha´ p: Jmp
<Vị trí đích>
Trong đo´ : có thể là nhãn của một lệnh, tên của một thủ tục hoặc có thể là một thanh ghi, một ô
nhớ (đã được định nghĩa) nào đó. cũng có thể là một biến nào đó, giá trị của nó thường là địa
chỉ của một ô nhớ trong đoạn Code. lOMoAR cPSD| 36066900
Ta´ c duṇ g: Khi gặp lệnh này chư¢ng trình chuyển điều khiển (nhảy đến) đến thực hiện lệnh sau đích> mà không phụ thuộc vào bất kỳ điều kiện nào.
C¢ chế thực hiện của lệnh Jmp là thay đổi nội dung của cặp thanh ghi con trỏ lệnh CS:IP. CS:IP mới
sẽ là địa chỉ của lệnh sau trong bộ nhớ.
Lệnh Jmp có 3 dạng: Short, Near và Far. Đối với dạng Short và Far thì chỉ có thanh ghi IP bị thay đổi
khi lệnh thực hiện, ngược lại, với dạng Far, khi lệnh thực hiện thì cả thanh ghi IP và thanh ghi đoạn
CS đều bị thay đổi. Hay nói cách khác: Đối với dạng Short và Near thì lệnh Jmp và phải
nằm trong cùng Segment nhớ, ngược lại, với dạng Far thì lệnh Jmp và có thể nằm ở các Segment nhớ khác nhau. Vi´ dụ 1: Start: Jmp Main TieuDe DB 8Khoa CNTT – DHHH9 Main Proc .................. Main Endp End Start Ví dā 2: • Jmp short Main • Jmp Ax • Jmp word PTR [BX] • Jmp dword PTR [BX] Ví dā 3: Reset DD 5BE000F0h Jmp Reset Ví dā 4: Mov Ax, 15 Mov Bx, 20 Jmp TTong Add Ax, Bx TTong: Sub Ax, Bx Mov Cx, Ax lOMoAR cPSD| 36066900
Kết thúc đoạn lệnh trên Cx = Ax = -5, vì lệnh Add
Ax, Bx không được thực hiện. Khi gặp lệnh Jmp
TTong chư¢ng trình nhảy đến thục hiện lệnh sau nhãn TTong, đó chính là lệnh Sub Ax, Bx.
Lßnh nhảy có điều kißn: Cu´ pha´ p chung:
<Vị trí đích>
Trong đo´ : : Tư¢ng tự như lệnh Jmp.
Ta´ c duṇ g: Khi gặp một lệnh nhảy có điều kiện, đầu tiên chư¢ng trình sẽ kiểm tra điều kiện nhảy của nó,
nếu thỏa mãn thì sẽ nhảy đến thực hiện lệnh ở , nếu không thì bỏ qua không thực hiện lệnh nhảy này.
Điều kiện nhảy của các lệnh nhảy này chính là sự thay đổi giá trị của các cờ hiệu, do đó để tạo điều
kiện nhảy cho một lệnh nhảy xác định thì chư¢ng trình phải làm thay đổi giá trị của cờ hiệu tư¢ng
ứng với nó. Chư¢ng trình thường dùng các lệnh địch bít, quay bít, so sánh,... để làm thay đổi giá trị
các cờ hiệu để tạo điều kiện nhảy cho các lệnh nhay. Cách đ¢n giản nhất là sử dụng lệnh Cmp ngay trước lệnh nhảy.
Sau đây là các lßnh nhảy có điều kißn vái dữ lißu có d¿u: • Lệnh JG:
Nhảy nếu [Đích] > [Nguồn] ; (SF = 0F và ZF = 0) • Lệnh JL:
Nhảy nếu [Đích] < [Nguồn] ; (SF <> 0F) • Lệnh JGE:
Nhảy nếu [Đích] g[Nguồn] ; (SF = 0F) • Lệnh JLE:
Nhảy nếu [Đích] f[Nguồn] ; (CF <> 0F và ZF = 1) • ...
Trong đó: [Đích] và [Nguồn] chính là hai toán hạng: [Toa´ n haṇ g đi´ch] và [Toa´ n han g nguô` n] trong
lệnh Cmp đứng ngay trước lệnh nhảy. Tức là, chư¢ng trình sử dụng lệnh Cmp để tạo điều kiện nhảy
cho các lệnh này. Cụ thể: lệnh nhảy có thực hiện được hay không (có chuyển điều khiển đến đích> hay không) phụ thuộc vào giá trị của [Đích] và [Nguồn] trong lệnh Cmp đứng ngay trước nó.
Với việc sử dụng lệnh Cmp để tạo điều kiện nhảy cho các lệnh nhảy thì ta không cần quan tâm đến
các cờ điều kiện nhảy của chúng.
Sau đây là các lßnh nhảy có điều kißn vái dữ lißu không d¿u: • Lệnh JA:
Nhảy nếu [Đích] > [Nguồn] ; (CF = 0 và ZF = 0) • Lệnh JB:
Nhảy nếu [Đích] < [Nguồn] ; (CF = 0) • Lệnh JNA:
Nhảy nếu [Đích] không lớn h¢n [Nguồn]; (CF =1 or ZF =1) • Lệnh JNB:
Nhảy nếu [Đích] không nhỏ h¢n [Nguồn] ; (CF = 0)
Các lệnh nhảy với dữ liệu có dấu có thể áp dụng với các dữ liệu không dấu.
Sau đây là các lßnh nhảy có điều kißn dùng chung: • Lệnh JC: Nhảy nếu cờ CF = 1 • Lệnh JNC: Nhảy nếu cờ CF = 0 • Lệnh JZ: Nhảy nếu cờ ZF = 1 lOMoAR cPSD| 36066900 • Lệnh JNZ: Nhảy nếu cờ ZF = 0 • Lệnh JE:
Nhảy nếu [Đích] = [Nguồn]; Tư¢ng tự JZ; (ZF = 1) • Lệnh JNE:
Nhảy nếu [Đích] ≠[Nguồn]; Tư¢ng tự JNZ; (ZF = 0) • ... [2 - 150]
Với các lệnh này, chư¢ng trình thường sử dụng các lệnh dịch bít hoặc lệnh quay bít để tạo điều kiện nhảy nó.
Ví dā 1a: Dãy lệnh sau đây thực hiện việc gán giá trị cho thanh ghi Cx dựa vào giá trị của thanh ghi Ax và Dx: Mov Ax, 12 Mov Dx, 25 ; Cmp Ax, Dx ; Ax ? Bx Jg Nhan1 ; nếu Ax > Dx Jle Nhan2 Nhan1: Mov Cx, Ax Jmp Tiep_Tuc Nhan2: Mov Cx, Dx Jmp Tiep_Tuc Tiep_Tuc: Mov Bx, Cx ;
Có thể thấy, ở đây không cần dùng lệnh Jle Nhan2, vì nếu Ax không lớn h¢n Dx thì chắc chẵn nó
sẽ nhỏ h¢n hoặc bằng Dx. Ngoài ra cũng không cần dùng lệnh Jmp
Tiep_Tuc sau nhãn Nhan2, vì
việc chuyển đến lệnh sau nhãn Tiep_Tuc ở đây là tất nhiên. Vì thế đoạn lệnh trên có thể được viết
rút gọn như trong Ví dā 1b sau đây.
Ví dā 1b: Dãy lệnh sau đây là trường hợp rút gọn của dãy lệnh trên: Mov Ax, 12 Mov Dx, 25 ; Cmp Ax, Dx Jg Nhan1 ; nếu Ax > Dx lOMoAR cPSD| 36066900 Mov Cx, Dx ; khi Ax fDx Jmp Tiep_Tuc Nhan1: Mov Cx, Ax ; khi Ax > Dx Tiep_Tuc: Mov Bx, Cx ;
Trong cả hai ví dụ trên: khi kết thúc, Bx = Cx = Dx = 25. Nhưng nếu cho
Ax = 120 (Ax > Bx) thì Bx = Cx = Ax = 120.
Ví dā 2: Giả sử tại địa chỉ 0A000:0100 trong bộ nhớ có chứa một mảng các số nguyên kiểu byte,
gồm 100 phần tử (100 byte).
Các lệnh sau đây tính tổng của các phần tử trong mảng này mà giá trị của nó lớn h¢n 123. Kết quả chứa ở thanh ghi Dx. Mov Ax, 0A000h Mov DS, Ax Mov DI, 0100h ; Mov Dx, 0 Mov Cx, 100 Lap_TT: Mov Al, Byte PTR DS:[DI] Cmp Al, 123 Jle Tiep_Tuc Add Dx, Al Tiep_Tuc: INC DI
; trỏ đến phần tử kế tiếp Loop Lap_TT
; lặp lại: kiển tra và tính tổng ;
Ví dā 3: Giả sử tại địa chỉ 0C000:00120 trong bộ nhớ có chứa một xâu kí tự, xâu này được kết thúc bởi giá trị 0 (số 0).
Các lệnh sau đây sẽ đếm xem xâu nói trên gồm bao nhiêu kí tự. Kết quả ghi vào ô nhớ ngay trước vùng nhớ chứa xâu này: Mov Ax, 0C000h lOMoAR cPSD| 36066900 Mov ES, Ax Mov DI, 00120h Mov SI, DI ; Mov Dx, 0 Lap_Dem: Mov Al, Byte PTR ES:[DI] Cmp Al, 0 ; so sánh Al với 0 Je KetThuc
; nếu Al = 0: đã đến cuối xâu INC Dx ; khi Al <> 0: đếm INC DI
; trỏ đến kí tự kế tiếp Jmp Lap_Dem
; lặp lại: kiển tra và đếm KetThuc: Mov Byte PTR DS:[SI - 1], Dx ;
Ví dā 4: Các lệnh sau đây in nội dung bản bản ASCII ra màn hình, nhưng không in ra các kí tự có mã 07h, 0Ah, 0Dh. Mov Cx, 256 Mov Ah, 02 Mov Dl, 0 Lap_In: Cmp Dl, 07h Je TTuc Cmp Dl, 0Ah Je TTuc Cmp Dl, 0Dh Je TTuc Int 21h TTuc: INC DL Loop Lap_In lOMoAR cPSD| 36066900 ;
Ví dā 5: Các lệnh sau đây cho phép nhập một xâu kí tự bất kỳ, dài không quá 200 kí tự, từ bàn phím
vào biến XauNhap. Sau đó copy các kí tự là chữ cái in hoa trong xâu vừa nhập vào biến XauHoa.
Trước hết chư¢ng trình phải khai báo các biến: XauNhap DB 200, 0, 200 Dup (8 9) XauHoa DB 200 Dup (8 9) Các lệnh: Mov Ax, Seg XauNhap Mov DS, XauNhap Mov Dx, Offset XauNhap Mov Ax, Seg XauHoa Mov ES, XauHoa Mov DI, Offset XauHoa ; Mov Ah, 0Ah Int 21h ; Mov Cx, 0 Mov Cl, XauNhap[1] Mov SI, Dx Add SI, 2 ; Lap_Copy: Mov Al, DS:[SI] Cmp Al, 8A9 Jl TTuc Cmp Al, 8Z9 Jg TTuc Mov ES:[DI], Al INC DI TTuc: lOMoAR cPSD| 36066900 INC SI ; Loop Lap_Copy ;
Nên nhớ, trong bảng mã ASCII các kí tự là chữ cái in hoa nằm ở những vị trí liên tiếp nhau: A, B, C,
..., Z, chúng có mã lần lượt là 65, 66, 67, ..., 90.
Ví dā 6: Giả sử tại địa chỉ 0F000:FFFE trong bộ nhớ ROM-BIOS có chứa một byte dữ liệu. Byte này
cho biết loại của máy tính đang sử dụng. Cụ thể, nếu byte này: chứa trị 0FBh: máy PC/XT; chứa trị
0FCh: máy PC/AT; chứa trị 0FFh: máy PC classic;...
Các lệnh sau đây cho biết máy tính đang sử dụng thuộc loại máy nào:
Trước hết chư¢ng trình phải khai báo các biến trả lời: TB1 DB 8Day la may PC/XT.$9 TB2 DB 8Day la may PC/AT.$9 TB3 DB 8Day la may PC classic.$9 Các lệnh: Mov Ax, 0F000h Mov ES, Ax Mov SI, 0FFFEh ; Mov Al, Byte PTR ES:[SI] Cmp Al, 0FBh Je TraLoi1 Cmp Al, 0Fch Je TraLoi2 Cmp Al, 0Ffh Je TraLoi3 ... TraLoi1: Mov Ax, Seg TB1 Mov DS, Ax Lea Dx, Offset TB1 Mov Ah, 09 Int 21h lOMoAR cPSD| 36066900 Jmp KetThuc TraLoi2: Mov Ax, Seg TB2 Mov DS, Ax Lea Dx, Offset TB2 Mov Ah, 09 Int 21h Jmp KetThuc TraLoi1: Mov Ax, Seg TB3 Mov DS, Ax Lea Dx, Offset TB3 Mov Ah, 09 Int 21h Jmp KetThuc ..... KetThuc: Mov Ah, 4Ch Int 21h ;
Có thể nói, ví dụ trên đây là một thao tác điển hình trong lập trình h¢̣p ngữ. Nó cũng cho thấy chức
năng và thế mạnh của ngôn ngữ này. Đây cũng là mục tiêu mà người lập trình h¢̣p ngữ nhắm tới.
Việc truy xuất vào các vùng nhớ dữ liệu để lấy các byte/word thông tin cấu hình hệ thống là một yêu
cầu c¢ bản với các ngôn ngữ lập trình cấp thấp, và nó được thực hiện một cách khá đ¢n giản trong
ngôn ngữ h¢̣p ngữ. Ví dụ trên đây cũng cho thấy nguyên tắc để làm việc này.
10. Các lßnh Dịch bít – Quay bít
Các lệnh dịch bít là các lệnh làm cho các bít trong một thanh ghi bị dịch về bên trái (lệnh ShR) hoặc
về bên phải (lệnh ShL) một hoặc nhiều bít. Lệnh quay bít làm cho các bít trong một thanh ghi quay
theo quay đều lần lượt được đưa qua cờ CF. Do đo, các lệnh dịch bít và quay bít thường được sử dụng
để kiểm tra giá trị bít (= 0 hay = 1) của các bít trong thanh ghi.
H¢̣p ngữ cung cấp hai dạng lệnh quay bít, quay không qua cờ CF (lệnh RcL và Rcl) và quay có qua cờ CF (lệnh ShL và ShR). lOMoAR cPSD| 36066900 Cu´ pha´ p: Shr
[Toa´ n hạng đi´ch], <n> Shl
[Toa´ n hạng đic´ h], <n>
Rcr [Toa´ n hạng đi´ch], <n> Rcl
[Toa´ n hạng đic´ h], <n>
Trong đo´ : [Toa´ n haṇ g đi´ch] là một thanh ghi 8 bít hoặc 16 bít. là số bít cần dịch, nếu = 1
thì chỉ định trực tiếp trong câu lệnh, nếu lớn h¢n 1 phải chỉ định thông qua thanh ghi CL. Ta´ c dung:
• Lệnh ShR (Shift Logical Right): Dịch chuyển các bít trong thanh ghi [Toa´ n hạng đi´ch] sang phải một hoặc
nhiều bít. Các bít được dịch lần lượt được đưa vào cờ CF, cờ CF sẽ chứa bít của lần dịch cuối cùng. Sau
khi dịch các bít bị khuyết (ở bên đối diện) sẽ được thay bằng các bít có trị 0. Tức là, với thanh ghi 8 bít thì
sau 8 lần dịch nó sẽ nhận được một dãy 8 bít = 0, tư¢ng tự với thanh ghi 16 bít thì sau 16 lần dịch nó sẽ
nhận được một dãy 16 bít = 0. Nếu thanh ghi AL = 01001001 thì sau khi bị dịch về bên trái 2 bít nó sẽ như
sau: AL = 00100100, khi đó CF = 1.
• Lệnh ShL (Shift Logical Left): Tư¢ng tự như lệnh ShR nhưng các bít được dịch về phía bên trái.
• Lệnh RCR (Rotate through Carry Right): Tư¢ng tự như lệnh ShR, nhưng bít được dịch sẽ được đặt vào lại
bít bị khuyết ở bên đối diện. Tức là, với thanh ghi 8 bít thì sau 8 lần dịch nó sẽ nhận lại dãy bít ban đầu,
tư¢ng tự với thanh ghi 16 bít thì sau 16 lần dịch nó sẽ nhận lại dãy bít ban đầu. Nếu thanh ghi AL
= 01001001 thì sau khi bị quay về bên trái 2 bít nó sẽ như sau: AL = 00100101, khi đó CF = 1.
• Lệnh RCL (Rotate through Carry Left): Tư¢ng tự như lệnh RCR nhưng các bít được quay về phía bên trái. Ví dā 1: • Shr Al, 1 • Mov Cl, 2 Shr Al, CL Shl Bl, CL Rcl AL, CL • Rcr Dl, 1
Ví dā 2: Các lệnh sau đây đếm số bít bằng 1 trong thanh ghi BX, kết quả chứa ở thanh ghi Al mà
không làm thay đổi giá trị của nó: Mov Al, 0 Mov Cx, 16 DemBit1: Rcl Bx, 1 Jnc TiepTuc lOMoAR cPSD| 36066900 Inc Al TiepTuc: Loop DemBit1 ;
Ví dā 3: Các lệnh sau đây đếm số bít giống nhau (tư¢ng ứng) giữa hai thanh ghi Ax và Bx. Kết quả
chứa trong biến Dem (Dem DB 0): Mov Dem, 0 Xor Ax, Bx Mov Cx, 16 KTra: Shl Ax, 1 Jnc Bit_0 Jmp TiepTuc Bit_0: Inc Dem TiepTuc: Loop KTra ;
Ví dā 4: Các lệnh sau đây in nội dung của thanh ghi BX ra màn hình dưới dạng sô nhị phân: Mov Cx, 16 ; lặp in đủ 16 bít Mov Ah, 02
; in ra kí tự với hàm 02/21h In_NhiPhan: Shl Bx, 1
; dịch trái để bít cần in r¢i vào cờ CF Jc In_1
; lệnh JC nhảy khi cờ CF = 1 Mov Dl, 809
; CF = 0 tức là bít cần in có trị = 0, nên in ra kí tự 809 Int 21h Jmp In_Tiep In_1: Mov Dl, 819 Int 21h In_Tiep: lOMoAR cPSD| 36066900 Loop In_NhiPhan ;
Ví dā 5: Các lệnh sau đây nhập một số nhị phân từ bàn phím đưa vào lưu trữ trong thanh ghi BX: Mov Bx, 0 Mov Cx, 0 Mov Ax, 0 Mov Ah, 1 Nhap: Int 21h Cmp Al, 0Dh
; nếu nhập Enter thì kết thúc Je KetThuc ; Cmp Al, 819 Je Them_Bit Cmp Al, 809 Je Them_Bit ; Mov Ah,09 Mov
Dx, Seg TB ; Biến TB được khai báo như sau: Mov DS, Dx ; TB
DB 8Ban phai nhap 0/1 hoac Enter$9 Mov Dx, Offset TB Int 21h Jmp Nhap Them_Bit: Sub Al, 30h
; có thẻ sử dụng lệnh And Al, 0Fh Shl Bx, 1 Or Bx, Al Inc Cx Cmp Cx, 17 Jne Nhap KetThuc: lOMoAR cPSD| 36066900 Mov 4Ch Int 21h ;
Ví dā 6: Giả sử tại địa chỉ 0B000:0010 trong bộ nhớ có chứa một byte dữ liệu, nó cho biết một số
thông tin liên quan đến cấu hình hệ thống. Byte 3 cho biết máy tính hiện tại có (byte 3 = 1) hay không
có (byte 3 = 0) cổng cắm USB.
Các lệnh sau đây cho biết máy tính hiện tại (máy thực hiện đoạn lệnh) có hay không có cổng cắm
USB. Kết quả được thông báo thông qua thanh ghi Cx: Cx = 0: không có cổng cắm USB; Cx = 0FFFFh: có cổng cắm USB. Mov Ax, 0B000h Mov DS, Ax Mov DI, 0010h ; Mov Ax, 0 Mov Al, byte PTR DS:[DI] ; Mov Cl, 4 Shr Al, Cl Jc CoUSB ; co cong USB Mov Cx, 0 ; khong co cong USB Jmp KetThuc CoUSB: Mov Cx, 0FFFFh KetThuc: ... ;
Trong thực tế, kết quả kiểm tra này thường được trả lời thông qua ngay chính cờ CF. CF = 0: không
có cổng USB, CF = 1: có cổng USB.
Chú ý 1: Có thể sử dụng lệnh dịch bít ShR/ShL để thực hiện phép chia/phép nhân giá trị của một
thanh ghi (chứa số nguyên không dấu) với một số là bội số của 2.
Ví dā: Hai lệnh sau đây sẽ dịch AL sang trái 3 bít, tức là nhân AL với 8: Mov Cl, 3 Shl Al, Cl
; Al ß AL * 8, 8 = 23. lOMoAR cPSD| 36066900
Ví dā: Hai lệnh sau đây sẽ dịch AL sang phải 3 bít, tức là chia AL với 8: Mov Cl, 3 Shr Al, Cl
; Al ß AL * 8, 8 = 23.
Chú ý 2: H¢̣p ngữ còn cung cấp các lệnh dịch chuyển số học SAL (Shift Arithmetic Left) và SAR
(Shift Arithmetic Right) . SAL tư¢ng tự hoàn toàn ShL, có thể sử dụng để thực hiện nhân 2 với các số
âm. SAR tư¢ng tự ShR nhưng bít cuối cùng của [Toa´ n hang đi´ch] không bị thay bằng bít 0 mà vẫn
giữ nguyên giá trị cũ, có thể sử dụng để thực hiện chia 2 với các có dấu.
Các lệnh dich bít, quay bít của các vi xử lý Intel 80286/80386/. .... cho phép viết số bít cần dịch, trong
trường hợp lớn h¢n một, trực tiếp trong lệnh dịch, quay mà không cần thông qua thanh ghi Cl [1 – 540]. lOMoAR cPSD| 36066900 Thanh Ghi
Thanh ghi nằm bên trong CPU tùy theo đội dài 8 hay 16 bít vàtùy theo chức năng. Khi
đó, thanh ghi được dùng để chứa dữ liệu, lưu trữ dữliệu, kết quả trung gian của máy tính
hoặc đơn vị địa chỉ bộ nhớ 8088 có 14thanh ghi được chia làm 5 nhóm
I. Nhóm thanh ghi đa dụng : (General Register)
Gồm 4 thanh ghi đa dụng : AX,BX,CX và DX (có 16 bít)
Công dụng chung của các thanh ghi này là : dùng trong các phép
toán số học, logic, chứa dữ liệu.
Một thanh ghi 16 bít có thể được xem là 2 thanh ghi 8bít và
chúng được chia như sau : Thanh ghi 16 bít 2 thanh ghi 8 bít ========================= Byte cao Byte thấp AX AH AL BX BH BL CX CH CL DX DH DL ========================== Ví dụ : AX = 0x1234 AH = 0x12 AL = 0x34
Mỗi thanh ghi còn có những công dụng riêng của nó :
a. Thanh ghi AX : (Auxliary Register)
Công dụng riêng dùng trong các phép toán số học, lưu kết
quả của các phép toán *, chia, ...
b. Thanh ghi BX : (Base Regiser)
Dùng trong phép định địa chỉ cơ sở của bộ nhớ, nó đóng vai
trò như 1 thanh ghi địa chỉ offset của bộ nhớ
c. Thanh ghi CX : (Count Regiser)
Dùng để chứa số vòng lặp trong chương trình, nó đóng vai
tròn như một biến đếm cho việc lặp vòng. Ngoài ra, thanh ghi
CL còn được dùng trong các phép dịch chuyển với số lần dịch
chuyển là nội dung của thanh ghi CL.
d. Thanh ghi DX : (Data Regiser)
Dùng để lưu trữ kết quả của phép toán * hoặc /, định địa chỉ
cổng trong các lệnh xuất nhập cổng.
II. Nhóm thanh ghi đoạn : (Segiment regiset)
Gồm 4 thanh ghi : CS, DS, ES, SS
a. Thanh ghi CS : (Code Segment)
Dùng để chứa địa chỉ Segment của đoạn mã của đoạn mã chương trình. lOMoAR cPSD| 36066900
b. Thanh ghi DS : (Data Segment)
Chứa địa chỉ Segment của đoạn dữ liệu
c. Thanh ghi ES : (Extra Segment)
Chứa địa chỉ Segment của đoạn dữ liệu bổ sung. Như vậy nếu
ta có hai đoạn dữ liệu thì một sẽ do thanh ghi DS và hai sẽ do thanh ghi ES quản lý
d. Thanh ghi SS (Stack Segment)
Dùng lưu địa chỉ Segment của đoạn Stack
Bốn thanh ghi này có thể truy xuất trên bốn đoạn khác nhau.
Như vậy một chương trình làm việc cùng một lúc tối đa là bốn đoạn
III. Nhóm thanh ghi con trỏ và chỉ mục :
a. Thanh ghi SI : (Source Index)
Dùng để trỏ đến ô nhớ trong đoạn dữ liệu định bởi thanh ghi
DS, trong xử lí chuỗi thanh ghi SI dùng để trỏ đến địa chỉ bắt đầu của chuỗi nguồn
b. Thanh ghi DI : (Distination Index)
Dùng để trỏ đến ô nhớ có địa chỉ Segment định bởi thanh ghi
ES, trong xử lí chuỗi nó dùng để trỏ đến địa chỉ của chuỗi đích
c. Thanh ghi SP : (Stack pointer)
Dùng để trỏ đến phần tử ở trên đỉnh của Stack
d. Thanh ghi BP : (Base pointer)
Dùng trong phép định địa chỉ cơ sở, trong việc truy xuất
phần tử trên Stack. Nó được dùng trong các phép gọi chương trình con
e. Thanh ghi IP : (Instruction Pointer)
Chứa đến địa chỉ ô nhớ được định bởi thanh ghi CS để chỉ
đến mã lệnh của chương trình. Khi thực thi một lệnh CPU sẽ tự
động thay đổi nội dung của thanh ghi IP để trỏ đến lệnh kế tiếp
của chương trình, thanh ghi này không bị tác động trực tiếp bởi
các lệnh. Vì vậy, nó thường không có mặt trong những lệnh của hợp ngữ.
Những cặp thanh ghi thường đi chung : DS : SI ES : DI SS : SP SS : BP CS : IP IV. Thanh ghi cờ :
Mục đích của việc sử dụng cờ là việc chỉ ra trạng thái của CPU.
Để làm được điều đó bộ vi xử lí đã dành riêng ra một thanh ghi
gọi là thanh ghi cờ. Những bit trên thanh ghi này được gọi là các
cờ . Có hai loại cờ : Cờ trạng thái, cờ điều khiển
Cờ trạng thái phản ánh kết quả của phép toán
Cờ điều khiển dùng để cho phép hay không cho phép một thao tác nào đó lOMoAR cPSD| 36066900
Chúng ta chỉ quan tâm đến nhóm cờ trạng thái gồm 6 cờ là : CF, AF, SF, OF, PF, ZF.
a. Cờ CF : (Carry Flag) " Cờ nhớ "
Cờ CF được bật lên một nếu kết quả của phép toán có mượn
hay có nhớ đối với bít cao
b. Cờ AF : (Awiliary Flag) " Cờ nhớ phụ "
Bật lên một khi có mượn hay có nhớ ở bít 3
c. Cờ SF : (Sign Flag) " Cờ dấu "
Cờ SF được bật lên một nếu như kết quả của một phép tính có
bít cao nhất bằng một (số âm)
d. Cờ OF : (Over Flag) " Cờ tràn "
Được bật lên một nếu như kết quả của phép toán có dấu bị sai Ví dụ : 01010000 = AL (dương) + 01110000 = BL (dương) 11000000
e. Cờ PF : (Parity Flag) " Cờ chẵn le "
Cờ PF được bật lên một nếu như kết quả của một phép toán có
tổng 8 bít thấp là một số chẵn f. Cờ ZF : (Zero Flag)
ZF = 1 nếu như kết quả của phép toán bằng không Ví dụ : AX = FFFFh + BX = FFFFh 1FFFEh