4-. Chapter 4 - Lap trinh assembly
Download
Report
Transcript 4-. Chapter 4 - Lap trinh assembly
Chương 4: Tập Lệnh
Lập trình Assembly
I
3
Khung Chương trình Assembly
II
Biên soạn và dịch chương trình Assembly
III
3
Thực hiện cấu trúc điều khiển chương trình bằng
assembly
IV
Các lệnh logic, dịch, quay, ngăn xếp và các thủ tục
V
Các lệnh nhân và chia
VI
Mảng
VII
Các lệnh thao tác với chuỗi
Chương 3: Lập trình Assembly
I
3
Khung Chương trình Assembly
II
Biên soạn và dịch chương trình Assembly
III
3
Thực hiện cấu trúc điều khiển chương trình bằng
assembly
IV
Các lệnh logic, dịch, quay, ngăn xếp và các thủ tục
IV
Các lệnh nhân và chia
IV
Mảng
IV
Các lệnh thao tác với chuỗi
I. Khung Chương trình Assembly
1. Bộ ký tự của Assembly
2. Từ khóa
3. Tên tự đặt
4. Cấu trúc một lệnh Assembly
5. Các dạng hằng dùng trong Assembly
6. Khai báo biến và hằng
7. Một số lệnh cơ bản
8. Các lệnh vào ra
I. Khung Chương trình Assembly
1. Bộ ký tự của Assembly
Các chữ cái latin: 26 chữ hoa A-Z, 26 chữ
thường a-z.
Các chữ số thập phân: ‘0’ - ‘9’
Các ký hiệu phép toán, các dấu chấm câu
và các ký hiệu đặc biệt: + - * / @ ? $ , . : [ ]
( ) < > { } & % ! \ # v.v...
Các ký tự ngăn cách: space và tab
I. Khung Chương trình Assembly
2. Từ khóa
Tên các thanh ghi, tên lệnh dạng gợi nhớ của bộ
vi xử lý, tên toán tử...
Các từ khóa này đòi hỏi người lập trình phải
dùng đúng như Assembly quy định.
Mov đích, nguồn
Push toán hạng
pushf
I. Khung Chương trình Assembly
3. Tên tự đặt
Tên là một dãy ký tự dùng để biểu thị tên
hằng, tên biến, tên nhãn, tên chương trình
con, tên đoạn nhớ...
Quy tắc đặt tên:
•
•
•
•
•
Tên chỉ gồm chữ cái,
chữ số và một số́ ký tự đặc biệt như ? @ _ $
Chữ đầu của tên bắt buộc phải là chữ cái.
Trong tên không có dấu cách.
Tên có thể dài từ 1 đến 35 ký tự.
4. Cấu trúc một lệnh assembly
Lệnh thật
Lệnh giả
Được
dịch ra
mã máy
Không
được dịch
ra mã
máy
Dòng lệnh
I. Khung Chương trình Assembly
4. Cấu trúc một lệnh assembly
Tên Mã lệnh
Các toán hạng
Chú giải
• Tên nhãn, tên biến hoặc tên thủ
tục (chương trình con).
• Các tên và nhãn này sẽ được
trình biên dịch gán bằng các địa
chỉ cụ thể của ô nhớ.
• Một nhãn kết thúc bằng dấu hai
chấm (:).
I. Khung Chương trình Assembly
4. Cấu trúc một lệnh assembly
Tên Mã lệnh
Các toán hạng
Chú giải
• Chứa các lệnh
thật hoặc lệnh giả
• Lệnh thật: chứa các toán hạng của
lệnh, có thể không có, có 1 hoặc 2 toán
hạng trong một lệnh.
• Lệnh giả: chứa các thông tin khác liên
quan đến lệnh giả.
I. Khung Chương trình Assembly
4. Cấu trúc một lệnh assembly
Tên Mã lệnh
Các toán hạng
Chú giải
• bắt đầu bằng dấu chấm phẩy.
• ghi các lời giải thích cho các lệnh của chương
• chương trình dịch không dịch từ sau dấu chấm
phẩy đến hết dòng.
I. Khung Chương trình Assembly
4. Cấu trúc một lệnh assembly
VD1:
LAP MOV
AH,[BX]
•Copy nội dung của ô nhớ có địa chỉ
DS:BX vào AH
VD2:
MAIN PROC
và
MAIN ENDP
• Hai dòng lệnh này là hai lệnh giả,
• Trường tên có tên thủ tục là MAIN,
• Trường mã lệnh có lệnh giả PROC và ENDP. Đây là hai lệnh
giả để bắt đầu và kết thúc một thủ tục có tên là MAIN.
I. Khung Chương trình Assembly
5.Các dạng hằng dùng trong assembly
Hằng số nhị phân: gồm một dãy các chữ số 0 và 1, kết thúc bằng chữ
B. Ví dụ: 10011101B
Hằng số hex: 0 đến 9 và A đến F (a đến f), kết thúc bằng chữ H. Đối
với các số bắt đầu bằng chữ thì phải thêm 0 đằng trước để báo cho
chương trình dịch biết đó là số không phải là tên.
Ví dụ: 7AC5H, 0ABH
Hằng số thập phân: 0 đến 9, có hoặc không có chữ D theo sau.
Ví dụ: 34 hoặc 34D.
Hằng ký tự: là một ký tự bất kỳ đặt giữa hai dấu phẩy trên. Ví dụ: ‘A’
Hằng xâu ký tự: là một dãy ký tự bất kỳ đặt giữa hai dấu phẩy trên.
Ví dụ: ‘Nhap’
I. Khung Chương trình Assembly
6. Khai báo biến và hằng
a) Khai báo biến
Khai báo biến kiểu byte
Khai báo biến kiểu từ
Khai báo biến kiểu từ kép
Khai báo biến mảng
Khai báo biến kiểu xâu ký tự
6. Khai báo biến và hằng
1. Khai báo biến kiểu byte
Tên biến DB
Giá trị khởi đầu
Tên biến DB
?
Ví dụ 1: B1
DB
4
• Biến kiểu byte có tên là B1
• Máy tính dành 1 byte bộ nhớ cho nó và trong byte đó có
chứa giá trị 4.
Ví dụ 2: B2
DB ?
Định nghĩa biến byte có tên là B2 và dành 1 byte bộ nhớ cho nó.
I. Khung Chương trình Assembly
6. Khai báo biến và hằng
1. Khai báo biến kiểu từ word
Tên biến DW Giá trị khởi đầu
Tên biến DW ?
Ví dụ 1: B1
DW 42H
• Biến kiểu word có tên là B1
• Máy tính dành 2 byte bộ nhớ cho nó và trong byte đó có
chứa giá trị 42H.
Ví dụ 2: B2
DW ?
Định nghĩa biến byte có tên là B2 và dành 1 byte bộ nhớ cho nó.
I. Khung Chương trình Assembly
6. Khai báo biến và hằng
1. Khai báo biến kiểu từ kép Double word
Tên biến DD Giá trị khởi đầu
Tên biến DD ?
Ví dụ 1: B1
DD 1000H
• Biến kiểu Double word có tên là B1
• Máy tính dành 4 byte bộ nhớ cho nó và trong byte đó có
chứa giá trị 1000H
Ví dụ 2: B2
DD ?
Định nghĩa biến byte có tên là B2 và dành 4 byte bộ nhớ cho nó.
I. Khung Chương trình Assembly
6. Khai báo biến và hằng
1. Khai báo biến kiểu MẢNG
Tên biến mảng
DB/DW/DD
Các giá trị khởi đầu
Gồm một dãy các phần tử và ô nhớ kiểu byte/ ord/double word
Ví dụ: M1 DB
4,5,6,7,8,9
• Biến mảng có tên là M1
• Máy tính dành 6 byte liên tiếp cho nó để chứa các giá trị khởi đầu tương
ứng là 4, 5 ,6 ,7 ,8 , 9.
• Phần tử đầu của mảng là 4 và có địa chỉ trùng với địa chỉ của tên biến
(M1), phần tử thứ hai là 5 và có địa chỉ là M1+1...
Ví dụ: M2
M3
DB
DB
20 DUP(0)
20 DUP(?)
• Biến mảng có tên là M2 gồm 20 byte để chứa 20 giá trị khởi đầu bằng 0
• Biến mảng có tên là M3 gồm 20 byte nhưng không chứa giá trị khởi đầu.
I. Khung Chương trình Assembly
6. Khai báo biến và hằng
1.
Khai báo biến kiểu MẢNG (tiếp)
Chú ý:
•
Toán tử DUP có thể dùng lồng nhau để định nghĩa 1 mảng
Ví dụ:
M4 DB
M4
•
DB
4,3,2,2 DUP(1,2 DUP(5),6)
4,3,2,1,5,5,6,1,5,5,6
Khi lưu trữ một từ trong bộ nhớ thì byte thấp của nó sẽ được để ở
ô nhớ có địa chỉ thấp, byte cao để ở ô nhớ có địa chỉ cao.
Ví dụ:
W1
DW
0FFACH
=> Byte thấp ACH sẽ được để tại địa chỉ W1, byte cao FFH sẽ
được để tại địa chỉ tiếp theo W1+1.
I. Khung Chương trình Assembly
6. Khai báo biến và hằng
1.
Khai báo biến kiểu xâu kí tự
Là trường hợp đặc biệt của biến mảng kiểu byte, trong đó các
phần tử của mảng là các ký tự.
Một xâu ký tự có thể định nghĩa bằng các ký tự hoặc bằng mã
ASCII của các ký tự đó.
Ví dụ:
• Xaukt
DB
‘ABCDE’
•
Xaukt
DB
41h,42h,43h,44h,45h
•
Xaukt
DB
41h,42h,’C’,’D’,45h
I. Khung Chương trình Assembly
6. Khai báo biến và hằng
b) Khai báo biến hằng
• Hằng có thể là kiểu số hoặc kiểu ký tự.
• Tên hằng EQU Giá trị của hằng
• Ví dụ:
CR
EQU 0Dh
LF
EQU 0Ah
CHAO
EQU ‘Hello’
• Vì lệnh giả EQU không dành chỗ của bộ nhớ cho tên hằng
nên ta có thể khai báo hằng ở bất kỳ đâu trong chương trình.
Tuy nhiên người ta thường đặt các khai báo hằng trong đoạn
dữ liệu.
7. Một số lệnh cơ bản
•
MOV Đích, Nguồn
Ví dụ: Mov AH,10D ;Chuyển giá trị 10 vào AH
Mov AX,BX ; Chuyển giá trị thanh ghi BX vào thanh ghi AX
Mov [DI],CX ; Chuyển giá trị thanh ghi CX vào ô nhớ DS:DI
•
XCHG Đích, Nguồn: Hoán đổi nội dung của 2 toán hạng đích
và nguồn
Ví dụ: XCHG AH,BL ; Hoán đổi nội dung của hai thanh ghi AH và B
• Lệnh cộng không nhớ: ADD Đích, Nguồn
Áp dụng cho= số nhị phân, gần như phép toán xor
Đích = Đích + Nguồn
• Lệnh cộng có nhớ: ADC Đích, Nguồn (Add With Carry)
Đích Đích + Nguồn + CF
7. Một số lệnh cơ bản
- Lệnh tăng: INC Đích
Đích Đích + 1
- Lệnh giảm: DEC Đích
Đích Đích - 1
- Lệnh trừ không mượn: SUB Đích, Nguồn
Đích Đích - Nguồn
- Lệnh trừ có mượn: SBB Đích, Nguồn
Đích Đích - Nguồn - CF
- NEG Đích
Đích -Đích
- LEA Đích, Nguồn (Load Effective Address): Nạp địa chỉ thực
+ Đích thường là một trong các thanh ghi: BX, CX, DX, BP, SI, DI
+ Nguồn là tên biến trong đoạn DS được chỉ rõ trong lệnh hoặc ô nhớ
cụ thể
=> Chuyển địa chỉ lệch của ô nhớ Nguồn vào thanh ghi Đích 16 bit
VD: Tb1 db “Nhap so can kiem tra: $”
LEA DX, Tb1
8. Các lệnh vào ra
• Lệnh INT: Gọi các chương trình ngắt của DOS và BIOS.
• Dạng lệnh: INT số_hiệu_ngắt
• Ngắt INT 21h
=> Ngắt int 21h dùng để gọi rất nhiều hàm của DOS. Mỗi hàm
được gọi bằng cách đặt số hàm vào trong thanh ghi AH và gọi
ngắt INT 21h
8. Các lệnh vào ra
Hàm 1: Vào một kí tự
Input AH=1
Ra AL = Lưu mã ASCII của kí tự nhập vào
= 0 Nếu 1 phím điều khiển hay chức năng
được ấn
=> Để gọi phục vụ này ta thực hiện lệnh:
MOV AH,1
INT 21h
8. Các lệnh vào ra
Vd: Nhập vào 2 số: Al, BL sau đó đảo giá trị cho nhau
MOV AH,1
INT 21H
MOV BL,AL
MOV AH,1
INT 21H
XCHG AL,BL
Nhập x
Nhập y
Đảo giá trị
8. Các lệnh vào ra
Hàm 2: Hiển thị một kí tự hay thi hành một chức năng điều
khiển
Input: AH=2
DL=Mã ASCII của kí tự hiển thị hay kí tự điều khiển
Output: Giá trị của DL
Ví dụ: sau sẽ hiển thị dấu “?” lên màn hình
MOV AH,2
MOV DL,”?”
INT 21h
Về đầu dòng
Xuống dòng
8. Các lệnh vào ra
Hàm 9: Hiển thị một chuỗi kí tự
Input: AH=9
DX=Địa chỉ tương đỗi của chuỗi
Output: Hiễn thị một chuỗi ra màn hình
Kí tự “$” đánh dấu kết thúc chuỗi và không được hiển thị. Nếu
chuỗi chứa mã ASCII của kí tự điều khiển thì các chức năng điều
khiển sẽ được thi hành
VD: msg
DB
“Xin chao $”
Để sao chép địa chỉ tương đối từ nguồn sang đích
LEA đích, nguồn
VD: Lea DX, msg
8. Các lệnh vào ra
Chu trình hiển thị chuỗi kí tự
B1: Khởi tạo đoạn dữ liệu chứa trong thanh ghi DS
MOV AX,@DATA
MOV
DS,AX
@ DATA : Tên đoạn dữ liệu được định nghĩa bởi .Data
Địa chỉ dữ liệu không chuyển trực tiếp.
B2: đưa địa chỉ vào thanh ghi DX
LEA DX,MSG
MOV AH,9
INT
21H
Vd: Viết chương trình hiển thị một chuỗi kí tự bất kì
9.Khung chương trình assembly
Khai báo quy mô sử dụng bộ nhớ
1
2
Khai báo đoạn ngăn xếp
Khai báo đoạn dữ liệu
Khai báo đoạn mã
3
4
a. Khai báo quy mô sử dụng bộ nhớ
.MODEL Kiểu_kích_thước_bộ_nhớ
9.Khung chương trình assembly
Khai báo quy mô sử dụng bộ nhớ
1
2
Khai báo đoạn ngăn xếp
Khai báo đoạn dữ liệu
Khai báo đoạn mã
3
4
2. Khai báo đoạn ngăn xếp .
• Máy tính dành ra một vùng nhớ đủ lớn dùng làm ngăn xếp phục
vụ cho hoạt động của chương trình.
• Cú pháp:
.STACK Kích_thước
• Kích_thước quyết định số byte dành cho ngăn xếp. Thông
thường với 100 - 256 byte là đủ để làm ngăn xếp và ta có thể
khai báo kích thước cho ngăn xếp như sau:
.STACK 100
hoặc
.STACK 100H
9.Khung chương trình assembly
Khai báo quy mô sử dụng bộ nhớ
1
2
Khai báo đoạn ngăn xếp
Khai báo đoạn dữ liệu
Khai báo đoạn mã
3
4
3. Khai báo đoạn dữ liệu .
•Bao gồm toàn bộ các khai báo biến và hằng của chương trình.
Các khai báo trong đoạn dữ liệu đặt sau lệnh giả .DATA
Ví dụ:
.DATA
MSG
B1
CR
LF
DB
DB
EQU
EQU
‘Hello!$’
100
0DH ; Quay về đầu dòng
0AH ; Xuống dòng
4. Khai báo đoạn mã
• Đoạn mã chứa mã lệnh của chương trình
• Để bắt đầu đoạn mã ta dùng lệnh giả .CODE
• Chương trình chính và chương trình con.
.CODE
Tên_CTChính PROC
;Các lệnh của chương trình chính
…
.
CALL Tên_CTCon ;Gọi chương trình con
…
Tên_CTChính ENDP
;Khai báo các chương trình con ở đây
Tên_CTCon
PROC
;Các lệnh của chương trình con
RET
;Trở về
Tên_CTCon
ENDP
VD
5. Khung chương trình Assembly để dịch ra chương
trình .exe
.
.MODEL
SMALL
.STACK 100H
.DATA
;Các khai báo biến và hằng để tại đây
.CODE
MAIN PROC
;Khởi đầu cho đoạn DS
MOV AX,@DATA
MOV DS,AX
;Các lệnh của chương trình để tại đây
......
;Trở về DOS dùng hàm 4CH của INT 21H
MOV AH,4CH
INT 21H
MAIN ENDP
;Các chương trình con (nếu có) khai báo tại đây
END MAIN
;Kết thúc toàn bộ chương trình
VD
5. Khung chương trình Assembly để dịch ra chương
trình .com
.
. Đoạn mã, đoạn dữ liệu và đoạn ngăn xếp được gộp lại trong một
đoạn duy nhất là đoạn mã
.MODEL TINY
.CODE
ORG 100H ; để gán địa chỉ bắt đầu của chương trình tại 100h
; để nhảy qua toàn bộ phần bộ nhớ dành cho việc khai báo dữ liệu
START: JMP CONTINUE.
;Các khai báo biến và hằng để tại đây
CONTINUE:
MAIN PROC
VD
;Các lệnh của chương trình chính để tại đây
;Trở về DOS
INT 20H
MAIN ENDP
;Các chương trình con (nếu có) khai báo ở đây
END START
Chương 3: Lập trình Assembly
I
3
Khung Chương trình Assembly
II
Biên soạn và dịch chương trình Assembly
III
3
Thực hiện cấu trúc điều khiển chương trình bằng assembly
IV
Các lệnh logic, dịch, quay, ngăn xếp và các thủ tục
IV
Các lệnh nhân và chia
IV
Mảng
IV
Các lệnh thao tác với chuỗi
II. Biên soạn và dịch chương trình Assembly
.
II. Biên soạn và dịch chương trình Assembly
.
Trở về thư mục gôc C:\
II. Biên soạn và dịch chương trình Assembly
.
Truy nhập vào thư mục MASM
II. Biên soạn và dịch chương trình Assembly
.
Dịch chương trình sang mã máy
II. Biên soạn và dịch chương trình Assembly
.
Liên kết các tệp đuôi .OBJ để tạo thành một
tệp chương trình chạy được đuôi .EXE
II. Biên soạn và dịch chương trình Assembly
.
Chạy chương trình
Chương 3: Lập trình Assembly
I
3
Khung Chương trình Assembly
II
Biên soạn và dịch chương trình Assembly
III
3
Thực hiện cấu trúc điều khiển chương trình bằng assembly
IV
Các lệnh logic, dịch, quay, ngăn xếp và các thủ tục
IV
Các lệnh nhân và chia
IV
Mảng
IV
Các lệnh thao tác với chuỗi
III. Thực hiện các cấu trúc điều khiển chương trình
bằng assembly
A. Lệnh JMP: Lệnh nhảy không điều kiện.
Cú pháp
JMP Nhãn
=> Chuyển CS:IP tới vị trí được xác định bởi Nhãn
B. Các lệnh nhảy có điều kiện
Có ba loại nhảy có điều kiện:
<1> Các lệnh nhảy không dấu dùng với các số không
dấu
<2> Các lệnh nhảy có dấu được dùng khi kết quả trả về
là các số có dấu
<3> Các lệnh nhảy điều kiện đơn: điều kiện phụ thuộc
vào một cờ riêng biệt.
III. Thực hiện các cấu trúc điều khiển chương trình
bằng assembly
1.Các lệnh nhảy không dấu
JA/ JNBE
Jump if Above: Nhảy nếu lớn hơn
Jump if Not Below or Equal: Nhảy nếu không thấp hơn
hoặc bằng).
vd: JA NHAN
/ JNBE NHAN
JAE/JNB/JNC
Jump if Above or Equal: Nhảy nếu cao hơn hoặc
bằng
Jump if Not Below: Nhảy nếu không thấp hơn
vd: JAE NHAN
JNB NHAN
JNC NHAN
III. Thực hiện các cấu trúc điều khiển chương trình
bằng assembly
1.Các lệnh nhảy không dấu
JB/JC/JNAE
Jump if Below: Nhảy nếu thấp hơn
Jump if Carry: Nhảy nếu có nhớ
Jump if Not Above or Equal:Nhảy nếu không cao hơn hoặc
bằng)
VD: JB NHAN / JC NHAN
/ JNAE NHAN
JBE/JNA
Jump if Below or Equal: Nhảy nếu thấp hơn hoặc bằng
Jump if Not Above: Nhảy nếu không cao hơn
JBE NHAN
JNA NHAN
III. Thực hiện các cấu trúc điều khiển chương trình
bằng assembly
2. Các lệnh nhảy có dấu
• JG/JNLE : Jump if Greater than/ Jump if Not Less than or
Equal (Nhảy nếu lớn hơn/ Nhảy nếu không bé hơn hoặc bằng)
JG
NHAN
JNLE NHAN
•
JGE/JNL: Jump if Greater than or Equal/ Jump if Not
Less than (Nhảy nếu lớn hơn hoặc bằng/ Nhảy nếu
không nhỏ hơn)
JGE
NHAN
JNL NHAN
III. Thực hiện các cấu trúc điều khiển chương
trình bằng assembly
2. Các lệnh nhảy có dấu
JL/ JNGE: Jump if Less than/ Jump if Not
Greater than or Equal (Nhảy nếu nhỏ hơn/ Nhảy
nếu không lớn hơn hoặc bằng)
JL
NHAN
JNGE NHAN
JLE/JNG: Jump if Less than or Equal/ Jump if
Not Greater than (Nhảy nếu nhỏ hơn hoặc bằng/
Nhảy nếu không lớn hơn)
JLE
NHAN
JNG NHAN
III. Thực hiện các cấu trúc điều khiển chương trình
bằng assembly
3. Các lệnh nhảy điều kiện đơn
JCXZ : Jump if CX Register if Zero (Nhảy nếu
nội dung thanh đếm rỗng)
JCXZ NHAN
JE/JZ: Jump if Equal/ Jump if Zero (Nhảy nếu
bằng nhau/ Nhảy nếu kết quả bằng không)
JE NHAN
JZ NHAN
JC: Jump if Carry ( Nhảy nếu có nhớ)
III. Thực hiện các cấu trúc điều khiển chương trình
bằng assembly
3. Các lệnh nhảy điều kiện đơn
JNC : Jump if Not Carry (Nhảy nếu không nhớ)
JO: Jump if Overflow (Nhảy nếu tràn)
JNO: Jump if Not Overflow (Nhảy nếu không
tràn)
JS:
Jump if Sign (Nhảy nếu dấu âm)
JNS: Jump if Not Sign (Nhảy nếu dấu dương)
Tất cả các lệnh nhảy hoặc nhảy có điều kiện đều
không tác động đến cờ
VD: so sánh lệnh nhảy có dấu và không dấu
Mỗi lệnh nhảy có dấu đều tương ứng với một
lệnh nhảy không dấu:
VD: JG (có dấu),JA(không dấu)
Ví dụ: AX chứa 7FFFh, BX chứa 8000h
Cmp
Ja
AX,BX
TEST
; Không nhảy đến nhãn TEST
Nếu coi AX, BX là các số có dấu thì AX>BX nhưng
sử dụng
Cmp AX,BX
Ja
TEST
; Không nhảy đến nhãn TEST vì Ja là lệnh
nhảy không dấu
III. Thực hiện các cấu trúc điều khiển chương trình
bằng assembly
C: CMP Left, Right
Left: có thể là thanh ghi hoặc ô nhớ (Không được phép là
hằng số)
Right: có thể là thanh ghi hoặc ô nhớ hoặc hằng số.
Các toán hạng của lệnh Cmp không thể cùng là các ô nhớ.
=> Lệnh này so sánh Left và Right bằng cách lấy toán tử Left trừ
đi toán tử Right, kết quả không được lưu lại nhưng các cờ bị
ảnh hưởng. Các toán hạng của lệnh Cmp không thể cùng là các
ô nhớ.
III. Thực hiện các cấu trúc điều khiển chương trình
bằng assembly
D: Các cấu trúc ngôn ngữ bậc cao
Cấu trúc rẽ nhánh IF-THEN
Cấu trúc lựa chọn CASE
Cấu trúc lặp với số lần xác định FOR-DO
Cấu trúc lặp với số lần không xác định
REPEAT-UNTIL và WHILE-DO
=> sử dụng các lệnh nhảy và lệnh lặp của bộ vi
xử lý. Cụ thể như sau:
Cấu trúc rẽ nhánh IF-THEN
Cấu trúc rẽ nhánh IF-THEN
(1) IF <Điều kiện> THEN <Công việc>
(2) IF <Điều kiện> THEN <Công việc 1> ELSE <Công việc 2>
Cấu trúc rẽ nhánh IF-THEN
VD: Viết
đoạn chương trình gán BX |AX|
IF_:
CMP AX,0
JAE ENDIF_
NEG AX
ENDIF_:
MOV BX,AX
VD2: Giả sử AL và BL chứa mã ASCII của ký tự. Kiểm
tra nếu AL<=BL thì hiện ra màn hình ký tự trong AL,
còn không thì hiện ký tự trong BL.
Cấu trúc lựa chon CASE
Cấu trúc lựa chon CASE
CASE <Biểu thức> OF
Giá_trị_1: Công_việc_1
Giá_trị_2: Công_việc_2
Giá_trị_N: Công_việc_N
END_CASE
III. Thực hiện các cấu trúc điều khiển chương trình
bằng assembly
B1: Nếu AX chứa số âm thì đưa -1 vào BX, nếu AX chứa 0 thì
đưa 0 vào BX, nếu AX chứa số dương thì đưa 1 vào BX.
Cấu trúc lặp với số lần xác định FOR-DO
FOR <Số lần lặp> DO
<Công việc>
Đưa số lần lặp
vào bộ đếm
ENDFOR
Công việc
Giảm bộ đếm đi
1
Sai
Bộ đếm = 0?
Đúng
Cấu trúc lặp với số lần xác định FOR-DO
VD: Hiện thị một dòng 80 ký tự ‘$’
FOR_:
MOV CX,80
MOV AH,2
MOV DL,’$’
INT 21H
LOOP FOR_
ENDFOR_:
Cx=80
Công việc
Cx=cx-1
Sai
cx = 0?
Đúng
Cấu trúc lặp với số lần xác định FOR-DO
Chú ý: Sử dụng lệnh nhảy JCXZ để tránh vòng lặp không kết
thúc được
MOV CX,80
MOV AH,2
JCNZ ENDFOR_
FOR_:
MOV DL,’$’
INT 21H
LOOP FOR_
ENDFOR_:
Cấu trúc lặp với số lần không xác định
Kiểm tra điều kiện trước
Pascal
Assembly
WHILE <Điều kiện>
DO
<Công việc>
WHILE <Điều kiện>
<Công việc>
ENDWHILE
BT: Đếm số kí tự được đọc vào từ bàn
phím khi nào gặp CR thì thôi
Cấu trúc lặp với số lần không xác định
Kiểm tra
điều kiện
sau
REPEAT
<Công
việc>
UNTIL <Điều kiện>
BT: Đếm số kí tự được đọc vào từ
bàn phím khi nào gặp CR thì thôi
Chương 3: Lập trình Assembly
I
3
Khung Chương trình Assembly
II
Biên soạn và dịch chương trình Assembly
III
3
Thực hiện cấu trúc điều khiển chương trình bằng assembly
IV
Các lệnh logic, dịch, quay, ngăn xếp và các thủ tục
IV
Các lệnh nhân và chia
IV
Mảng
IV
Các lệnh thao tác với chuỗi
IV. CÁC LỆNH LOGIC, DỊCH VÀ QUAY. NGĂN
XẾP VÀ CÁC THỦ TỤC
A. Các lệnh logic
Các lệnh
logic
AND
AND Đích, Nguồn
Đích Đích AND Nguồn
Đổi mã ASCII của một số thành số thập phân tương ứng
• Khi đọc 1 kí tự từ bàn phím, AL chứa mã ASCII của kí tự
đó.
• Ví dụ khi ấn phím “5”, AL chứa 35h thay cho 5. Để nhận
được 5 trong thanh ghi AL ta có thể làm như sau:
SUB AL,30h
Dùng AND để xoá nửa byte cao của AL
AND AL,0Fh
AND Đích, Nguồn
AND
Đổi chữ thường thành chữ hoa
•“a” đến “z” :61h đến 7Ah,
•“A” dến “Z” : 41h đến 5Ah.
• Nếu DL chứa mã ASCII của 1 chữ thường ta có thể đổi ra chữ
hoa bằng cách thực hiện lệnh:
SUB DL,20h
AND DL,0DFh
Kí tự
Mã ASCII
Kí tự
Mã ASCII
a
0110 0001
A
0100 0001
b
0110 0010
B
0100 0010
c
0110 0011
C
0100 0010
..
..
..
..
z
0111 1010
Z
0101 1010
Chương II: Bộ vi xử lý Intel 8088
OR, XOR, NOT, TEST
OR Đích, Nguồn: Đích Đích OR Nguồn
XOR Đích, Nguồn: - Đích Đích XOR Nguồn
- Xóa thanh ghi
NOT Đích:
- Đích NOT Đích
- Lấy số bù 1 của toán hạng đích
TEST Đích, Nguồn: Đích AND Nguồn
• Toán hạng Đích không bị thay đổi.
• Mục đích của lệnh TEST là thiết lập các cờ
• Các cờ bị tác động:
SF, ZF, PF phản ánh kết quả
AF không xác định
CF,OF=0
Chương II: Bộ vi xử lý Intel 8088
B. Nhóm lệnh dịch và quay bit
Lệnh dịch bit
Lệnh quay bit
SHL Đích,CL
ROL Đích,CL
SAL Đích,CL
RCL Đích,CL
SHR Đích,CL
ROR Đích,CL
SAR Đích,CL
RCR Đích,CL
Lệnh dịch trái
SHL Đích,CL
SAL tương tự SHL
• Trong đó CL chứa N.
• N phép dịch trái đơn được thực hiện.
• Giá trị CL vẫn giữ nguyên không thay đổi khi
thực hiện xong lệnh
• Sau mỗi lẫn dịch trái thì giá trị 0 được thêm vào
vị trí bên phải nhất của toán hạng đích. Bit MSB
được đưa vào CF
Lệnh dịch trái
Các cờ bị tác động:
+ SF, PF, ZF phản ánh kết quả, PF chỉ có ý nghĩa khi kết quả là 8
bit
+ CF chứa bit cuối cùng được dịch ra khỏi toán hạng
+ OF = 1 nếu kết quả bị thay đổi dấu trong lần dịch chuyển cuối
cùng
Lệnh dịch trái
VD1: DH chứa 8Ah, CL chứa 3. Cho biết giá trị DH, CF
sau khi lệnh SHL DH,CL được thực hiện
Giá trị nhị phân
Lần 1
Lần 2
Lần 3
Lệnh dịch trái
Ví dụ 2:
AL chứa 5d =0000 0101b.
Dịch trái 1 bit: 00001010=10d nghĩa là
bằng 2 giá trị của nó.
Tiếp tục dịch trái ta nhận được
00010100b=20d
Lệnh dịch phải
- SHR Đích,CL
SAR tương tự SHL
• Trong đó CL chứa N.
• N phép dịch phải đơn được thực hiện.
• Giá trị CL vẫn giữ nguyên không thay đổi khi
thực hiện xong lệnh
• Sau mỗi lẫn dịch phải thì giá trị 0 được thêm
vào vị trí bên phải nhất của toán hạng đích. Bit
MSB được đưa vào CF
Lệnh dịch trái phải
Các cờ bị tác động:
+ SF, PF, ZF phản ánh kết quả, PF chỉ có ý nghĩa khi kết quả là 8
bit
+ CF chứa bit cuối cùng được dịch ra khỏi toán hạng
+ OF = 1 nếu kết quả bị thay đổi dấu trong lần dịch chuyển cuối
cùng
Lệnh dịch phải
VD1: DH chứa 8Ah, CL chứa 3. Cho biết giá trị DH, CF
sau khi lệnh SHR DH,CL được thực hiện
Giá trị nhị phân
Lần 1
Lần 2
Lần 3
Lệnh quay trái ROL
- ROL Đích,1 hoặc ROL Đích,CL:
• Lệnh ROL (Rotate left) dịch các bit sang bên trái.
• Bit msb được dịch vào bit bên phải nhất, đồng thời được
đưa vào cờ CF, bit lsm theo sau bit msb.
Lệnh quay trái có nhớ RCL
- RCL Đích,1 hoặc RCL Đích,CL:
• Lệnh quay trái qua cờ nhớ - Rotate Carry Lef
• Dịch các bit của toán hạng đích sang trái. Bit msb được
đặt vào cờ CF, giá trị cũ của CF được đưa vào bit phải
nhất của toán hạng đích
Lệnh quay trái ROL
- ROR Đích,1 hoặc ROR Đích,CL:
• Lệnh ROR (Rotate right) dịch các bit sang bên phải.
• Bit bên phải nhất được dịch vào và bit msb đồng thời
cũng được đưa vào cờ C.
Lệnh quay trái có nhớ RCL
- RCR Đích,1 hoặc RCR Đích,CL:
• Lệnh quay phải qua cờ nhớ - Rotate Carry Lef
• Dịch các bit của toán hạng đích sang phải. Bit lsb
được đặt vào cờ CF, giá trị cũ của CF được đưa vào
bit trái nhất của toán hạng đích
C. Vào ra với số nhị phân và số hex
Nhập các số nhị phân
Nhập các số nhị phân từ bàn phím kết thúc bằng cách
nhấn phím Enter.
Các số nhận được ở dạng chuỗi các chữ số 0 và 1.
Mỗi kí tự được nhập phải đổi ra giá trị của từng bit
rồi kết hợp các bit vào trong thanh ghi, kết qủa lưu
trong BX
Thuật toán nhập số nhị phân
Xoá BX
;BX lưu kết quả
Nhập một kí tự ;’0’ hoặc ‘1’
While kí tự <> CR Do
Đổi kí tự ra giá trị số nhị phân
Dịch trái BX
Chèn giá trị nhận được vào bit lsb của BX
Nhập kí tự
End_while
Ví dụ: Biểu diễn với việc nhập 101
Xoá BX
BX=0000 0000 0000 0000
Nhập vào kí tự ‘1’ đổi nó thành 1
Dịch trái BX
BX=0000 0000 0000 0000
Chèn giá trị nhị phân nhận được vào bit lsb của BX
BX=0000 0000 0000 0001
Nhập kí tự ‘0’ đổi nó thành 0
Dịch trái BX
BX=0000 0000 0000 0010
Chèn giá trị nhị phân nhận được vào bit lsb của BX
BX=0000 0000 0000 0010
Nhập kí tự ‘1’ đổi nó thanh 1
Dịch trái BX
BX=0000 0000 0000 0100
Chèn giá trị nhị phân nhận được vào bit lsb của BX
BX=0000 0000 0000 0101
BX chứa 101B
Thuật toán hiện số nhị phân
For 16 lần Do
Quay trái BX ; BX chứa giá trị cần đưa ra, bit msb
đưa vào CF
If CF=1 Then
Đưa ra ‘1’
Else
Đưa ra ‘0’
End_if
End_for
Ví dụ: Biểu diễn với việc nhập 101
Học sinh tự làm
D. Nhập và hiện số hex
Nhập số HEX
Nhập số hex bao gồm các chữ số ‘0’ đến ‘9’
và các chữ cái từ ‘A’ đến ‘Z’ kết thúc bằng kí
tự CR.
Giả thiết
Chỉ sử dụng các chữ hoa
Chỉ nhập vào tối đa 4 chữ số hex
Thuật toán nhập số hex
Xoá BX ;BX chứa giá trị nhập vào
Nhập kí tự hex
While kí tự <> CR Do
Đổi kí tự ra số nhị phân
Dịch trái BX 4 lần
Chèn giá trị mới vào 4 bit của BX
Nhập kí tự
End_While
Thuật toán hiện số hex
BX chứa số 16 bit bằng giá trị của số hex 4 chữ số. Để đưa ra
nội dung của BX, bắt đầu từ bên trái, lấy ra từng nhóm bit của
mỗi chữ số đổi nó thành chữ số hex tương ứng sau đó đưa ra
For 4 lần Do
Chuyển BH vào DL
Dịch DL về bên phải 4 lần
If DL<10 then
Đổi thành một trong các kí tự “0”.. ”9”
Else
Đổi thành một trong các chữ cái “A” … “F”
Đưa kí tự ra
Quay BX 4 lần về bên trái
End_For
D. Ngăn xếp
Đoạn ngăn xếp của chương trình dùng để lưu
trữ tạm thời các dữ liệu và địa chỉ.
Ngăn xếp (LIFO) là cấu trúc dữ liệu một
chiều, các phần tử được cất vào sau, lấy ra
trước (Last In First Out)
Mỗi chương trình phải dành ra một khối bộ
nhớ để làm ngăn xếp. Chúng ta thực hiện điều
này khi khai báo đoạn ngăn xếp
.STACK 100h
D. Ngăn xếp
PUSH Nguồn
Cất nội dung của một thanh ghi hoặc một ô nhớ 16 bit
vào ngăn xếp
Ví dụ: PUSH AX
Lệnh PUSH thực hiện các công việc sau:
+ Giảm SP đi 2
+ Một bản sao của nội dung của toán hạng nguồn
được chuyển vào địa chỉ xác định bởi SS:SP. Toán
hạng nguồn không bị thay đổi.
Ban đầu, SP chứa địa chỉ offset của ô nhớ theo sau
đoạn ngăn xếp. Lệnh PUSH đầu tiên giảm SP đi 2
làm cho con trỏ chỉ đến từ cuối cùng của trong đoạn
ngăn xếp. Bởi vì lện PUSH làm giảm SP
D. Ngăn xếp
• Ban đầu, SP chứa địa chỉ offset của ô nhớ theo sau đoạn
ngăn xếp. SP được khởi tạo bằng 100h
• Lệnh PUSH đầu tiên giảm SP đi 2 làm cho con trỏ chỉ đến
từ cuối cùng trong đoạn ngăn xếp.
D. Ngăn xếp
POP Đích: Lệnh POP được dùng để lấy ra phần tử
đỉnh ngăn xếp, trong đó phần tử đích là một thanh ghi
16 bit (trừ IP) hoặc là 1 từ nhớ.
Ví dụ: POP BX
Lệnh POP thực hiện các công việc sau:
+ Nội dung của ô nhớ SS:SP (đỉnh ngăn xếp)
được chuyển tới toán tử đích
+ SP tăng lên 2
POPF: Lệnh POPF đưa vào thanh ghi cờ nội dung
của đỉnh ngăn xếp
Chương II: Bộ vi xử lý Intel 8088
D. Ngăn xếp
D. Ngăn xếp
Chú ý:
- Các lệnh PUSH, PUSHF, POP, POPF không ảnh
hưởng đến cờ
- Các lệnh PUSH và POP chỉ thao tác với các WORD,
vậy nên nếu dùng với các byte, các số liệu trực tiếp là
không hợp lê.
- Cất một số liệu trực tiếp là được phép đối với các bộ
vi xử lý 80186, 80486
PUSH DL ; Không hợp lệ
PUSH 2 ; Không hợp lệ
E. Thủ tục
Khai báo thủ tục
Name PROC type
; thân thủ tục
...
RET
Name ENDP
Trong đó: Name là tên của thủ tục định nghĩa bởi
người sử dụng
Type toán hạng tuỳ chọn có thể là NEAR hay FAR
(NEAR được ngầm định nếu bỏ qua type). NEAR có
nghĩa là dòng lệnh gọi thủ tục ở cùng đoạn với thủ tục
đó, ngược lại FAR có nghĩa là dòng lệnh gọi ở trong
một đoạn khác
E. Thủ tục
Gọi CTC: CALL Nhãn
Lệnh Call thực hiện các công việc sau đây:
1. Địa chỉ trở về của chương trình gọi được cất
vào ngăn xếp. Địa chỉ này là offset của lệnh
ngay sau dòng Call, dạng segment:offset của
nó tại thời điểm thi hành lệnh Call chứa trong
CS:IP
2. IP được gán bằng địa chỉ offset lệnh đầu tiên
của thủ tục. Thao tác này chuyển điều khiển
cho thủ tục
E. Thủ tục
Trở về từ CTC: RET
Để trở về từ một thủ tục ta dùng lệnh:
RET
pop_value
Tham số nguyên pop_value là tuỳ chọn. Trong
một thủ tục NEAR, lệnh RET đưa giá trị ở
đỉnh ngăn xếp vào IP. Nếu pop_value xác định
bằng N thì N sẽ được cộng vào SP. Điều này
tương đương với việc lấy N byte khỏi ngăn
xếp CS:IP lúc này chứa địa chỉ dạng
segment:offset và điều khiển được trả lại cho
chương trình gọi.