Các lệnh điều khiển

Một phần của tài liệu Kiến trúc máy tính (Trang 84 - 88)

6.3.1. Các lệnh điều kiện, lặp Cú pháp:

Loop <Nhãn đích>

Trong đó: <Nhãn đích> 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 <Nhãn lệnh> đủ 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

83

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

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

84

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ớ 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ớ

6.3.2. Lệnh chuyển hướng chương trình Cú pháp:

LEA [Toán hạng đích],[Toán hạng nguồn]

Trong đó: [Toán hạng đích]: Là các thanh ghi 16 bít. [Toán hạng nguồn]: Là địa chỉ của một vùng nhớ hay tên của một biến.

Tác dụng: Lệnh LEA có tác dụng chuyển địa chỉ offset của [Toán hạng nguồn] vào [Toán hạng đích]. Lệnh này thường được sử dụng để lấy địa chỉ offset của một biến đã được khai báo trong chương trình. Thanh ghi được sử dụng trong trường hợp này là thanh ghi cơ sở (BX) và thanh ghi chỉ mục (SI và DI).

Ví dụ 1:

Lea Bx, DS:[0100] ; chuyển thành phần địa chỉ offset (0100) vào Bx Lea DI, XauKT ; chuyển địa chỉ offset của biến XauKT vào DI

; thao tác này thường được gọi là trỏ DI và đầu

; biến XauKT

Khi chương trình được nạp vào bộ nhớ để hoạt động thì các biến được khai báo trong chương trình sẽ được định vị (cấp phát vùng nhớ) tại một địa chỉ xác định trong vùng nhớ Data. Từ đây, để thao tác đến dữ liệu trên các biến của chương trình thì chương trình phải xác định được địa chỉ segment vào offset (hai thành phần của địa chỉ logic) của biến. Lệnh LEA ở trên chỉ lấy được địa chỉ offset của biến, để lấy được địa chỉ segment của nó ta có thể sử dụng lệnh Mov với toán tử Seg (tương tự có thể sử dụng lệnh Mov với toán tử Offset để lấy địa chỉ offset của biến). Ví dụ: Các lệnh sau lấy địa chỉ Segment:Offset của biến XauKT (hay trỏ DS:SI về đầu biến XauKT):

Mov Ax, Seg XauKT ; đưa địa chỉ Segment của biến XauKT Mov DS, Ax ; vào thanh ghi DS

Mov SI, Offset XauKT ; đưa địa chỉ Offset của biến XauKT vào SI Ví dụ 2: Giả sử biến TenGom (là biến kiểu byte) đã được khai báo như sau:

85 TenGom DBNguyen Kim Le Tuan’

Xem các lệnh sau đây (1):

Mov Bx, 0

Mov Al, TenGom[Bx] ; Al =‘N’

Add Bx, 7 ;

Mov Bl, TenGom[Bx] ; Bl =‘K’

Xem các lệnh sau đây (2):

Lea DI, TenGom

Mov Al, [DI] ; Al =‘N’

Mov Bl, [DI + 7] ; Bl =‘K’

Ta có thể thấy, nhóm các lệnh (1) và nhóm các lệnh (2) là tương đương nhau về tác dụng của nó, nhưng (1): sử dụng trực tiếp tên biến để truy xuất đến các phần tử của nó; (2): sử dụng thanh ghi chỉ mục DI để truy xuất đến các phần tử của biến. Trong trường hợp này địa chỉ segment mặc định được chỉ bởi DS, điều này phù hợp với việc sử dụng địa chỉ gián tiếp thanh ghi chỉ mục.

Ví dụ 3: 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 vào một biến trong chương trình.

Với yêu cầu này chương trình phải khai báo một biến byte có độ lớn 50 byte:

LuuTru DB 50 Dup (‘ ‘) 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, 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 kí 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 kí tự tiếp theo

Inc DI

Loop Lap_Copy ; lặp lại đủ 50 lần (để copy đủ 50 kí tự)

Chú ý: Hợp ngữ còn cung cấp các lệnh LDS (Load Pointer use DS) để lấy nội dung toán hạng bộ nhớ 32 bít đưa vào các thanh ghi 16 bít (mặc định 16 bít cao vào thanh ghi đoạn dữ liệu DS); và lệnh LES (Load Pointer use DS) tương tự LDS nhưng mặc định 16 bít cao vào thanh ghi đoạn dữ liệu (thứ hai) ES [2 - 137].

*) Lệnh chuyển dữ liệu qua cổng: IN và OUT Cú pháp:

IN AL, <Địa chỉ cổng>

86

OUT <Địa chỉ cổng>, AL

Trong đó:<Đị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.

Tác dụng:

- 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.

Ví 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:

Một phần của tài liệu Kiến trúc máy tính (Trang 84 - 88)

Tải bản đầy đủ (PDF)

(95 trang)