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 [Toán hạng đí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].
113 trang |
Chia sẻ: nguyenlam99 | Lượt xem: 3195 | Lượt tải: 0
Bạn đang xem trước 20 trang tài liệu Tự học lập trình assembly - Bài 1: Bước đầu với lập trình assembly trên vi xử lý intel 8086/8088, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
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ố hà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 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 =
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 =
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ếnTieuDe 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 =
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 =
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ếnTieuDe:
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
Một số ví dụ:
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
;-------------------------------------
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 ‘D:\ASSEM\BTCB’,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:
...
;----------------------------------------------------
Tự học lập trình Assembly - Bài 5: Sử dụng Interrupt trong chương trình assembly (2)
Thứ Ba, 03/09/2013 16:05
MỘT SỐ VÍ DỤ
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
;-------------------------------------
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 ‘D:\ASSEM\BTCB’,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:
...
;----------------------------------------------------
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
;--------------------------
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
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], ‘$’
;-------------------------
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
.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
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
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
;-------------------------
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
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
Tự học lập trình assembly - Bài 6: Tập lệnh assembly của Intel 8088/8086 - Tiếp theo (1)
Thứ Sáu, 25/10/2013 15:44
TẬP LỆNH ASSEMBLY CỦA INTEL 8088/8086 - (Tiếp theo)
Lệnh so sánh:
Cú pháp: Cmp [Toán hạng đích], [Toán hạng nguồn]
Trong đó: [Toán hạng đích], [Toán hạng nguồn] có thể là hằng, biến, thanh ghi hay ô nhớ. [Toán hạng đích] không thể là hằng số. [Toán hạng đích] và [Toán hạng nguồn] không thể đồng thời là ô nhớ.
Tác dụng: Lệnh Cmp (Compare) được sử dụng để so sánh giá trị/nội dung của [Toán hạng đích] so với [Toán hạng nguồn]. Tương tự như lệnh Sub, nó lấy [Toán hạng đích] trừ đi [Toán hạng nguồn] nhưng kết quả không làm thay đổi [Toán hạng đí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à: [Toán hạng đích] > [Toán hạng nguồn]; [Toán hạng đích] ≥[Toán hạng nguồn]; [Toán hạng đích] < [Toán hạng nguồn]; [Toán hạng đích] ≤[Toán hạng nguồn]; [Toán hạng đích] = [Toán hạng nguồn]; [Toán hạng đích] ≠ [Toán hạng 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.
Ví 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, ‘A’ ; so sánh giá trị thanh ghi Al với ‘A’
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ờ.
Các lệnh nhảy
Lệnh nhảy không điều kiện:
Cú pháp: Jmp
Trong đó: 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.
Tác dụng: 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 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.
Ví dụ 1:
Start:
Jmp Main
TieuDe DB ‘Khoa CNTT – DHHH’
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
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:
Cú pháp chung:
Trong đó: : Tương tự như lệnh Jmp.
Tác dụng: 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] 0F)
Lệnh JGE: Nhảy nếu [Đích] ≥[Nguồn] ; (SF = 0F)
Lệnh JLE: Nhảy nếu [Đích] ≤[Nguồn] ; (CF 0F và ZF = 1)
...
Trong đó: [Đích] và [Nguồn] chính là hai toán hạng: [Toán hạng đích] và [Toán hạng 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 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
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
Mov Cx, Dx ; khi Ax ≤Dx
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
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
;-----------------------
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 (‘ ’)
XauHoa DB 200 Dup (‘ ’)
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, ‘A’
Jl TTuc
Cmp Al, ‘Z’
Jg TTuc
Mov ES:[DI], Al
INC DI
TTuc:
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 ‘Day la may PC/XT.$’
TB2 DB ‘Day la may PC/AT.$’
TB3 DB ‘Day la may PC classic.$’
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
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.
Các lệnh Dịch bít – Quay bít (còn tiếp)
Tự học lập trình assembly - Bài 6: Tập lệnh assembly của Intel 8088/8086 - Tiếp theo (2)
Thứ Sáu, 25/10/2013 16:08
TẬP LỆNH ASSEMBLY CỦA INTEL 8088/8086 - (Tiếp theo)
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 “chiều trái” hoặc theo “chiều phải” một hoặc nhiều bít. Thông thường các bít được dịch hay được 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 RoL và RoL) và quay có qua cờ CF (lệnh RcL và RcR).
Cú pháp:
Shr [Toán hạng đích],
Shl [Toán hạng đích],
Rcr [Toán hạng đích],
Rcl [Toán hạng đích],
Trong đó: [Toán hạng đí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.
Tác dụng:
Lệnh ShR (Shift Logical Right): Dịch chuyển các bít trong thanh ghi [Toán hạng đí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:
Rol Bx, 1
Jnc TiepTuc
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, ‘0’ ; CF = 0 tức là bít cần in có trị = 0, nên in ra kí tự ‘0’
Int 21h
Jmp In_Tiep
In_1:
Mov Dl, ‘1’
Int 21h
In_Tiep:
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, ‘1’
Je Them_Bit
Cmp Al, ‘0’
Je Them_Bit
;----------------------
Mov Ah,09
Mov Dx, Seg TB ; Biến TB được khai báo như sau:
Mov DS, Dx ; TB DB ‘Ban phai nhap 0/1 hoac Enter$’
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:
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.
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 [Toán hạng đí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].
Các lệnh xử lý chuỗi
Các file đính kèm theo tài liệu này:
- tu_hoc_lap_trinh_assembly_8763.docx