Lập trình Assembly-Bài 4-P1
MỘT SỐ LỆNH ASSEMBLY CƠ BẢN
Cú pháp lệnh:
Một lệnh hợp ngữ đầy đủ gồm bốn thành phần sau đây:
[Nhãn lệnh:] <Tên lệnh> [Các toán hạng] [;Chú thích]
Trong đó:
- [Nhãn lệnh:]: Là một dãy các kí tự đứng trước câu lệnh (kết thúc bởi dấu hai chấm (:)), nó được chỉ định thay thế cho địa chỉ của câu lệnh trong các đoạn lệnh lặp, rẽ nhánh,... Do đó nó chỉ được sử dụng khi cần.
Trong một chương trình hợp ngữ không thể có hai nhãn lệnh trùng tên, tên của các nhãn cũng không thể trùng với tên của các thủ tục trong chương trình.
- <Tên lệnh>: Là một trong các lệnh thuộc tập lệnh hợp ngữ (lệnh gợi nhớ: Mnemonic) của vi xử lý trên máy tính thực hiện lệnh này.
Lệnh hợp ngữ không phân biệt chữ hoa hay chữ thường. Trong chương trình hợp ngữ mỗi dòng chỉ có thể chứa một lệnh và mỗi lệnh phải được đặt trên một dòng.
- [Các toán hạng]: Là đối tượng mà lệnh tác động vào. Một lệnh hợp ngữ của Intel 8088/8086 có thể không có toán hạng, có một toán hạng, hoặc có hai toán hạng. Nếu có hai toán hạng thì toán hạng đứng trước gọi là [Toán hạng đích], toán hạng đứng sau gọi là [Toán hạng nguồn]. [Toán hạng đích] không thể là một hằng số.
Một số lệnh hợp ngữ của các Intel 80286/80386/... có thể có đến 3 toán hạng, trong trường hợp này cũng chỉ có một [Toán hạng đích].
- [;Chú thích]: Chỉ có tác dụng với người viết và người đọc chương trình, nó không có ý nghĩa với trình biên dịch, tức là, không được dịch sang mã máy. Lời giải thích thường được sử dụng để làm rõ ý nghĩa của câu lệnh (khi người viết thấy cần). Lời giải thích phải nằm sau dấu chấm phảy (;).
Ví dụ 1: Xét lệnh sau đây:
Mov AX,BX ; đặt giá trị thanh ghi BX vào thanh ghi AX
Trong đó:
- Lenh_VD: Trong trường hợp này dãy kí tự Lenh_VD được sử dụng làm nhãn lệnh cho lệnh Mov.
- Mov: Là tên lệnh.
- AX và BX: Là các toán hạng (đích và nguồn). Trong trường hợp này toán hạng là các thanh ghi đa năng 16 bít.
- “đặt giá trị thanh ghi BX vào thanh ghi AX”: Là lời giải thích cho lệnh này. Trong thực tế lời giải thích thường là tiếng Việt không dấu.
Ví dụ 2: Xem các lệnh sau đây:
- NOP ; đây là lệnh không có toán hạng
- Mov Ax, Bl ; lệnh này có hai toán hạng, [Toán hạng đích] là thanh
; ghi 16 bít, [Toán hạng nguồn] là thanh ghi 8 bít
- Add Cl, Spt ; lệnh này có hai toán hạng, [Toán hạng đích] là thanh
; ghi 8 bít, [Toán hạng nguồn] là một biến byte
- Mov Ax, [SI] ; lệnh này có hai toán hạng, [Toán hạng đích] là thanh
; ghi 16 bít, [Toán hạng nguồn] là một ô nhớ
- Sub Dl, ‘a’ – ‘A’ ; lệnh này có hai toán hạng, [Toán hạng đích] là thanh
; ghi 8 bít, [Toán hạng nguồn] là một hằng số
- IMul Ax, Bx, 20 ; lệnh này có ba toán hạng, [Toán hạng đích] là thanh
; ghi 16 bit (Ax), [Toán hạng nguồn] là thanh ghi 16 bít
; (Bx) và một hằng số (20)
Lệnh Imul ở trên là một lệnh nhân mới của vi xử lý Intel 80286. Lệnh này thực hiện như sau: lấy nội dung/giá trị hai [Toán hạng nguồn] nhân với nhau, kết quả chứa ở [Toán hạng đích] (trong lệnh trên là: Bx*20, tích kết quả chứa ở thanh ghi Ax (chỉ lấy 16 bít thấp của tích để đưa vào Ax)).
1. Lệnh Mov (Move):
Cú pháp lệnh:
Mov [Toán hạng đích], [Toán hạng nguồn]
Trong đó:
- [Toán hạng đích]: Có thể là thanh ghi (8 bít hay 16 bít), ô nhớ (chính xác hơn là địa chỉ của một ô nhớ) hay một biến nào đó. [Toán hạng đích] không thể là hằng số.
- [Toán hạng nguồn]: Có thể là hằng số, biến, thanh ghi, ô nhớ (chính xác hơn là địa chỉ của một ô nhớ) nào đó.
Tác dụng: Lấy nội dung (giá trị) của [Toán hạng nguồn] đặt vào [Toán hạng đích]. Nội dung của [Toán hạng nguồn] không bị thay đổi.
Ví dụ:
- Mov Ax, [SI] ; đặt nội dung ô nhớ được chỉ bởi SI vào thanh ghi Ax
- Mov [DI], Bx ; đặt giá trị của thanh ghi bx vào ô nhớ được chỉ bởi DI
- Mov [DI], [SI] ; [DI] ß [SI] : lệnh không hợp lệ, vì: không thể chuyển
; nội dung của ô nhớ vào một ô nhớ một cách trực tiếp
- Mov Var1, Ax ; Var1 ß Ax : đặt giá trị t/ghi Ax vào biến word Var1
Chú ý:
- Lệnh Mov không làm ảnh hưởng đến các cờ.
- Mov DS:[DI], ES:[SI] ; lệnh không hợp lệ, vì: không thể chuyển dữ liệu
; trực tiếp giữa hai toán hạng bộ nhớ với nhau
- Mov DS, ES ; DS ß ES: lệnh không hợp lệ,
- Mov ES, 0100 ; lệnh không hợp lệ, vì: không thể chuyển
; trực tiếp một hằng số vào thanh ghi đoạn.
Để chuyển giá trị của hai thanh ghi đoạn hay nội dung của hai ô nhớ ta có thể mượn một thanh ghi đa năng làm trung gian:
- Mov Ax, ES ; hai lệnh này chuyển nội dung của thanh ghi đoạn ES
Mov DS, Ax ; vào thanh ghi đoạn DS thông qua thanh ghi Ax
Theo cách thông thường, để hoán đổi giá trị của hai thanh ghi đoạn hay nội dung của hai ô nhớ người ta thường sử dụng hai thanh ghi đa năng làm trung gian:
- Mov Ax, [DI] ; lưu tạm nội dung ô nhớ được chỉ bởi DI và Ax
Mov Bx, [SI] ; lưu tạm nội dung ô nhớ được chỉ bởi SI và Bx
Mov [DI], Bx ; chuyển giá trị của t/ghi Bx và ô nhớ được chỉ bởi DI
Mov [SI], Ax ; chuyển giá trị của t/ghi Ax và ô nhớ được chỉ bởi SI
Bốn lệnh trên có tác dụng hoán đổi nội dung của hai ô nhớ trong đoạn Data (DS) được chỉ bởi DI và SI (DI và SI chứa địa chỉ Offset của các ô nhớ).
- Không thể dùng thanh ghi đoạn CS làm [Toán hạng đích] trong lệnh Mov.
2. Các lệnh Inc – Dec – Add và Sub
Cú pháp lệnh:
- Inc [Toán hạng đích]
- Add [Toán hạng đích],[Toán hạng nguồn]
- Dec [Toán hạng đích]
- Sub [Toán hạng đích],[Toán hạng nguồn]
Trong đó: [Toán hạng đích], [Toán hạng nguồn]: tương tự lệnh Mov.
Tác dụng:
- Lệnh Inc (Increment): làm tăng giá trị của [Toán hạng đích] lên 1 đơn vị.
- Lệnh Dec (Decrement): làm giảm giá trị của [Toán hạng đích] xuống 1 đơn vị.
- Lệnh Add (Addition): lấy giá trị/nội dung của [Toán hạng nguồn] cộng vào giá trị/nội dung của [Toán hạng đích], kết quả này đặt vào lại [Toán hạng đích].
- Lệnh Sub (Subtract): lấy giá trị/nội dung của [Toán hạng đich] trừ đi giá trị/nội dung của [Toán hạng nguồn], kết quả này đặt vào lại [Toán hạng đích].
Ví dụ 1:
Mov Ax, 121 ; đặt giá trị 121 vào thanh ghi Ax
Mov Bx, 223 ; đặt giá trị 232 vào thanh ghi Bx
Inc Ax ; Ax = Ax + 1: tăng Ax lên 1 đơn vị (Ax = 122)
Dec Bx ; Bx = Bx + 1: giảm Bx xuống 1 đơn vị (Bx = 222)
Sub Ax, Bx ; Ax = Ax – Bx : Ax = -100
Add Ax, 120 ; Ax = Ax + 120 : Ax = 20
Mov Cx, Ax ; Cx= Ax : Cx = 20
Dãy lệnh trên, đặt giá trị cuối cùng của thanh ghi Ax vào thanh ghi Cx (Cx = 20).
Ví dụ 2:
- Inc Spt ; Spt = Spt + 1; tăng giá trị biến Spt lên 1 đơn vị
- Inc DS:[SI] ; tăng ndung ô nhớ được chỉ bởi DS:SI lên 1 đơn vị
- Add Ax, Var1 ; Ax = Ax + Var1; cộng giá trị biến Var1 vào Ax
- Add Var2, Dx ; Var2 = Var2 + Dx. Biến Var2 là biến dạng word
- Add Dx, [SI] ; cộng thêm nội dung ô nhớ được chỉ bởi SI vào Dx
- Add [DI], [SI] ; [DI] = [DI] + [SI] : lệnh không hợp lệ, vì: không thể
; cộng trực tiếp nội dung hai ô nhớ với nhau.
; Yêu cầu của lệnh trên có thể được viết lại như sau:
Mov Ax, [SI] ; lưu tạm nội dung ô nhớ được chỉ bởi SI và Ax
Mov Bx, [DI] ; lưu tạm nội dung ô nhớ được chỉ bởi DI và Bx
Add Bx, Ax ; cộng Ax và Bx, kết quả chứa ở Bx
Mov [DI], Bx ; đặt kết quả phép cộng vào lại ô nhớ được chỉ bởi DI
Chú ý 1:
- Không thể cộng trực tiếp hai thanh ghi đoạn. Trong trường hợp này phải sử dụng các thanh ghi đa năng làm trung gian.
- Lệnh Add thực hiện phép cộng không nhớ. Để thực hiện phép cộng có nhớ (cộng thêm giá trị của cờ nhớ (CF) hiện tại vào kết quả) phải sử dụng lệnh ADC (ADD with Carry) [2 - 171]. Tương tự với lệnh Sub và SBB [2 - 180].
- Để thực hiện phép cộng trên các số/giá trị BCD (Binary Coded Decimal) ta phải sử dụng các lệnh cộng AAA (Ascii Adjust for Addition) và DAA (Decimal Adjust for Addition) để điều chỉnh (adjust) kết quả cuối cùng [2 - 172]. Tương tự, với phép trừ trên các số BCD phải sử dụng lệnh AAS và DAS [2 - 183].
Chú ý 2:
- Các thanh ghi của vi xử lý Intel 8086/8088 đều là 16 bít, nên để chứa một đại lượng dữ liệu 32 bít nó phải dùng 2 thanh ghi, thường là các thanh ghi đa năng (thanh ghi tích lũy): Ax, Bx, Cx, Dx. Cặp thanh ghi Dx:Ax thường được sử dụng nhất, khi đó Ax chứa 16 bít thấp, Dx chứa 16 bít cao của đại lượng 32 bít.
- Để cộng/trừ trên các số 32 bít ta không thể sử dụng Add/Sub theo cách thông thường, mà phải thực hiện như sau: Cộng/Trừ 16 bít thấp, sau đó Cộng/Trừ 16 bít cao. Nếu phép Cộng/Trừ trên 16 bít thấp xuất hiện bít nhớ/bít mượn thì phải tiến hành điều chỉnh kết quả, nếu không kết quả sẻ sai. Sử dụng các phép kiểm tra cờ để biết phép Cộng/Trừ có xuất hiện bít nhớ/bít mượn hay không [1 - 477].