Lập trình Assembly-Bài 4-P3
5. Lệnh Mul và Div
Cú pháp:
Trong đó: [Toán hạng nguồn]có thể là thanh ghi hay ô nhớ. Với các lệnh nhân: [Toán hạng đích] ngầm định là thanh ghi Al hoặc Ax. Với các lệnh chia: [Toán hạng đích] là một trong các thanh ghi đa năng Ax, Bx,...
Tác dụng:
- Lệnh Mul (Multiply): Thực hiện phép nhân trên số không dấu. Nếu [Toán hạng nguồn] là toán hạng 8 bít thì lệnh sẽ nhân nội dung của [Toán hạng nguồn] với giá trị thanh ghi AL, kết quả 16 bít chứa ở thanh ghi Ax.
Nếu [Toán hạng nguồn] là toán hạng 16 bít thì lệnh sẽ nhân nội dung của [Toán hạng nguồn] với giá trị thanh ghi Ax, kết quả 32 bít chứa ở cặp thanh ghi Dx:Ax, phần thấp ở Ax, phần cao ở Dx. Nếu phần cao của kết quả (AH hoặc DX) bằng 0 thì các cờ CF = 0 và OF = 0.
- Lệnh IMul (Interger Multiply): Tương tự lệnh Mul nhưng thực hiện phép nhân trên hai số có dấu. Kết quả cũng là một số có dấu.
- Lệnh Div (Divide): Thực hiện phép chia trên số không dấu. Nếu [Toán hạng nguồn] là toán hạng 8 bít thì lệnh sẽ lấy giá trị của thanh ghi Ax (số bị chia) chia cho [Toán hạng nguồn] (số chia), kết quả thương số chứa trong thanh ghi Al, số dư chứa trong thanh ghi Ah.
Nếu [Toán hạng nguồn] là toán hạng 16 bít thì lệnh sẽ lấy giá trị của cặp thanh ghi Dx:Ax (số bị chia) chia cho [Toán hạng nguồn] (số chia), kết quả thương số chứa trong thanh ghi Ax, số dư chứa trong thanh ghi Dx.
Nếu phép chia cho 0 xảy ra hay thương số vượt quá giới hạn của thanh ghi AL (chia 8 bít) hay Ax (chia 16 bít) thì CPU sẽ phát sinh lỗi “Divice overflow”.
- Lệnh Idiv (Integer Divide): Tương tự lệnh Div nhưng thực hiện phép chia trên hai số có dấu. Kết quả cùng là các số có dấu.
Ví dụ 1:
- Mul Bl ; Ax ßAL * Bl: số bị nhân ngầm định trong Al
- Mul Bx ; Dx:Ax ßAx * Bx: số bị nhân ngầm định trong Ax
- Idiv Bl ; Ax/Bl, thương số chứa trong Al, số dư chứa trong Ah
- Idiv Bx ; Dx:Ax/Bx, thương số chứa trong Ax, số dư trong Dx
Ví dụ 2: Dãy các lệnh dưới đây sẽ thực hiện phép gán A = 4*A – 3*B, trong đó A và B là các biến kiểu word:
Mov Ax, 4 ; số nhân phải được chứa trong Ax
IMul A ; thực hiện phép nhân
Mov Bx, Ax ; lưu tạm kết quả vào Bx
Mov Ax, 3 ; Ax = 3
Imul B ; Ax = Ax * B
Sub Bx, Ax
Mov A, Bx ; đặt kết quả cuối cùng vào A
Trong trường hợp này ta đã giả sử hiện tượng tràn đã không xảy ra và kết quả phép nhân chỉ chứa trong thanh ghi Ax.
Ví dụ 3: Các lệnh sau đây thực hiện phép: chia -123 cho 24:
Mov Ax, -123 ; đặt số bị chia vào Ax
Mov Bl, 24 ; đặt số chia vào Bl (thanh ghi 8 bít)
Idiv Bl ; chia Ax cho Bl, kết quả chứa ở Al và Ah
Ví dụ 4: Dãy lệnh dưới đây sẽ thực hiện phép gán A = N! (tính N giai thừa). A là một biến word:
Mov Ax, 1 ; chuẩn bị Ax để lưu kết quả
Mov Cx, N ; tính N!
LapNhan:
Mul Cx ; Ax ßAx * Cx
Loop LapNhan
;---------------------------
Mov A, Ax ; trả kết quả vào biến A
Trong trường hợp này chúng ta giả sử kết quả không vượt quá gới hạn 16 bít.
Chúng ta đã biết: N! = 1 nếu N = 1, N! = N*(N-1)*(N-2)*...*1 nếu N>1, điều này hoàn toàn phù hợp với sự thay đổi của thanh ghi CX trong lệnh lặp Loop. Do đó, ở đây ta có thể sử dụng CX như là N trong biểu thức tính giai thừa.
Chú ý: Hợp ngữ cung cấp lệnh AAM (Ascii Adjust for Multiple) để điều chỉnh kết quả phép nhân trên 2 số BCD dạng không dồn. Và lệnh AAD (Ascii Adjust for Division) để điều chỉnh kết quả phép chia trên 2 số BCD dạng không dồn. Ngoài ra còn có lệnh CBW (Convert Byte to Word) và lệnh CWD (Convert Word to Doubleword) để hỗ trợ cho phép chia trên các số có dấu [2 – 187-200].
Lệnh IMul của vi xử lý Intel 80286 cho phép ghi rõ [Toán hạng đích], [Toán hạng nguồn] trong câu lệnh, các lệnh này có thể có đến 3 toán hạng [1 - 541].
6. Lệnh chuyển dữ liệu qua cổng: IN và OUT
Cú pháp:
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:
Mov Al, POR ;
Mov Bl, DAT ;
Out Bl, Al ;
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 ...