Tải bản đầy đủ (.pdf) (29 trang)

Bài tập lập trình hợp ngữ asembly

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.32 MB, 29 trang )

Bài thực hành số 1
Nhập môn
Mục đích
 Làm quen với ngôn ngữ lập trình Assembly
 Biết cách viết, dịch, chạy và chẩn lỗi (debug) một vài chương trình đơn giản
Tóm tắt lý thuyết
Hợp ngữ (assembler) là ngôn ngữ bậc thấp, giúp cho người lập trình không phải ghi nhớ mã máy
(opcode) mà sử dụng các từ ngữ gợi nhớ (pseudo-code) gần với ngôn ngữ tự nhiên để miêu tả công
việc cần thực hiện. Tuy vậy, assembler rất gần với ngôn ngữ máy, đòi hỏi người lập trình phải hiểu
biết tương đối đầy đủ về cấu trúc phần cứng máy tính.
Với mỗi kiểu kiến trúc của bộ vi xử lý, có một bộ lệnh riêng, do đó, có một ngôn ngữ assembler
riêng cho nó. Ở đây, chúng ta nghiên cứu assembler cho các bộ vi xử lý Intel thuộc họ x86. Các
chương trình sẽ được viết cho chế độ thực (real mode) trong DOS và được biên dịch bằng Turbo
Assembler.

Cấu trúc thông thường của một chương trình hợp ngũ

.model <Khai báo kiểu chương trình>
.stack <Khai báo kích thước ngăn xếp>
.data
<Khai báo dữ liệu>
.code
<Các lệnh>
end

Ví dụ: Chương trình sau in ra màn hình dòng chữ “Hello !”

.model small
.stack 100h
.data
s DB “Hello !$” ; khai báo xâu kí tự cần in


.code
mov AX,@data ; lấy địa chỉ data segment ghi vào DS
mov DS,AX ; Vì model small, đây cũng là địa chỉ
; segment của xâu s

; xuất chuỗi
mov DX, OFFSET s ; lấy địa chỉ offset ghi vào DX
mov AH , 9
int 21h ; gọi hàm 9, ngắt 21h để in

mov AH, 4Ch ; Thoát khỏi chương trình
int 21h
end

Lưu ý:
- Mọi chương trình đều phải có đoạn code thoát khỏi chương trình, nếu không chương
trình sẽ không dừng khi hết chương trình của mình.

Khai báo biến trong hợp ngữ

Cú pháp:
<tên biến> D<Kiểu DL> <giá trị khởi tạo>
hoặc
<tên biến> D<Kiểu DL> <số phần tử> dup(<giá trị khởi tạo>)

Các kiểu dữ liệu: B (1 byte), W (2 bytes), D (4 bytes)
Nếu không khởi tạo, dùng dấu hỏi “?”

Ví dụ:


Khai báo trong C
Khai báo trong hợp ngữ
char ch;
ch DB ?
char ch = „a‟;
ch DB „a‟
char ch = 5;
ch DB 5
char s[]=”\nhello world!”
s DB 10,13,”hello world!$”
int i=100;
i DW 100
long l;
l DD ?
char a[] = {1,2,3};
a DB 1,2,3
char a[100];
a DB 100 dup(?)
char a[100][50];
a DB 100 dup(50 dup(?))


Dịch, liên kết, chạy và chẩn lỗi chương trình từ dấu nhắc DOS

Cần có các file: tasm.exe (dịch), tlink.exe (liên kết), td.exe (chẩn lỗi). Các bước như sau:
 B1. Thiết lập đường dẫn
path = %path%;<đường dẫn đến thư mục chứa các file kể trên>

 B2. Biên dịch từ file .ASM sang file .OBJ
Tasm <tên file chương trình>.ASM


 B3. Biên dịch từ file .OBJ sang file .EXE
Tlink <tên file>.OBJ

 B4: chạy chương trình:
<tên file>.EXE
 B5: chẩn lỗi (nếu cần thiết)
Td <tên file>.EXE

Để tự động hóa, ta có thể tạo file .BAT chứa các lệnh trên.

Ví dụ:

Tạo file RunASM.bat trong cùng thư mục với tập tin .ASM với nội dung như sau :

tasm %1
tlink %1
%1

(%1 là lấy tham số thứ nhất trong command line)
Sau đó để biên dịch, liên kết và thực thi chương trình hello.ASM ta chỉ cần gõ :

RunASM hello


Công cụ EditPlus

Đây là công cụ soạn thảo văn bản tiện dụng, cho phép tự động đổi màu chữ theo cú pháp.
Ngoài ra còn có thể thiết đặt phím tắt để gọi các tiện ích khác. Để dùng cho soạn thảo chương
trình assembler, cần copy file định nghĩa cú pháp vào thư mục cài đặt và đăng kí sử dụng nó cho

những file có tên mở rộng “.asm”.

 B0. Cấu hình Edit Plus: xem trong file hướng dẫn
 B1. Biên dịch file .ASM : nhấn Ctrl + 1 sẽ biên dịch file đang soạn thảo thành .OBJ
 B2. Liên kết : nhấn Ctrl + 2 sẽ biên dịch file .OBJ thành .EXE
 B3. Chạy chương trình : nhấn Ctrl + 3 sẽ chạy chương trình .EXE
 B4. Chẩn lỗi chương trình : nhấn Ctrl + 4 sẽ debug chương trình .EXE

Lưu ý:
- Để tránh phiền phức khi làm việc với Turbo Assembler, tránh đặt tên thư mục có chứa
khoảng trắng.
- Trước khi nhấn Ctrl + 1 lần đầu tiên, nhớ lưu chương trình với tên cần thiết.

Một số lệnh cơ bản

MOV des,src : chép dữ liệu từ src sang des
INC des : tăng des một đơn vị
DEC des : giảm des một đơn vị
ADD des,src : des = des + src
SUB des,src : des = des – src
INT num : gọi ngắt


Tài liệu tham khảo
1. Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 1, ĐHKHTN, 2002
2. Randal Hyde, The art of assembly language programming – Chapter 1.
3. Norton Guide
4. Dan Rollins, TechHelp v.6.0

Bài tập


Bài 1. Viết CT nhập vào 1 ký tự, xuất ra ký tự đó
Ví dụ:
Moi ban nhap 1 ky tu: b
Ky tu vừa nhập: b

Bài 2. Viết chương trình xuất ra màn hình một số dòng.
Ví dụ:
De chay duoc 1 CT hop ngu ban can thuc hien cac buoc sau:
Dich file ASM thanh file OBJ
Lien ket file OBJ thanh file EXE
Chay file EXE

Bài 3. Viết CT nhập vào 1 ký tự, xuất ra ký tự liền trước và liền sau.
Ví dụ:
Moi ban nhap 1 ky tu: b
Ky tu lien truoc: a
Ky tu lien sau: c

Bài 4. Viết CT nhập vào 1 ký tự thường. In ra ký tự Hoa
Ví dụ:
Moi ban nhap 1 ky tu: b
Ky tu Hoa: B

Bài 5. Viết CT nhập vào 1 ký tự hoa. In ra ký tự thường
Ví dụ:
Moi ban nhap 1 ky tu: B
Ky tu thường: b

Bài 6. Viết chương trình nhập vào 2 số nguyên dương x1, x2 (1  x2 < x1 < 9). Xuất ra kết quả các

phép tính: x1-1, x1 +2, x1+x2, x1-x2
Ví dụ:
x1 = 5
x2 = 3
x1 – 1 = 4
x1 + 1 = 6
x1 + x2 = 8
x1 – x2 = 7

Mở rộng
1. Tự tìm hiểu xem hàm nào trong ngắt 21h dùng để nhập một xâu kí tự ? Ngoài ngắt 21h, còn
ngắt nào có thể dùng để nhập xuất từ bàn phím ? (dùng NortonGuide hoặc TechHelp).
2. Viết chương trình nhập tên và in ra màn hình câu “Hello ” + tên đã nhập.
3. Tìm hiểu xem tại sao không có lệnh MOV x1, x2 (x1,x2 là hai biến trong bộ nhớ)
4. Hai lệnh “INC AX” và “ADD AX, 1” khác nhau chỗ nào ?

Hướng dẫn
Bài 1. Để nhập 1 một ký tự sử dụng hàm 1 của ngắt 21h, để xuất, sử dụng hàm 2.
Ví dụ:
mov AH,1
int 21h ; kết quả trong AL

mov DL,AL ; kí tự cần xuất trong DL
mov AH,2
int 21h
Bài 2. Cặp kí tự xuống dòng là 10,13. Có thể khai báo nhiều xâu kí tự hoặc chung một xâu.
Ví dụ:
Msg3 DB 10,13,9,“1. Dich file ASM thanh file OBJ.$”
Msg4 DB 10,13,9,“2. Lien ket file OBJ thanh file EXE.$”


Hoặc

Msg34 DB 10,13,9,“1. Dich file ASM thanh file OBJ.”
DB 10,13,9,“2. Lien ket file OBJ thanh file EXE.$”


Bài 3, 4. Kí tự hoa và kí tự thường của cùng một chữ cái tiếng Anh cách nhau 20h. Do đó, để
chuyển đổi chữ hoa thành chữ thường và ngược lại, chỉ cần dùng lệnh ADD, SUB.

Bài 5. Để chuyển đổi các kí tự „0‟ – „9‟ thành số 0 – 9 chỉ cần thực hiện phép trừ đi 48 (mã của „0‟).
Sau khi thực hiện phép tính, chuyển đổi thành kí tự và in ra màn hình (có thể dùng biểu diễn Hex).

Bài thực hành số 2
Lệnh so sánh – Lệnh nhảy – Lệnh lặp
Mục đích
 Hiểu cách so sánh hai số trong hợp ngữ
 Hiểu cách thay đổi thứ tự thực hiện các lệnh
 Biết cách sử dụng các lệnh so sánh, nhảy và lặp
Tóm tắt lý thuyết

Lệnh so sánh

Trong hợp ngữ, muốn so sánh hai số, ta phải thực hiện một phép toán số học hoặc logic trên hai
số đó và căn cứ vào các bit trong thanh ghi cờ rồi đưa ra kết luận. Để làm việc này, có thể dùng lệnh
CMP và TEST.
Bản chất của lệnh CMP Des,Src là lệnh SUB Des,Src (thực hiện phép tính Des – Src) nhưng
kết quả của phép tính không được lưu vào Des như trong lệnh SUB.

Ví dụ: so sánh hai số nguyên dương
MOV AH,1

MOV AL,2
CMP AH,AL
Sau khi thực hiện hai lệnh trên, cờ Carry (CF) bật, báo hiệu rằng AH < AL

Bản chất của lệnh TEST Des,Src là lệnh AND Des,Src (thực hiện phép tính Des AND Src)
nhưng kết quả của phép tính không được lưu vào Des như trong lệnh AND.

Ví dụ: kiểm tra hai bit cuối cùng của AL
TEST AL,3 ; 3h = 11b
Nếu cờ Zero (ZF) bật, có nghĩa là cả hai bit 0 và 1 của AL đều bằng 0.

Lệnh nhảy

Thông thường, khi một lệnh (instruction) được thực hiện, giá trị của thanh ghi IP (instruction
pointer) được tự động cập nhật để trỏ đến lệnh kế tiếp. Ngoài ra, nội dung của thanh ghi IP chỉ có
thể bị thay đổi thông qua một số lệnh đặc biệt. Đó là: các lệnh nhảy (J*), lệnh lặp (LOOP*), lệnh gọi
hàm (call, ret), lệnh gọi ngắt (int, iret). Các lệnh này được xếp vào nhóm “Lệnh điều khiển luồng”
(Program flow control instructions). Trong bài thực hành này, chúng ta sẽ học cách sử dụng các lệnh
nhảy và các lệnh lặp.

 Lệnh nhảy không điều kiện

JMP <target>

Có các trường hợp sau:
 JMP SHORT <tên nhãn> (short jump). Khi đó trong mã lệnh lưu 1 byte khoảng
cách (offset) giữa vị trí hiện tại và vị trí cần nhảy đến. Kiểu này chỉ nhảy trong phạm
vi từ –128 đến +127 byte so với vị trí hiện tại.
Ví dụ: JMP SHORT Calculate


 JMP <tên nhãn> (near jump). Khi đó trong mã lệnh lưu 2 byte khoảng cách
(offset) giữa vị trí hiện tại và vị trí cần nhảy đến. Kiểu này nhảy tùy ý trong phạm vi
segment.
Ví dụ: JMP Calculate

 JMP FAR PTR <tên nhãn> (far jump). Khi đó trong mã lệnh lưu offset và
segment của vị trí cần nhảy đến. Kiểu này nhảy đến bất kì chỗ nào.
Ví dụ: JMP FAR PTR Calculate
 JMP <con trỏ 2 byte> (near indirect jump). Khi đó trong mã lệnh lưu địa
chỉ offset của một ô nhớ. Khi thực hiện, IP sẽ được gán bằng giá trị lưu tại địa chỉ
này. Có thể kết hợp dùng với định vị chỉ số.

Ví dụ:
myPointer DW Prepare, Calculate, Check, Output

MOV bx,2 ; chỉ số trong mảng con trỏ
SHL bx,1 ; nhân đôi
JMP myPointer[bx]

Prepare: ; công việc 0

Calculate: ; công việc 1

Check: ; công việc 2 – nơi cần nhảy đến

Output: ; công việc 3


 JMP <con trỏ 4 byte> (far indirect jump). Tương tự trường hợp trên, nhưng
con trỏ gồm cả segment và offset. Chỉ khác ở khai báo con trỏ


Ví dụ:
myPointer DD Prepare, Calculate, Check, Output

MOV bx,1 ; chỉ số trong mảng con trỏ
MOV cl,2
SHL bx,cl ; nhân 4
JMP myPointer[bx]

Prepare: ; công việc 0

Calculate: ; công việc 1 – nơi cần nhảy đến


 JMP <thanh ghi 2 byte> (indirect jump via regs). Nhảy đến địa chỉ lưu
trong thanh ghi AX.

Ví dụ:
MOV ax, offset Calculate

JMP ax ; (IP ← AX)







 Lệnh nhảy có điều kiện


J <Label>

Các lệnh nhảy có điều kiện bắt đầu bằng chữ J sau đó là các chữ cái biểu thị điều kiện (ví dụ
JGE ah,5: Jump if Greater than or Equal, nhảy nếu AH lớn hơn hay bằng 5), tiếp sau là một tên
nhãn. Tùy thuộc vào trạng thái các cờ hiệu mà bộ vi xử lý có thực hiện việc nhảy đến nhãn hay
không.

Đối với bộ vi xử lý 80286 trở xuống, lệnh nhảy có điều kiện có độ dài 2 byte, byte đầu tiên chứa
mã lệnh, byte thứ hai chứa khoảng cách tương đối từ lệnh đến nhãn, vì vậy <Label> trong lệnh nhảy
có điều kiện phải nằm trong khoảng từ -128 đến 127 so với vị trí lệnh nhảy. Muốn nhảy xa hơn ta
phải dùng kết hợp lệnh nhảy không điều kiện JMP
Từ 80386 trở lên, bộ lệnh được bổ sung, cho phép sử dụng lệnh nhảy có điều kiện có độ dài 4
byte, do đó <Label> có quyền nằm tùy ý trong cùng phạm vi segment.

Khi sử dụng lệnh nhảy có điều kiện sau khi thực hiện phép so sánh, phải đặc biệt lưu ý toán
hạng trong phép so sánh là số có dấu (signed) hay không có dấu (unsigned) để lựa chọn lệnh cho
phù hợp.
Ví dụ:
MOV AH,AL ; AL hiện bằng 128
CMP AH,1
JGE Greater ; AH > 1 nhưng không nhảy ????
. . .
Greater:

Một số lệnh nhảy có điều kiện thường dùng (tham khảo thêm trong SGK trang 81):
 JE, JZ (nhảy nếu bằng).
 JA (nhảy nếu lớn hơn, không dấu), JG (nhảy nếu lớn hơn, có dấu), JB (nhảy nếu nhỏ
hơn, không dấu), JL (nhảy nếu nhỏ hơn, có dấu).
 JAE (nhảy nếu lớn hơn hay bằng, không dấu), JGE (nhảy nếu lớn hơn hay bằng, có
dấu), JBE (nhảy nếu nhỏ hơn hay bằng, không dấu), JLE (nhảy nếu nhỏ hơn hay

bằng, có dấu).
 JNE, JNZ (nhảy nếu không bằng).

Ví dụ: nếu AL là số nguyên không dấu thì đoạn chương trình ở trên phải sửa lại như sau:
MOV AH,AL
CMP AH,1
JAE Greater
. . .
Greater:

Lệnh lặp

Bằng cách dùng các lệnh nhảy có thể tạo ra vòng lặp. Tuy nhiên, để viết chương trình tiện lợi và
ngắn gọn, có thể dùng thêm các lệnh lặp như LOOP, LOOPZ,…
Lệnh LOOP <Label> tự động giảm CX một đơn vị, sau đó kiểm tra xem CX có bằng 0, nếu
không bằng thì nhảy đến nhãn <Label>
Lệnh LOOPZ <Label> tự động giảm CX một đơn vị, sau đó kiểm tra xem CX có bằng 0
hoặc cờ ZF có bật không, nếu cả hai điều này không xảy ra thì nhảy đến nhãn <Label>

Ví dụ: Nhập mảng A gồm 10 ký tự

MOV SI, 0 ; chỉ số mảng
MOV CX, 10 ; số lần lặp
LAP:
;nhập ký tự
MOV AH, 1
INT 21H
MOV A[SI], AL
INC SI


; xuất ký tự
MOV AH, 2
INT 21H

LOOP LAP

Tài liệu tham khảo
1. Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 4, ĐHKHTN, 2002
2. Randal Hyde, The art of assembly language programming – Chapter 6, 10.
3. Dan Rollins, TechHelp v.6.0
4. NortonGuide
Bài tập
Bài 1. Viết chương trình cho nhập 1 ký tự từ màn hình và xuất câu thông báo chào buổi sáng, buổi
trưa hay buổi chiều tương ứng với ký tự nhậpvào là 'S', 's', 'T', 't', 'C', 'c'.

Bài 2. Nhập 2 số nguyên dương thuộc N,M thuộc [0 9], nhập 1 ký tự Char. Xuất ra màn hình ma
trận gồm N dòng và M cột gồm ký tự Char.
Ví dụ: N=3, M=4, C='*'
 * * * *
* * * *
* * * *

Bài 3. Nhập 2 số nguyên dương A, B. Tính A/B, A*B (không dùng lệnh DIV, MUL)
Ví dụ: A=18, B=3
Tính A/B: 18 - 3 - 3 - 3 - 3 - 3 - 3 = 0, vậy A/B = 6 (tổng số lần A trừ B cho đến khi A = 0).
Tính A*B = 18 + 18 + 18 = 54

Bài 4. Tìm USCLN của 2 số nguyên dương N, M nhập từ bàn phím. Kiểm tra N,M có là hai số
nguyên tố cùng nhau không?
Ví dụ: N = 15, M = 6 => USCLN(15, 6) = 3

Ví dụ: N = 3, M = 5 => USCLN(3, 5) = 1 => 3, 5 là 2 số nguyên tố cùng nhau.

Bài 5. Dùng lệnh lặp, viết chương trình nhập vào 1 chuỗi ký tự. Sau khi nhập xong đếm xem chuỗi
có bao nhiêu ký tự. Xuất số ký tự có trong chuỗi.
Ví dụ: S = "Hello world !" ==> Số kí tự trong chuỗi là 13.

Bài 6. Nhập vào 2 chuỗi số, đổi 2 chuỗi thành số, sau đó cộng hai số, đổi ra chuỗi và xuất chuỗi
tổng.
Ví dụ: S1 = "123" => N1 = 123
S2 = "456" => N2 = 456
N = N1 + N2 = 123 + 456 = 579 => S = "579" (xuất S ra màn hình)

Bài 7. Viết chương trình cho phép nhập vào một chuỗi S.
Đổi tất cả ký tự thường thành ký tự hoa.
Đổi tất cả ký tự hoa thành ký tự thường.

Bài 8. Nhập và xuất mảng 1 chiều. Tìm phần tử max, min, tính tổng các phần tử trong mảng.
Ví dụ: N = 5
A[N] = {3,1,2,7,4}
=> max = 7, min = 1, tổng = 17.

Bài 9. Cài đặt thuật toán Bubble Sort dùng ASM.

Thuật toán Bubble Sort theo ngôn ngữ C như sau:
for (int i = 0; i< N-1; i++)
for(int j=N-1;j > i; j )
if(a[j] < a[j-1])
Hoan_Vi (a[j], a[j-1]);

Bài 10. Nhập và xuất mảng A hai chiều.

a. Tính tổng các phần tử trên đường chéo chính, đường chéo phụ.
b. Đếm số phần tử 0 và phần tử khác 0 trong mảng.
c. Tìm phần tử max của mỗi dòng, mỗi cột. Tính tổng của mỗi dòng, mỗi cột.
d. Nhập 1 mảng hai chiều B, tạo một mảng hai chiều C có các phần tử trên dòng chẵn bằng
với các phần tử trên dòng chẵn của A, các phần tử trên dòng lẻ bằng các phần tử trên dòng lẻ của B.

Mở rộng
1. Trong bài tập 5, làm sao để đếm số từ có trong chuỗi kí tự?
2. Trong bài tập 10, làm sao để thể hiện một menu cho phép người dùng chọn trong các kí tự từ
„a‟ đến „d‟ sau đó thực hiện công việc ứng với chữ cái đó.
Hướng dẫn
Bài 1. Xem ví dụ:

.MODEL SMALL
.STACK 100H
.DATA
CBS DB "CHAO BUOI SANG$"
CBT DB "CHAO BUOI TRUA$"
CBC DB "CHAO BUOI CHIEU$"
.CODE
MOV AX, @DATA
MOV DS, AX

;nhập 1 ký tự bất kỳ
MOV AH, 1
INT 21H

CMP AL, 'S'
JE CHAO_BUOI_SANG


CMP AL, 's'
JE CHAO_BUOI_SANG

CMP AL, 'T'
JE CHAO_BUOI_TRUA

CMP AL, 't'
JE CHAO_BUOI_TRUA

CMP AL, 'C'
JE CHAO_BUOI_CHIEU

CMP AL, 'c'
JE CHAO_BUOI_CHIEU

CHAO_BUOI_SANG:
LEA DX, CBS
MOV AH,9
INT 21H
JMP THOAT

CHAO_BUOI_TRUA:
LEA DX, CBT
MOV AH,9
INT 21H
JMP THOAT

CHAO_BUOI_CHIEU:
LEA DX, CBC
MOV AH,9

INT 21H
JMP THOAT

THOAT:
MOV AH, 4CH
INT 21H

END

Bài 3. Để nhập một số nguyên, có thể làm như sau: đầu tiên nhập xâu kí tự chứa các số từ 0 đến 9,
sau đó đổi từng kí tự ra số và nhân với các lũy thừa tương ứng của 10 và cộng lại.
Bài 9. Xem ví dụ sau: Lặp gồm 2 vòng lặp (xếp mảng A có N phần tử tăng dần)

MOV N, 10 ;giả sử mảng A gồm N ký tự, trong ví dụ này N=10

MOV CX, N
DEC CX
MOV SI, 0

FOR_I:
PUSH CX
MOV CX, N
MOV DI, 0
MOV DL, A[SI]

FOR_J:

CMP DL, A[DI]
JB LAP
MOV BL, A[DI]

MOV A[DI], DL
MOV A[SI], BL
MOV DL, A[SI]

LAP:
INC DI
LOOP FOR_J

INC SI
POP CX
LOOP FOR_I

Bài thực hành số 3
Ngăn xếp – Thủ tục – Macro
Mục đích
 Hiểu được cơ chế hoạt động của ngăn xếp, quá trình gọi một thủ tục.
 Biết cách sử dụng ngăn xếp, khai báo và gọi thủ tục.
 Biết cách tạo và sử dụng macro.
Tóm tắt lý thuyết

Ngăn xếp
1. Một số lưu ý:
 Ngăn xếp (Stack) là vùng nhớ đặc biệt được truy cập theo cơ chế “vào trước ra sau”
(LIFO – Last In First Out), nghĩa là dữ liệu nào đưa vào sau sẽ được lấy ra trước.
 Ngăn xếp gồm nhiều phần tử, mỗi phần tử là một từ (2 bytes).
 Vị trí của ngăn xếp trong bộ nhớ được xác định bởi cặp thanh ghi SS:SP (SS chứa địa
chỉ đoạn, SP chứa địa chỉ ô của đỉnh ngăn xếp). Khi chưa sử dụng, ngăn xếp rỗng, vị
trí được xác định bởi SP lúc đó là đáy ngăn xếp.

2. Khai báo:

.STACK <kích thước của ngăn xếp>

Ví dụ: khai báo một vùng ngăn xếp có kích thước 256 bytes:
.STACK 100h

3. Các thao tác:
 Đưa trị vào (đỉnh) ngăn xếp:
PUSH <nguồn> ; đưa nguồn (thanh ghi hay từ nhớ
; 16 bit) vào đỉnh ngăn xếp
PUSHW <hằng> ; đưa trực tiếp một hằng16 bit vào
; đỉnh ngăn xếp
PUSHF ; đưa nội dung thanh ghi cờ vào đỉnh ; ngăn xếp
 Lấy trị (ở đỉnh) ra khỏi ngăn xếp:
POP <đích> ; lấy giá trị (2 bytes) ở đỉnh ngăn xếp
; đưa vào đích (thanh ghi (trừ thanh
; ghi IP) hay từ nhớ 16 bit)
POPF ; lấy giá trị (2 bytes) ở đỉnh ngăn xếp
; đưa vào thanh ghi cờ

Chú ý : Các lệnh PUSH, PUSHF, POP và POPF không ảnh hưởng tới các cờ.

Ví dụ: Chương trình xuất chuỗi ngược dùng stack:

.model small
.stack 100h


.data
msg1 DB 'Nhap vao 1 chuoi: $'
msg2 DB 10,13,'Chuoi nghich

dao la: $'
.code
mov ax,@data
mov ds,ax

mov ah,9
lea dx,msg1
int 21h

mov cx,0
nhap:
mov ah,1
int 21h
cmp al,13
je thongbaoxuat
xor ah,ah
push ax
inc cx
jmp nhap
thongbaoxuat:
mov ah,9
lea dx,msg2
int 21h
xuat:
pop ax
mov dl,al
mov ah,2
int 21h
loop xuat


mov ah,4ch
int 21h
END
1. Khai báo










2. Nhập lần lượt a,b,c đưa vào ngăn xếp:
Nhập ký tự „a‟:






00
61

Nhập ký tự „b‟:





00
62
00
61

Nhập ký tự „c‟:


00
63
00
62
00
61

3. Xuất các giá trị trong ngăn xếp
Xuất ký tự „c‟:


00
63
00
62
00
61

Xuất ký tự „b‟:





00
62
00
61

Xuất ký tự „a‟:






00
61








000h

0FCh


0FCh



SS:SP 


0FCh


0FCh


SS:SP 

000h

0FCh


0FCh


SS:SP 

000h
100h


000h

0FCh



0FCh


100h


SS:SP 


0FCh


0FCh


SS:SP 

000h
100h



0FCh


0FCh


SS:SP 


000h
100h



0FCh


0FCh


SS:SP 

000h
100h


100h


100h


Thủ tục

1. Khai báo:
<Tên thủ tục> PROC <Kiểu>;kiểu là NEAR(mặc định) hay FAR
; thân thủ tục
……………

RET
<Tên thủ tục> ENDP
Thủ tục thường được viết ở cuối chương trình.
2. Gọi thủ tục:
CALL <Tên thủ tục>
CALL <Địa chỉ> ; địa chỉ là thanh ghi hoặc vùng nhớ chứa địa chỉ
; thủ tục
3. Hoạt động của lời gọi thủ tục:
Khi thực hiện lời gọi thủ tục (CALL) thì:
 Địa chỉ ô của lệnh kế lệnh CALL (*) sẽ được cất vào ngăn xếp
 Địa chỉ ô của lệnh đầu tiên trong thủ tục được đưa vào IP
Khi thực hiện lệnh RET để quay về trình gọi thì:
 Địa chỉ trong ngăn xếp được lấy ra và được vào IP.
Do đó, nếu trong thủ tục có thao tác với ngăn xếp thì trong thủ tục, trước khi thao tác với
ngăn xếp ta nên lưu lại địa chỉ (*) ở trên (chính là giá trị hiện thời trong ngăn xếp) để
quay trở về trình gọi. Xem mô tả trong ví dụ sau.

Ví dụ: Nhập xuất chuỗi kí tự


.model small
.stack 100h
.code
CALL Nhap
CALL Xuat

mov ah,4ch
int 21h
;
Nhap PROC

pop bx
mov ah,2
mov dl,‟?‟
int 21h
xor cx,cx
nhap:
mov ah,1
int 21h
cmp al,13
je ketthucnhap
push ax
inc cx
jmp nhap
ketthucnhap:
push bx
RET
Nhap ENDP
;
Xuat PROC
pop bx
mov ah,2
mov dl,13
int 21h
mov dl,10
int 21h
jcxz ketthucxuat
xuat:
pop dx
int 21h
loop xuat

ketthucxuat:
push bx
RET
Xuat ENDP
END
1. Khai báo









2. Gọi thủ tục Nhap






CALL Xuat

IP = địa chỉ ô lệnh “pop bx”
3. Lưu lại địa chỉ quay về










BX = địa chỉ lệnh “CALL Xuat”
4. Nhập ký tự a,b:




00
62
00
61

5. Trả lại địa chỉ quay về
BX = địa chỉ lệnh “CALL Xuat”



CALL Xuat
00
62
00
61

6. Kết thúc thủ tục Nhập:




00
62
00
61

IP = địa chỉ ô lệnh “CALL Xuat”

Lời gọi thủ tục xuất (CALL Xuat) cũng
hoạt động tương tự như trên.







000h

0FCh


0FCh


100h


SS:SP 



0FCh


0FCh


SS:SP 

000h
100h


000h

0FCh


0FCh


100h


SS:SP 


0FCh



0FCh


SS:SP 

000h
100h


000h

0FCh


0FCh


100h


SS:SP 

000h

0FCh


100h



0FCh


SS:SP 

Macro

1. Một số lưu ý:
 Khi chúng ta có nhiều đoạn code giống nhau, chúng ta có thể sử dụng macro để thay
thế, giống như chúng ta dùng define ở trong C.
 Bản chất là thay thế lời gọi macro bằng các lệnh trong thân macro.
 Các macro nên phục hồi những thanh ghi mà nó sử dụng trừ những thanh ghi chứa
kết quả.
2. Khai báo:
<tên macro> MACRO <các đối số>
; thân macro
……………
ENDM

3. Hai cách sử dụng macro
 Tạo macro trực tiếp trong chươnng trình:
 Các macro thường được khai báo ở đầu chương trình trước phần .code.
 Ví dụ: Xuất một chuỗi ra màn hình sử dụng macro

.model small
.stack 100h
.data
chuoi1 db “hello”,10,13,‟$‟
chuoi2 db “bye”,10,13,‟$‟


@xuatchuoi macro chuoi
lea dx,chuoi
mov ah,9
int 21h
endm

.code

@xuatchuoi chuoi1
@xuatchuoi chuoi2

end

 Xây dựng thư viện các macro:
 Tạo 1 thư viện (tập tin) chứa các macro
 include vào chương trình (thường trước phần .code) bằng lệnh include
 Ví dụ: Xuất một chuỗi ra màn hình sử dụng thư viện macro

THUVIEN.INC
@xuatchuoi macro chuoi
lea dx,chuoi
mov ah,9
int 21h
endm







TestMacro.asm
.model small
.stack 100h
.data
chuoi1 db “hello”,10,13,‟$‟
chuoi2 db “bye”,10,13,‟$‟

INCLUDE THUVIEN.INC

.code

@xuatchuoi chuoi1
@xuatchuoi chuoi2

end

4. Các thành phần cục bộ của macro:
 Trong macro, ta cũng có thể khai báo các biến, nhãn cục bộ để tránh gây ra lỗi khi
gọi macro nhiều lần.
 Cú pháp :
LOCAL <danh sách các nhãn, các biến cục bộ>
 Ví dụ: Xuất một chuỗi hằng ra màn hình sử dụng macro với biến cục bộ

.model small
.stack 100h

@xuatchuoi macro chuoi
LOCAL chuoicucbo, nhancucbo
.data
chuoicucbo db chuoi,‟$‟

.code
lea dx,chuoicucbo
mov ah,9
int 21h
endm

.code

nhancucbo:

@xuatchuoi <“hello”,10,13>
@xuatchuoi ”bye”

end

Lưu ý: nếu cần truyền chuỗi phức tạp thì ta cần sử dụng <…> để báo cho trình biên dịch biết đây
là một đối số.





Tài liệu tham khảo
1. Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 6, ĐHKHTN, 2002
2. Randal Hyde, The art of assembly language programming – Chapter 11,12.
3. Norton Guide
4. Dan Rollins, TechHelp v.6.0

Bài tập


Bài 1: Viết chương trình kiểm tra một biểu thức đại số có chứa các dấu ngoặc (như (), [] và {}) là
hợp lệ hay không hợp lệ .
Ví dụ:
(a + [b – { c * ( d – e ) } ] + f)
là hợp lệ nhưng
(a + [b – { c * ( d – e )] } + f)
là không hợp lệ.

Bài 2: Tính giá trị biểu thức đã nhập ở bài tập 2 theo thứ tự từ trái sang phải.

Bài 3: Viết lại các bài tập tuần trước dưới dạng các thủ tục

Bài 4: Xây dựng một thư viện các macro

Mở rộng
1. Có những cách nào để truyền tham số cho thủ tục ? để nhận kết quả trả về ?
2. Thử viết một thủ tục đệ quy.
3. Tìm hiểu cách phân chia chương trình thành nhiều file và cách biên dịch, liên kểt chúng.
Hướng dẫn
Bài 1. dùng ngăn xếp để PUSH các dấu ngoặc trái ( „(„, ‟{„, „[„ ) vào ngăn xếp. Nếu gặp dấu ngoặc
phải ( „)‟, „}‟, „]‟ ) thì POP từ stack ra. Nếu không POP được, hoặc POP ra không đúng loại với dấu
ngoặc phải -> không hợp lệ . Ngược lại là biểu thức hợp lệ.

Bài thực hành số 4
Làm việc với số nguyên
Mục đích
 Biết sử dụng các phép toán logic, số học
 Biết cách đổi giữa các cơ số nhị phân, thập phân và thập lục phân
Tóm tắt lý thuyết


Phép toán trên bit

1. NOT : lệnh này đổi tác tố đích thành số bù. Không có cờ nào bị ảnh hưởng
2. AND (OR hoặc XOR) : AND (OR, XOR) Đích, nguồn
Tất cả các cờ đều bị ảnh hưởng
Chú ý : AND dùng để xóa các bit. OR dùng để bật các bit. XOR dùng để đảo bit.
3. Các lệnh dịch bit SHL và SHR : dịch các bit của toán hạng đích sang trái (hoặc phải) một
hay nhiều bit.
SHL (SHR) Đích, 1 hoặc SHL (SHR) Đích, CL
CL là số lần dịch bit.Việc dịch bit trái (phải) tương ứng với phép nhân (chia) cho
lũy thừa 2.
Chú ý : Hiện tượng tràn số có thể xảy ra và cờ CF chứa bit cuối cùng bị dịch ra
khỏi toán hạng.Để dịch bit với các số âm ta nên dùng SAL hoặc SAR tương ứng.
4. Các lệnh quay ROL và ROR : dịch các bit của toán hạng đích sang trái (phải)
một hay nhiều bit theo vòng tròn.
ROL (ROR) Đích, 1 hoặc ROL (ROR) Đích, CL
CL là số lần quay bit, cờ CF sẽ chứa giá trị bit bị dịch ra khỏi toán hạng.
Chú ý : Để dịch bit qua cờ nhớ ta dùng RCL hoặc RCR tương ứng.
Ví dụ : Sử dụng lệnh ROL để đếm số bit 1 trong thanh ghi BX
XOR AX,AX
MOV CX,16
TOP :
ROL BX, 1
JNC NEXT ; kiểm tra có phải là bit 0 không
INC AX ; nếu không phải thì tăng số bit 1
NEXT:
LOOP TOP ; lặp cho đến khi làm xong

Lệnh số học


1. Cộng ADD, ADC : ADD (ADC) đích , nguồn
Ví dụ : ADD AL , 10H -> AL = AL + 10H
2. Trừ SUB, SBB : SUB (SBB) đích , nguồn
Ví dụ : SUB BL, 10H -> BL = BL – 10H
Chú ý : Các phép toán cộng trừ trực tiếp giữa các ô nhớ là không hợp lệ. Ngoài ra
ta cũng có thể sử dụng INC hoặc DEC để cộng hoặc trừ 1 đơn vị vào nội dung
một ô nhớ hoặc một thanh ghi.
3. Nhân MUL, IMUL: MUL (IMUL) nguồn
Lệnh MUL thực hiện phép nhân không dấu, còn IMUL là lệnh nhân có dấu. Nếu nguồn là
byte (8 bit) thì kết quả chứa trong AX và AX = AL * nguồn. Nếu nguồn là word (16 bit) thì
kết quả chứa trong DX:AX và DX:AX = AX * nguồn. Nếu nguồn là double (32 bit) thì kết
quà chứa trong EDX:EAX và EDX:EAX = EAX * nguồn.
4. Chia DIV, IDIV : DIV (IDIV) số chia
Lệnh DIV thực hiện chia không dấu, còn IDIV là lệnh chia có dấu. Nếu số chia là byte (8
bit) thì số bị chia là AX và kết quả gồm: phần dư = AH, phần thương = AL. Nếu số chia là word (16
bit) thì số bị chia là DX:AX và kết quả gồm phần dư = DX, phần thương = AX. Nếu số chia là
double thì sô bị chia là EDX:EAX và kết quả gồm phần dư = EDX, phần thương = EAX.
Chú ý : phải xoá giá trị DX hoặc EDX trước khi nhân, hoặc chia.

Tài liệu tham khảo
1. Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 7, ĐHKHTN, 2002
2. Randal Hyde, The art of assembly language programming – Chapter 9.
3. Norton Guide
4. Dan Rollins, TechHelp v.6.0
Bài tập

1. Viết chương trình (VCT) đổi một số dạng thập phân sang thập lục phân.
Ví dụ: Nhập một số hệ 10 : 26
Dạng thập lục phân: 1A
2. VCT nhập một số hệ thập phân rồi xuất ra biểu diễn dạng nhị phân của nó.

Ví dụ: Nhập số hệ 10: 26
Dạng nhị phân: 11010
3. VCT đổi một số dạng thập lục phân sang sang thập phân.
Ví dụ: Nhập số hệ thập lục phân: 1a (hoặc 1A)
Dạng thập phân của nó là: 26
4. VCT đổi một số dạng thập lục phân sang nhị phân
Ví dụ: Nhập số hệ thập lục phân: 1a (hoặc 1A)
Dạng biểu diễn nhị phân là : 00011010
5. VCT đổi một số dạng nhị phân sang thập phân
Ví dụ: Nhập một số nhị phân: 11010
Dạng thập phân là: 26
6. VCT đổi một số dạng nhị phân sang thập lục phân
Ví dụ: Nhập một số nhị phân: 11010
Dạng thập lục phân là: 1A
7. VCT “echo” với yêu cầu: nhập vào số nguyên dương n và một kí tự bất kì, sau đó trên màn hình
xuất hiện n lần kí tự đó.
Ví dụ: Nhập một kí tự: k Nhập số lần n : 5  Kết quả : kkkkk.
8. VCT nhập vào hai số nguyên dương. Tính tổng, hiệu, tích, thương (phép div) và phần dư khi
chia 2 số nguyên (phép mod)
Ví dụ: Nhập số thứ nhất : 14 Nhập số thứ hai : 16
Tổng hai số là : 30 Hiệu: -2 Tích: 224 Thương: 0 Phần dư: 14
Mở rộng
1. Tìm hiểu về BCD. Viết chương trình nhập 2 số nguyên ở hệ 10, chuyển sang BCD, tính tổng,
hiệu và in kết quả ở hệ 10.
2. Liệu có thể viết chương trình tính được 20!, 30!, kết quả in ra ở dạng hex ? dạng cơ số 10 ?


Bài thực hành số 5
Làm việc với xâu kí tự
Mục đích

 Biết sử dụng các phép toán trên chuỗi
 Biết làm một số thao tác với xâu kí tự (tìm kiếm, đếm từ, chuyển hoa / thường …. )
Tóm tắt lý thuyết

 Cờ hướng DF (Direction Flag) : xác định hướng xử lí chuỗi. Khi DF = 0 (dùng lệnh
CLD) chuỗi được xử lí tăng dần, ngược lại DF = 1 (lệnh STD) chuỗi được xử lí giảm
dần.
 Con trỏ chuỗi: DS:SI – địa chỉ nguồn và ES:DI – địa chỉ đích
 Các lệnh trên chuỗi :

1. MOVSB (MOVSW) : chuyển nội dung của byte (word) được định bởi DS:SI đến
byte (word) được chỉ bởi ES: DI. Sau đó SI và DI tự động tăng lên 1 (hoặc 2) nếu
cờ DF = 0 hay giảm 1 (hoặc 2) nếu DF = 1
Ví dụ: giả sử cần chép nội dung chuỗi thứ nhất : ‘HELLO’ vào chuỗi
thứ hai theo thứ tự ngược lại ta làm như sau :

.DATA
STR1 DB ‘HELLO’
STR2 DB 5 DUP(‘?’)
.CODE
MOV AX, @DATA
MOV DS, AX
MOV ES, AX
LEA SI, STR1+4 ; cuối STR1
LEA DI, STR2 ; đầu STR2
STD ; định hướng xử lí giảm
MOV CX, 5
move :
MOVSB
ADD DI,2 ; + 2 do DI bị giảm

; 1 sau lệnh MOVSB
LOOP move

2. STOSB (STOSW): chuyển nội dung của thanh ghi AL (AX) đến byte
(word) được định bởi ES:DI. Sau đó DI tự động tăng lên 1 (hoặc 2) nếu
cờ DF = 0 hay giảm 1 (hoặc 2) nếu DF = 1.

Ví dụ: Đọc và lưu một chuỗi kí tự bằng chức năng AH = 1, ngắt 21H

NhapChuoi PROC
;Vào: DI = chứa offset của chuỗi
;Ra: DI = nội dung chuỗi vừa nhập
; BX = kích thước chuỗi

CLD ; đặt cờ DF theo hướng tăng
XOR BX, BX ; gán BX = 0
MOV AH, 1
INT 21H
while1 :
CMP AL, 13 ; nếu gõ ENTER
JE end_while1 ; kết thúc nhập
CMP AL, 8 ; nếu gõ BS
JNE else1 ;không phải lưu chuỗi
DEC DI ;ngược lại lùi 1 kí tự
DEC BX ;giảm kích thước chuỗi
JMP read ; đọc kí tự khác
else1:
STOSB
INC BX
read:

INT 21H
JMP while1
end_while1: ; thoát khỏi vòng lặp

4. LODSB (LODSW) : chuyển nội dung của byte (word) được định bởi
DS:SI vào AL (hoặc AX) sau đó tăng (hoặc giảm) SI 1 (hoặc 2) đơn vị.
5. SCASB (SCASW): tìm nội dung chứa trong AL (hoặc AX) có trong chuỗi
định bởi ES:DI hay không. Nếu tìm thấy thì cờ ZF sẽ được bật. Sau mỗi
lần thực hiện con trỏ DI sẽ tăng hoặc giảm 1 (hoặc 2) đơn vị.
6. CMPSB (CMPSW) : so sánh byte tại DS:SI và byte tại ES:DI, sau đó tăng
(hoặc giảm) SI và DI 1 (hoặc 2) đơn vị.
Bài tập

1. VCT nhập một chuỗi kí tự và in ra chuỗi theo thứ tự ngược lại. In chiều dài chuỗi.
Ví dụ : Nhập chuỗi : abcd Chuỗi kết quả: dcba Chiều dài chuỗi: 4
2. VCT nhập họ tên .Sau đó biến tất cả thành chữ hoa rồi in ra. Biến tất cả thành chữ thường rồi in
ra.
Ví dụ: Nhập vào chuỗi : Thanh cHi khanG Chuỗi Hoa : THANH CHI KHANG
Chuỗi kết quả thường: thanh chi khang
3. Nhập một chuỗi kí tự tính tần số xuất hiện của các nguyên âm.
Ví dụ : Nhập chuỗi : Thanh Chi Khang Số lần xuất hiện của các nguyên âm là: 3
4. VCT nhập hai chuỗi, liệt kê các kí tự có mặt trong hai chuỗi.
Ví dụ: Nhập chuỗi: computer và chuỗi : informatic
Các kí tự có mặt trong hai chuỗi : o, m, t, r

5. Nhập vào hai chuỗi kí tự, so sánh hai chuỗi (= > < ).
Ví dụ: Chuỗi thứ nhất: forn Chuỗi thứ hai : form
Kết quả : Chuỗi thứ nhất > chuỗi thứ hai.
6. Nhập vào hai chuỗi kí tự, kiểm tra chuỗi thứ nhất là chuỗi con chuỗi tthứ hai không, không phân
biệt hoa thường.

Ví dụ: Chuỗi thứ nhất : form Chuỗi thứ hai: inFoRMatic
Kết quả : Chuỗi thứ nhất là con chuỗi thư hai



Hướng dẫn thực hành môn Hợp Ngữ File
Bài thực hành số 6

CÁC THAO TÁC TRÊN FILE


I. CÁC LỆNH


1. Tạo 1 file handle: AH = 3Ch
Input
: DS:DX trỏ đến đường dẫn đến file cần mở, là chuỗi ASCIIZ.
CX chứa giá trị thuộc tính file.
CX = 00: normal
= 01: read-only
= 02: hidden
= 04: system
= 10h: tên thư mục con
= 20h: archive
Output
:Nếu CF=0 thì AX = handle của file
Nếu CF=1 thì lỗi tạo handle cho file.

2. Mở file: AH = 3Dh
Input

: DS:DX trỏ đến đường dẫn đến file cần mở, là chuỗi ASCIIZ.
AL là kiểu mở
AL = 0: read-only
= 1: write-only
= 2: read/write
Output
: Nếu CF = 0 thì AX chứa handle của file
Nếu CF = 1 thì lỗi mở file

3. Đọc file: AH = 3Fh
Input
: BX chứa handle của file.
CX chứa số byte cần đọc.
DS:DX trỏ đến buffer đủ lớn để chứa các byte đọc được.
Output
: Nếu CF = 0 thì AX chứa số byte thật sự đọc được.
Nếu CF = 1 thì việc đọc có lỗi, xét AX.
Nếu AX = 5 là lỗi đọc
Nếu AX = 6 là thẻ không có giá trị.

4. Ghi file: AH = 40h
Input
: BX chứa handle của file.
CX chứa số byte cần ghi.
DS:DX trỏ đến buffer chứa các byte để ghi.
Khoa Công Nghệ Thông Tin – Trường ĐH KHTN Tp.HCM - 1 -
Hướng dẫn thực hành môn Hợp Ngữ File
Output: Nếu CF = 0 thì AX chứa số byte thật sự được ghi.
Nếu CF = 1 thì thông báo lỗi ghi file, xét AX.
Nếu AX = 5: file không được phép ghi.

Nếu AX = 6: thẻ chưa mở hoặc không có giá trị.

5. Đóng file: AH = 3Eh
Input
: BX = file handle
Output
: Nếu CF = 0 có nghĩa đã lưu tất cả nội dung file xuống đĩa, đóng
file thành công.
Nếu CF = 1 thì đóng file không thành công (handle của file không
hợp lệ).

6. Xóa file: AH = 41h
Input
: DS:DX trỏ đến đường dẫn file cần xoá
Output
: Nếu CF = 0 thì xoá file thành công
Nếu CF = 1 thì xét AX:
Nếu AX = 5: đường dẫn không hợ p lệ hay file không tìm thấy
Nếu AX = 6: đường dẫn chỉ đến 1 thư mục hay 1 file chỉ đọc.

7. Di chuyển con trỏ file (đọc/ghi): AH = 42h
Input
: BX chứa thẻ file
CX:DX chứa khoảng di chuyển tính theo byte
AL chứa kiểu di chuyển:
AL = 00: di chuyển từ đầu file
AL = 01: tại vị trí con trỏ hiện tại
AL = 02: từ cuối file
Output
: Nếu CF = 0 thì DX:AX chứa vị trí mới của con trỏ

Nếu CF = 1 thì việc di chuyển con trỏ không thành công, xét AX:
- Nếu AX = 1 thì giá trị trong thanh ghi AL không có trong 3
giá trị hợp lệ của phần input trước khi gọi ngắt.
- Nếu AX = 6 thì handle không mở.

8. Đổi thuộc tính cho file
Input
: DS:DX trỏ đến đường dẫn file là 1 chuỗi ASCIIZ.
Nếu AL = 0 để lấy thuộc tính file
Nếu AL = 1 để đặt thuộc tính file thì
- CX = 00: normal
- CX = 01: read-only
- CX = 02: hidden
- CX = 04: system
- CX = 10h: thư mục con
- CX = 20h: archive
Output
: Nếu CF = 0 và AL = 00h thì CL chứa thuộc tính của file
Khoa Công Nghệ Thông Tin – Trường ĐH KHTN Tp.HCM - 2 -
Hướng dẫn thực hành môn Hợp Ngữ File
Nếu CF = 1 thì có lỗi, xét AX:
Nếu AX = 1: AL không hợp lệ.
Nếu AX = 3: đường dẫn không hợp lệ hoặc file không tìm
thấy.
Nếu AX = 5: không thể thay đổi thuộc tính.
Khoa Công Nghệ Thông Tin – Trường ĐH KHTN Tp.HCM - 3 -

×