Lập trình Assembly-Bài 5-P2
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 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.
Hàm 02 của ngắt 21h:
Tác dụng: 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ử dụng:
Vào: Ah = 02
Dl = <Kí tự cần in ra>
Ra: Không có
Ví dụ 1: Các lệnh sau đây in ra màn hình kí tự A:
Mov Ah, 02
Mov Dl, ‘A’ ;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, ‘A’
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 ‘Khoa CNTT Truong DHKH Hue’
Các lệnh:
Lea DI, TieuDe
Mov Cx, 25
Mov Ah, 02
Lap_In:
Mov Dl, Byte PTR [DI]
Int 21h
INC DI
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
;--------------------------------------
Hàm 09 của ngắt 21h:
Tác dụng: 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ử dụng:
Vào: Ah = 09
DS:DX = <Segment:Offset của xâu cần in ra>
Ra: Không có
Ví 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 ‘Truong DH Khoa hoc Hue$’
- 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
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 ‘Khoa CNTT Truong DHKH Hue$’
Các lệnh sau chỉ in các kí 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 lệnh sau chỉ in các kí 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], ‘$’
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
Mov Byte PTR DS:DX, ‘$’
;-------------------------------------
Mov Ah, 09
Int 21h
;-------------------
Hàm 01 của ngắt 21h:
Tác dụng: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ử dụng:
Và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ự ‘*’.
Ví 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 (‘ ‘)
Các lệnh:
Mov Ax, Seg LuuXau
Mov DS, Ax
Lea DI, LuuXau
;--------------------------------
Mov Cx, 30
Mov Ah, 01
Nhap_Xau:
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ự.
Hàm 0Ah của ngắt 21h:
Tác dụng: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 (‘ ‘)
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ử dụng:
Và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.
Ví 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: “Tin 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 “Tin hoc”
- Từ byte 2 đến 8 chứa lần lượt các kí tự trong xâu “Tin hoc.
Ví dụ 2: Giả sử chương trình đã khai báo xâu TieuDe như sau:
TieuDe DB 100, 0, 100 Dup (‘ ‘)
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
Add Dx, 2
Mov DI, Dx
Mov Cx, 0
Mov Cl, TieuDe[1]
Add DI, Cx
Mov Byte PTR DS:[DI], ‘$’
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ự ‘$’, nhờ đó, khi dùng hàm 09h/21h để in ra chương trình không cần đưa thêm kí tự ‘$’ 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
Int 21h
;-------------------------
Mov Ah, 09h
Lea Dx, Buff
Add Dx, 2
Int 21h
;-------------------------
Int 20h
Main Endp
End Start
BÀI VIẾT LIÊN QUAN:
Bài báo đăng Tạp chí ngành cơ khí Việt Nam
The paper presents the researched results on design and manufacture of ...
Sửa lỗi USB hoặc thẻ nhớ SD không thể format ở Windows 10
Nếu bạn đang gặp phải vấn đề với việc format USB hay thẻ nhớ SD thì bài viết ...