ĐHQG – HN CNTT Ngôn ng y ASSEMBLY
Các ngt ca h thng h tr cho lp trình ASSSEMBLY
Có 4 hàm hay dùng nht:
Hàm 1: Ch 1 ký t t bàn phím:
Mov ah, 1 ;AL cha mã ASCII ký t mã vào
Int 21h
Hàm 2: Đưa 1 ký t dng ASCII ra màn hình ti v trí con tr đang
đứng
Cách 1: Nh ngt ca BIOS
Mov al, mã ASCII ca ký t
Mov ah, oeh
Int 10h
Cách 2:
Mov dl, mã ASCII ca ký t
Mov ah, 2
Int 21h
Hàm 3: Hin 1 xâu ký t kết thúc bng du $ ra màn hình
Mov dx, offset tên biến xâu
Mov ah, 9
Int 21h
Hàm 4: Tr v DOS
Mov ah, 4ch ;[int 20h]
Int 21h
Các DIRECTIVE điu khin SEGMENT dng đơn gin: d viết, d
liên kết nhưng chưa bao hết mi tình hung v điu khin SEGMENT
.Model thuê vùng nh RAM thích hp cho chương trình
.Model kiu_tiny code+data64KB
.Model kiu_small code64KB;data64KB
.Model kiu_compact code64KB;data64KB
.Model kiu_medium code64KB;data64KB
.Model kiu_large code64KB;data64KB song khi khai báo1
array không 64KB
.Model kiu_large code64KB;data64KB song khi khai báo1
array không >64KB
.Stack Độ ln (Byte) Xác lp độ ln stack cho chương trình
.Data Xác lp vùng nh cho d liu ca chương trình khai báo
biến nm segment này
.Data Khai báo biến (có 3 loi biến)
Vi các loi biến s thì kiu db có độ dài 1 byte
dw có độ dài 2 byte
dd có độ dài 4 byte
dp/df có độ dài 6 byte
dq có độ dài 8 byte
dt có độ dài 10 byte
Vi các loi biến xâu có các cách khai báo như sau:
tên_biến_xâu db ‘các ký t
tên_biến_xâu db độ_ln dup(‘1 ký t’)
tên_biến_xâu db độ_ln dup(?)
Vi các loi biến trường s (array) có các cách khai báo như sau:
tên_biến_trường kiu_thành_phn (các s cách nhau bi du ,)
tên_biến_trường kiu_thành_phn độ_ln dup(giá tr 1 s)
tên_biến_trường kiu_thành_phn độ_ln dup(?)
.Code Xác lp vùng nh truy xut ngu nhiên dùng cho phn mã máy
.Code
nhãn_chương_trình:
mov ax, @data
mov ds, ax
...
thân chương trình
...
mov ah, 4ch
int 21h
[các chương trình con]
end nhãn_chương_trình
Các DIRECTIVE điu khin SEGMENT dng chun: _SEGMENT;
_GROUP; _ASSUME
_SEGMENT Xác lp các segment cho chương trình
tên_segment SEGMENT align combine use ‘class’
{thân segment}
tên_segment ENDS
trong đó:
tên_segment là 1 identifier (không cha du cách, du \ ; : ...)
align là cách xác lp khong cách gia segment đang khai báo vi
segment trước nó
align
byte khong cách 1 byte
word khong cách 2 byte
paka khong cách 16 byte
page khong cách 256 byte
combine có hai chc năng:
+cho phép đặt segment vào 1 địa ch mong mun (theo yêu cu) ca
b nh RAM
tên_segment SEGMENT at địa_ch_dng_vt_lý
{thân}
tên_segment ENDS
+cho chương trình đa tp: cách gp các segment có cùng tên nm
các tp khác nhau khi liên kết. Ví d: Tp 1 có DATA SEGMENT; Tp 2
có DATA SEGMENT.khác
_COMMON tc là độ dài ca segment sau liên kết bng độ dài
segment ln nht
_PUBLIC tc là độ dài ca segment sau liên kết bng tng độ dài c
2 segment
_PRIVATE tc là độ dài ca segment sau liên kết bng độ dài ca
chính nó (không quan h vi nhau, đây là chế độ default)
_STACK ging như _PUBLIC
_CLASS sp xếp các segment li gn nhau sau khi liên kết
(Sau khi liên kết thì nhng segment nào cùng mt nhóm thì gn nhau)
_GROUP gp các segment có cùng kiu li vi nhau cho d dàng qui
chiếu
tên_ nhóm GROUP tên_các_segment (cách nhau bi du , )
_ASSUME cho biết tên segment thuc loi segment nào
_ASSUME tên_thanh_ghi SEG : tên_seg
Cu trúc mt chương trình Assembly thường thy: Khai báo
MACRO, STRUCT, UNION, RECORD, SEGMENT
Dng đơn gin
.Model kiu
.Stack độ ln
[.Data
khai báo biến]
.Code
nhãn_chương_trình:
mov ax, @data
mov ds, ax
...
thân chương trình
...
mov ah, 4ch
int 21h
[các chương trình con]
END nhãn_chương_trình
Dng chun
_Stack segment
db độ_dài dup(?)
_Stack ends
Data segment
khai báo biến
Data ends
Code segment
Assume cs:code ds:data ss:stack nhãn_chương_trình:
mov ax, data
1
ĐHQG – HN CNTT Ngôn ng y ASSEMBLY
mov ds, ax
...
thân chương trình
...
mov ah, 4ch
int 21h
[các chương trình con]
ENDS
END nhãn_chương_trình
*Chương trình con:
1, Cơ chế khi 1 chương trình con b gi:
Bước 1: Tham s thc đưa vào STACK
Bước 2: Địa ch ca lnh tiếp theo được đưa vào STACK
Bước 3: H điu hành qun lý địa ch đầu ca chương trình con do vy
H điu hành s đưa địa ch đó vào CS:IP r nhánh vào chương trình
con
Bước 4: Thc hin thân chương trình con cho đến khi gp lnh RET thì
vào STACK ly địa ch lnh tiếp theo (đã ct Bước 2) và cho vào
CS:IP, ri quay v chương trình đã gi nó
Bước 5: Tiếp tc thc hin chương trình đang đợi
2, Cú pháp ca chương trình con Assembly:
Tên_chương_trình_con PROC [NEAR/FAR]
Bo v các thanh ghi s b phá v thân chương trình
Thân chương trình con
Hi phc các thanh ghi mà chương trình con phá v
RET
Tên_chương_trình_con ENDP
a, Vn đề NEAR – FAR:
NEAR chương trình con cùng nm trên 1 segment vi chương trình gi
nó địa ch lnh tiếp theo ct vào STACK (Bước 2) ch cn 2 byte
offset
FAR chương trình con nm khác segment vi chương trình con gi nó
địa ch lnh tiếp theo ct vào STACK (Bước 2) cn đến 4 byte offset
* Vi khai báo segment dng đơn gin thì directive model s xác định
hin chương trình con NEAR hay FAR
. Model tiny chương trình con là NEAR
. Model small chương trình con là NEAR
. Model compact chương trình con là NEAR
. Model medium chương trình con là FAR
. Model large chương trình con là FAR
. Model huge chương trình con là FAR
* Vi khai báo dng chun thì mc định là NEAR
b, Chương trình con Assembly không có đối s cơ chế kích hot
chương trình con Assembly không có Bước 1
3, Chuyn giao tham s:
Cách 1: Nh thanh ghi
Chương_trình_chính Chương_trình_con
...... ......
mov ax, 10 mov bx, ax
call Chương_trình_con ......
......
(khi đó bx = 10)
Cách 2: Nh biến nh
Chương_trình_chính Chương_trình_con
...... ......
mov value, 20 mov bx, value
call Chương_trình_con ......
......
(khi đó bx = 20)
Cách 3: Thông qua STACK (dùng khi liên kết vi ngôn ng lp trình
bc cao)
4, Bo v thanh ghi:
Khi thân chương trình con s dng các lnh làm giá tr thanh ghi thay
đổi như and, xor, ... thì phi bo v các thanh ghi đó trước khi dùng
Cách 1: Dùng các lnh POP, PUSH
Cách 2: Chuyn vào biến hoc thanh ghi khác sau đó hi phc
Tp include
Tp INCLUDE cho phép người lp trình viết gn chương trình
- Thiết lp 1 tp ngoài (gi là tp INCLUDE) mà trong tp này cha khi
lnh Assembly .ASM
- Sau đó dùng lnh INCLUDE để chèn khi lnh đó vào tp chương
trình đang viết. Cú pháp:
..............
INCULDE X:\đường dn\tp INCLUDE
..............
- Cơ chế ca chương trình dch Assembly khi gp INCLUDE: chương
trình dch ca Tubor Assember khi gp INCLUDE thì thc hin các
bước:
* M tp INCLUDE theo sau Directive Include
* Sao chép và chèn toàn b khi lnh Assembly có trong tp INCLUDE
vào v trí Directive Include đứng
* Tiến hành dch khi lnh đó
- Cách tìm tp INCLUDE để chèn
* Nếu tp đứng sau Directive Include có tên đĩa, đường dn thì chương
trình dch tìm đến, nếu không có thì đó là thư mc hin hành, còn nếu
không có na thì sai
* Nếu sai thì ch có cách sa li chương trình ngun. Khi dch chương
trình dùng thêm tham s TASM -i A:\...\*.ASM
- Hn chế ca INCLUDE là không được phép có nhãn nhy trong khi
lnh ca tp INCLUDE khi gi nó 2 ln
macro và các vn đề liên quan
1, Các lnh lp khi lnh khi dch chương trình:
REPT dch khi lnh theo s ln đi sau REPT
REPT n
Khi_lnh
ENDM
IRP dch khi lnh theo s lượng danh sách
IRP tên_đối <danh sách>
Khi_lnh
ENDM
- Các Directive điu khin điu kin khi dch chương trình
Chc năng: Dch khi lnh khi điu kin đúng TRUE
IF <điu kin> IF <điu kin>
Khi_lnh Khi_lnh_1
ENDIF ELSE Khi_lnh_2
ENDIF
Lnh IFE ging như lnh IF nhưng ngược điu kin
Chc năng: Dch khi lnh khi biu thc <điu kin> = 0
IFB <biu thc>
Khi_lnh
ENDIF
Lnh IFNB ging như lnh IFB nhưng ngưc điu kin
Chc năng: Dch khi lnh khi <biu thc 1> = <biu thc 2>
IFIDN <biu thc 1>, <biu thc 2>
Khi_lnh
ENDIF
Lnh IFDIF ging như lnh IFIDN nhưng ngược điu kin
Chc năng: Dch khi lnh khi nhãn theo sau đó đã được khai báo
IFDEF nhãn
Khi_lnh
ENDIF
Lnh IFNDEF ging như lnh IFDEF nhưng ngược điu kin
*Macro là 1 cơ chế giúp người lp trình to 1 lnh mi trên cơ s tp
lnh sn có ca Assembly
- Trước khi được dùng thì phi khai báo
Cú pháp:
Tên_Macro MACRO[đối]
Bo v các thanh ghi s b phá v thân chương trình
Thân MACRO
Hi phc các thanh ghi mà chương trình con phá v
2
ĐHQG – HN CNTT Ngôn ng y ASSEMBLY
ENDM
- Cách dùng lnh mi đã xác lp MACRO: Sau khi macro đã được xác
lp thì tên ca Macro tr thành mt lnh mi ca ASM
- Cách dùng: Gi tên macro và thay vì đối s là tham s thc
Chương trình Macro hin xâu ra màn hình:
HIENSTRING MACRO XAU
Push ax, bx
Lea dx, XAU
Mov ah, 9
Int 21h
Pop dx, ax
ENDM
Chương trình Macro xóa màn hình:
CLRSCR MACRO
Push ax
Mov ah, 0fh
Int 10h
Mov ah, 0
Int 10h
Pop ax
ENDM
tính ưu vit ca macro
a, So sánh Macro vi chương trình con:
Tc độ: Khi chy chương trình thì Macro nhanh hơn vì không phi dùng
lnh CALL và RET
Tiết kim b nh: Chương trình con chiếm ít b nh hơn
Macro cho phép chuyn giao tham s thông qua đối và cho phép s
dng các Directive lp khidch chương trình. Các Directive điu khin
điu kin khi dch chương trình.
b, So sánh Macro vi tp INCLUDE:
Cơ chế: Ging nhau khi dch
Tc độ: Khi chy chương trình thì Macro nhanh hơn vì không phi m
đóng tp
Macro cho phép có nhãn nhy trong lnh ca Macro nh Directive
Local. Trong thân Macro cho phép có các Macro khác
Chương trình dng *.com và *.exe
Chương trình .EXE có 3 segment {code, data và stack}. Có th không
cùng nm trên 1 segment
Chương trình .COM có 3 segment {code, data và stack} nm cùng trên
1 segment. Khi chy chương trình .COM cn 256 byte đầu ca segment
đó để nhy. Do vy, lnh đầu ca chương trình .COM s đặt offset
người lp trình phi khai báo cho h điu hành Directive ORG
Khai báo chương trình dng .COM có 1 segment và là Code Segment
biến cũng được khai báo Code Segment
.Code
Nhãn_chương trình:
Jmp nhãn_khác
[nếu có khai báo biến]
Khai báo biến
Nhãn_khác:
......
mov ah, 4ch
int 21h
Dng thường thy ca chương trình .COM thun túy [Khai báo
MACRO, STACK, UNION, RECORD]
Dng đơn gin Dng chun
.Model tiny .Code segment
(hoc small) ORG 100h
.Code assume cs:code,ds:code,ss:code
ORG 100h Nhãn_chương_trình:
Nhãn_chương_trình: Jmp nhãn_khác
Jmp nhãn_khác Khai báo biến
Khai báo biến Nhãn_khác:
Nhãn_khác: ........
......... int 20h
int 20h [các chương trình con]
[các chương trình con] code ends
END nhãn_chương_trình END nhãn_chương_trình
Directive public
Chc năng: Báo cho chương trình dch biết nhng nhãn Model này
cho phép các tp khác cũng có th dùng
Cú pháp: Public tên_nhãn
Khai báo kiu nhãn
.Vi hng: Public tên_hng = hng
Public Port
Port = 038h
.Vi biến: Public tên_biến
Khai báo biến
.Vi tên chương trình con:
Public tên_chương_trình_con
tên_chương_trình_con PROC
...........
RET
tên_chương_trình_con ENDP
Directive public
Chc năng: Báo cho chương trình dch biết Module này xin phép được
dùng các nhãn mà các Module khác đã cho phép
Cú pháp: Extrn tên_nhãn: kiu
.Nhãn là tên hng: Extrn tên_nhãn: ABS
Extrn Post kiu
.Nhãn là biến nh: Extrn x: word (hoc byte hoc dword)
.Nhãn là chương trình con:
Extrn tên_chương_trình_con:PROC
Directive global
Chc năng: Không phi chương trình nào cũng có Directive này, nó
thay cho Public và Extrn
Cú pháp: GLOBAL tên_nhãn: kiu
Khai báo biến
Liên kết C vi Assembly
INLINE ASM là chèn khi lnh ASM vào chương trình được viết bng C
Cú pháp: khi lnh C
ASM lnh ASM
...........
ASM lnh ASM
khi lnh C
Dch và liên kết
TCC -ms :IC\TC\INCLUDE -LC
Hn chế: Các lnh ASM được chèn thì dch nh bi chương trình dch
ca TC. Do đó 1 s lnh khó ca ASM dch không đúng. Không cho
phép có các nhãn nhy trong ASM khi lnh chèn vào yếu (vì không
có LOOP, nhy có và không có điu kin)
Viết tách bit tp cho c và tp cho asm
Phi gii quyết 3 vn đề:
1, Vn đề đa tp: (khai báo Public) vi Module ca C, bt k khai báo
nào ca C đều là khai báo Public. Khai báo External ngôn ng C phi
xin phép dùng các nhãn đã cho phép t tp ngoài. Vi Module ASM
ging như đa tp thun túy
2, Vn đề du (-) (underscore) người viết chương trình ASM phi thêm
du – vào trước trên các nhãn dùng chung vi C và thêm mi nơi mà
tên đó xut hin
3, Vn đề giá tr quay v ca hàm ASM: qui định vi giá tr 2 byte thì
trước khi RET ax = bao nhiêu thì tên hàm ASM có giá tr by nhiêu. Vi
giá tr 4 byte trước khi RET dx:ax có giá tr bao nhiêu thì hàm ASM có
giá tr by nhiêu
cơ chế khi mt ngt và chương trình con được kích hot
Chương trình con bình thường:
CALL
Bước 1: Tham s thc STACK
Bước 2: Địa ch lnh tiếp theo STACK
3
ĐHQG – HN CNTT Ngôn ng y ASSEMBLY
Bước 3: H điu hành qun lý địa ch đầu ca chương trình con H
điu hành đưa địa ch đầu ca chương trình con cs:ip r nhánh vào
chương trình con
Bước 4: Thc hin các lnh ca chương trình con RET thì vào
STACK ly địa ch lnh tiếp theo (đã ct bước 2) cs:ip và tr v
chương trình đang d
Bước 5: Tiếp tc chương trình đang d
Chương trình con phc v ngt:
Int n (tác động linh kin)
Bước 1: Flag STACK;Tham s thc STACK
Bước 2: Địa ch lnh tiếp theo STACK
Bước 3: H điu hành qun lý địa ch đầu ca chương trình con phc
v ngt. Song địa ch đầu ca chương trình con phc v ngt nm trong
ô nh tương ng ca bng vectơ ngt máy tính vào vectơ ngt ly địa
ch đầu ca chương trình con phc v ngt đưa vào cs:ip r nhánh
vào chương trình con phc v ngt
Bước 4: Thc hin các lnh ca chương trình con cho đến khi gp IRET
thì vào STACK ly địa ch lnh tiếp theo (đã ct bước 2) cs:ip và tr
v chương trình đang d
Bước 5: Trước khi tiếp tc chương trình đang d thì vào STACK ly c
đã ct
Bng vectơ ngt: là vùng nh RAM cha địa ch đầu ca chương trình
con phc v ngt. Máy tính có 256 ngt có 256 chương trình con
phc v ngt. Địa ch ô bng n * 4 (mi địa ch 4 byte)
Các bước để xác lp chương trình con phc v ngt:
Bước 1: Viết chương trình con theo yêu cu ca thut toán
Cú pháp: Tên_chtrình_con_pv_ngt PROC [NEAR/FAR]
Bo v các thanh ghi
Thân chương trình
Phc hi các thanh ghi
IRET
Tên_chtrình_con_pv_ngt ENDP
Bước 2: Sau khi viết xong chương trình con phc v ngt thì tìm địa ch
đầu ca chương trình này đưa vào v trí tương ng ca bng vectơ ngt
Khi động máy tính vi h điu hành DOS
Vi máy tính ca INTEL, khi bt máy thì thanh ghi CS = F000h; IP =
FFF0h và s nhy vào thc hin lnh ô nh F000:FFF0. Lnh này là
lnh jmp và nó nhy đến chương trình khi động máy tính đều nm
ROM-BIOS
ROM-BIOS là vùng nh ch đọc, không ghi được và cha 2 loi chương
trình khi động máy và chương trình phc v ngt ca BIOS
Các chương trình khi động máy tính:
Test CPU: kim tra các thanh ghi. Tng vào các giá tr 00, 55 và FF vào
các thanh ghi và kim tra li có bng 00, 55 và FF không. Đồng thi
kim tra mt s lnh ASM nếu có li thì hin FATA ERROR.
Kim tra ROM-BIOS: trong ROM có 1 byte CHECKSUM (tng các byte
ca ROM) khi khi động thì có 1 chương trình cng các byte ca ROM
li lưu kết qu vào 1 byte và so sánh byte này vi CHECKSUM. Nếu
bng nhau thì tc là ROM tt, ngược li là ti.
Kim tra mt s linh kin quan trng ca mainboard
8259 là chip phc v ngt
8250 UART (COM)
8253 Timer
8237 DMA
Kim tra RAM (ging ht CPU và thanh ghi) tc là cho toàn b các byte
ca RAM các giá tr 00, 55, FF liu RAM có chp nhn các giá tr này
không
Xác lp bng vec tơ ngt ca BIOS
Đưa mi địa ch đầu ca các chương trình con phc v ngt vào bng
vec tơ ngt
Đưa các thông s máy tính đang dùng vào vùng nh biến BIOS
Kim tra liu có ROM m rng: vi màn hình và đĩa thì v phn cng
cho các Card điu khin không ging nhau không th viết 1 driver
chung và np vào ROM-BIOS chun tha hip ca các hãng: Ai sn
xut phn cng thì viết driver cho nó và np vào ROM và ROM đó s
được đặt trên Card đó
Int 19h: Lôi boot sector xung RAM và trao quyn cho chương trình
nm trong boot sector
Trong boot sector là sector 512 byte cha tham s đĩa và cha chương
trình mi
Chương trình mi lôi 2 tp n xung RAM (h điu hành DOS)
Kim tra thiết b ngoi vi
Lôi COMMAND.COM vào vùng nh RAM – là chương trình dch các
lnh ca DOS Mã máy
CONFIG.SYS
AUTOEXEC.BAT
C:\>
Bài tp 1:
Hin 1 xâu ký t “Hello TASM!” ra màn hình
Cách 1:
.MODEL small
.STACK 100h
.DATA
Message db ‘Hello TASM!$’
.CODE
ProgramStart:
Mov AX,@DATA
Mov DS,AX
Mov DX,OFFSET Message
Mov AH,9
Int 21h
Mov AH,4Ch
Int 21h
END ProgramStart
Cách 2:
_STACK segment stack ‘stack’
db 100h dup(?)
_STACK ends
DATA segment
Message db ‘Hello TASM!’,0
DATA ends
CODE segment
Assume CS:CODE, DS:DATA, SS:_STACK
ProgramStart:
Mov AX,DATA
Mov DS,AX
Mov SL,OFFSET Message
cld
L1:
Lodsb
And AL,AL
Jz Stop
Mov AH,0eh
4
ĐHQG – HN CNTT Ngôn ng y ASSEMBLY
Int 10h
Jmp L1
Stop:
Mov AH,1
Int 21h
Mov AH,4Ch
Int 21h
CODE ends
END ProgramStart
Bài tp 2:
So sánh 2 s nguyên nhp t bàn phím xem s nào bé hơn
Cách 1:
include C:\HTDAT\INCLUDE\lib1.asm
_stack segment stack 'stack'
db 100h dup(?)
_stack ends
data segment
m1 db 10,13,'Vao so thu nhat:$'
m2 db 10,13,'Vao so thu hai:$'
m3 db 10,13,'So be la:$'
m4 db 10,13,'Co tiep tuc khong (c/k)?:$'
data ends
code segment
assume cs:code,ds:data,ss:_stack
ps:
mov ax,data
mov ds,ax
clrscr
hienstring m1
call Vao_so_N
mov bx,ax
hienstring m2
call Vao_so_N
cmp ax,bx
jl L1
xchg ax,bx
L1:
hienstring m3
call Hien_so_N
hienstring m4
mov ah,1
int 21h
cmp al,'c'
je ps
mov ah,4ch
int 21h
include C:\HTDAT\INCLUDE\lib2.asm
code ends
end ps
So sánh 2 s nhp vào t bàn phím xem s nào bé hơn
Cách 2:
hien_string MACRO xau
push ax dx
mov dx,offset xau
mov ah,9
int 21h
pop dx ax
ENDM
;---------------------------------
.model small
.stack 100h
.data
sohex dw ?
temp dw ?
m1 db 0ah,0dh,'Vao so thu1: $'
m2 db 0ah,0dh,'Vao so thu2: $'
m3 db 0ah,0dh,'So be la: $'
.code
ps:
mov ax,@data
mov ds,ax
hien_string m1
call VAOSO
mov ax,sohex
mov temp,ax
hien_string m2
call VAOSO
mov bx,sohex
hien_string m3
cmp ax,bx
jl L1
xchg ax,bx
L1:
call HIENSO
mov ah,1
int 21h
mov ah,4ch
int 21h
;--------------------------------------------
VAOSO PROC
push ax bx cx dx
mov bx,10
xor cx,cx
mov sohex,cx
VS1:
mov ah,1 ; Ham nhan 1 ki tu va --->al
int 21h
cmp al,0dh
je VS2
sub al,30h
mov cl,al
mov ax,sohex
mul bx
add ax,cx
mov sohex,ax
jmp VS1
VS2:
pop dx cx bx ax
ret
VAOSO ENDP
;----------------------------------------------
HIENSO PROC
push ax bx cx dx
mov bx,10
xor cx,cx
HS1:
xor dx,dx
div bx ; tuc lay dx:ax chia cho bx kq thuong-->ax va du-->dx
add dx,30h ; de dua ra dang ASCCI
push dx ; tong 1 chu vao stack
inc cx
cmp ax,0
jnz HS1
HS2:
pop ax
mov ah,0eh
int 10h
loop HS2
pop dx cx bx ax
ret
5