1640
Chia sẻ bởi Phạm Văn Mùi |
Ngày 01/05/2019 |
102
Chia sẻ tài liệu: 1640 thuộc Power Point
Nội dung tài liệu:
Dùng trình soạn thảo văn bản để soạn chương trình nguồn:
Gồm tất cả các chương trình soạn thảo:
- Có thể của Pascal, C, Notepad, Bked, v. . V. .
- hoặc Tại dấu nhắc DOS gõ: Edit
Sử dụng bản Turbo Assembly (TASM) để biên dịch và thực hiện chương trình.
TASM. EXE để dịch chương trình nguồn.
Ví dụ: C:>Tasm hello.asm - Dùng trình hợp dịch TASM (Enter)
hello.obj
- Dùng trình liên kết TLINK. EXE để liên kết chương trình với các thư viện.
Ví dụ: C:>Tlink hello.obj (Enter)
hello.exe
- Thực thi chương trình
Kết quả: Hello world
Ví dụ 1: In dòng chữ “Hello Assembler” ra màn hình.
.model small
.stack 100h
.data
msg db "Hello Assembler$"
.code
start:
mov ax,@data ;Dua dia chi du lieu vao ax
mov ds,ax ;Cho DS tro vao
mov ah,09h ;Ham nay in chuoi do dx tro toi
mov dx, offset msg
int 21h
mov ax,4c00h
int 21
end start
Khung của một chương trình Hợp ngữ
+ Chương trình mã máy trong bộ nhớ bao gồm các vùng nhớ khác nhau, gồm:
Vùng chứa mã lệnh
Vùng chứa dữ liệu
Vùng ngăn xếp phục vụ hoạt động của chương trình.
+ Chương trình viết bằng Assembly có cấu trúc tương tự, được trình biên dịch Assembler dịch ra ngôn ngữ máy như trên.
Các khối của chương trình:
Khai báo quy mô bộ nhớ:
Xác định kích thước bộ nhớ dành cho đoạn mã và đoạn dữ liệu trong một chương trình, nhờ hướng dẫn chương trình dịch như sau:
.model Kiểu_kích_thước_bộ nhớ
Khai báo đoạn ngăn xếp:
- Khai báo một vùng nhớ có kích thước đủ lớn để phục vụ hoạt động của chương trình khi có chương trình con.
. Stack kích_thước
- Kích thước sẽ quy định số byte cho ngăn xếp, thông thường từ 100-256 byte là đủ. Nếu không chỉ định rõ, chương trình mặc định là 1KB (đây là kích thước quá lớn đối với chương trình của chúng ta)
Khai báo đoạn dữ liệu
- Chứa toàn bộ các định nghĩa cho các biến của chương trình. Các hằng cũng nên định nghĩa ở đây để đảm bảo tính hệ thống của chương trình.
Ví dụ:
. Data
msg DB ‘hello !$’
CR DB 13
LF EQU 10
Khai báo đoạn mã:
Chứa mã lệnh của chương trình
. code
Các dòng lệnh được tổ chức hợp lý, đúng ngữ pháp dưới dạng một chương trình chính (CTC). Trong chương trình chính có thể có các chương trình con (ctc) được gọi bằng lệnh CALL.
Ví dụ:
Tên_CTC proc
; Các lệnh của thân chương trình chính
CALL Tên_ctc ; gọi chương trình con
Tên_CTC endp
Tên_ctc Proc
; các lệnh của thân chương trình con
RET
Tên_ctc endp
Hai dạng chính của một chương trình hợp ngữ:
* Khung chương trình hợp ngữ để dịch ra dạng *. Exe
.model small
.stack 100h
.data
; Các định nghĩa cho các biến và hằng để tại đây
.code
Main proc
;khởi đầu cho đoạn DS
mov ax,@data ;Dua dia chi du lieu vao ax
mov ds,ax ;Cho DS tro vao
;Các lệnh của chương trình chính để tại đây
;Trở về DOS dùng hàm 4Ch của ngắt INT 21h
mov ax,4c00h
int 21h
Main endp
; Các chương trình con nếu có để tại đây
Đặc điểm:
- Khi một chương trình *. Exe được nạp vào bộ nhớ . DOS sẽ tạo ra một mảng gồm 256byte gọi là đoạn mào đầu chương trình(PSP) để chứa các thông tin liên quan đến chương trình. DOS cũng đưa các thông số liên quan đến chương trình vào đoạn DS, ES. Cho nên để chương trình chạy đúng phải khởi đầu cho các thanh ghi ES, và DS.
Khung chương trình hợp ngữ để dịch ra dạng *.com
- Ta thấy chương trình *. Exe có đầy đủ các đoạn. Trong các chương trình *.com thì các đoạn mã, đoạn dữ liệu, đoạn stack thành một đoạn duy nhất là đoạn mã.
Tiết kiệm thời gian và bộ nhớ khi chạy chương trình, ngoài ra còn tiết kiệm không gian lưu trữ trên ổ đĩa.
Ví dụ:
.Model tiny
.Code
ORG 100h; gán địa chi bắt đầu cho chương trình tại 100h
start: jmp continue
; các định nghĩa cho các biến của chương trình chính để tại đây
continue:
main proc
;Các lệnh của chương trình chính để tại đây
INT 20h ;trở về DOS
main endp
; các chương trình con nếu có để tại đây
end start
Đoạn đầu của chương trình(PSP)
Jmp continue
Dữ liệu nằm tại đây
Continue:
(chiều diễn tiến của mã và dữ liệu)
(chiều diễn tiến của ngăn xếp)
IP
SP
100h
000h
FFFEh
Địa chỉ lệch
Hình 4.1: Tệp chương trình *.com trong bộ nhớ
Bộ ký tự của hợp ngữ:
Bộ kỹ tự: - Các chữ cái
- các chữ số
- các ký tự đặc biệt
Từ vựng:
- Từ khoá (keyword): là các từ dành riêng của hợp ngữ, như:
- tên các thanh ghi
- tên các lệnh gợi nhớ
- Tên các toán tử
(các từ khoá có thể viết bằng chữ hoa, hoặc chữ thường)
- Tên (symbol, name): Một dãy các ký tự biểu thị tên biến, tên hằng, tên ctc, tên đoạn. . .
Quy tắc:
- Ký tự đầu của một tên không được là số.
- Dấu chấm không được dùng trong một tên, chỉ dùng làm ký tự đầu của nhãn
Dữ liệu cho chương trình:
- hệ 2
-hệ 16
- hệ 10
- các ký tự
Khi cung cấp dữ liệu ở hệ nào thì phải kèm đuôi hệ đón (trừ hệ 10)
Với hệ 16 nếu số đó bắt đầu bằng a,b,c,d,e,f hoặc A,B...F thì thêm 0 vào trước để chương trình dịch không nhầm là nhãn.
Vi dụ: 0011B ;Số hệ 2
1234 ;Số hệ 10
0ABBAh ; Số hệ 16
1EF1H ;Số hệ 16
Khi dữ liệu là ký tự hoặc chuỗi ký tự thì chúng được đóng trong cặp dấu trích dẫn đơn hoặc kép. Chương trình sẽ dịch ra mã ASCII. Vì vậy ta có thề cung cấp mã ASCII thay vì ký tự. Ví dụ “0” thay bằng 30h
Biến và hằng
Một biến phải được định nghĩa là kiểu byte hay kiểu từ, và được chương trình gán cho một địa chỉ nhất định trong bộ nhớ.
DB (define byte) ; định nghĩa biến kiểu byte
DW
DD
* Biến byte
Chiếm 1 byte trong bộ nhớ:
Tên DB giá_trị_khởi_đầu
Ví dụ: B1 DB 4
Nếu không muốn khởi đầu giá trị thì thay giá trị khởi đầu bằng ?
Trường hợp đặc biệt của biến kiểu byte là biến ký tự:
Ví dụ: C1 DB ‘$’
C2 DB 34 ;thay bằng mã ASCII
Biến từ
Tên DW giá_trị_khởi_đầu
Ví dụ: W1 DW 40
Tương tự có thể dùng dấu ?
Biến mảng
-Một dãy các phần tử liên tiếp cùng loại byte, hoặc từ
Ví dụ: M1 DB 4,5,6,7,8,9
Phần tử đầu có địa chỉ ứng với M1, phần tử tiếp theo có địa chỉ là M1+1.
Khi khai báo có cùng giá trị khởi đầu, ta khai báo:
M2 DB 100 DUP(0)
M3 DB 100 DUP(?)
Biến kiểu xâu ký tự:
Là một trường hợp đặc biệt của biến mảng:
Ví dụ: STR1 DB ‘string’
STR1 DB 73h, 74h, 72h, 69h, 6Eh, 67h
STR1 DB 73h, 74h, ‘r’, ‘i’, 6Eh, 67h
Hằng có tên
Các hằng được gán tên làm cho chương trình hợp ngữ dễ đọc hơn
Hằng có thể là kiểu ký tự, hoặc kiểu số
Việc gán được thực hiện bằng lệnh giả (EQU:EQUate):
CR EQU 0Dh ;CR là Carriage Reture: Về đầu dòng
LF EQU 0Ah ;LF là Line Feed: Thêm dòng mới
Hằng cũng có thể là chuỗi ký tự.
CHAO EQU ‘HELLO!’
Ta có thể dùng hằng này để định nghĩa một biến mảng khác:
MSG DB CHAO,’$’
Chú ý: Lệnh giả (EQU) không dành chỗ bộ nhớ cho tên của hằng nên ta có thể đặt nó khá tự do tại những chỗ thích hợp trong chương trình. Tuy nhiên, thực tế người ta thường đặt chúng trong đoạn dữ liệu.
* Cú pháp tổng quát của một dòng lệnh: Gồm các trường sau
Tên Mã_lênh Các_toán_hạng Chú giải
Trường Tên:
Chứa các nhãn, tên biến, hoặc thủ tục
Các tên và nhãn này được chương trình dịch gán bằng địa chỉ cụ thể của ô nhớ.
Các tên và nhãn có độ dài tối đa là 31 ký tự, không chứa dấu cách, không bắt đầu bằng số. Các ký tự đặc biệt có thể dùng là ? . @ _ $ % (dấu ‘.’ phải được đặt ở vị trí đầu tiên của tên). Nói chung cứ đặt một tên bình thường và có ý nghĩa sẽ ít khi bị sai.
Một nhãn thường kết thúc bằng dấu hai chấm:
Trường mã lệnh
Có các lệnh thật hoặc lệnh giả.
Lệnh thật: Chứa các mã lệnh gợi nhớ. Được chương trình dịch dịch ra mã máy
Lệnh giả: nằm trong các hướng dẫn chương trình dịch. Không được dịch ra mã máy.
Trường toán hạng:
Với lệnh thật: Trường này chứa các toán hạng của lệnh. Tuỳ theo từng loại lệnh mà ta có thể có 0,1,2 toán hạng trong một lệnh. Với 1 toán hạng thì toán hạng đó có thể là toán hạng đích hoặc gốc. Với 2 toán hạng thì một toán hạng là đích còn toán hạng còn lại là gốc.
* Trường chú giải:
Lời giải thích phải được bắt đầu bằng dấu (;). Dành cho người lập trình ghi các lời giải thích cho các lệnh với mục đích giúp cho người đọc chương trình dễ hiểu các thao tác của chương trình hơn.
Ví dụ1:
TIEP: MOV AH, [BX] [SI] ;Nạp vào AH nội dung ô nhớ có địa chỉ DS:(BX+SI)
Tên Mlệnh Thđích, gốc Chú giải
Ví dụ2: Dòng lệnh với các hướng dẫn chương trình dịch
MAIN PROC ;Bắt đầu một thủ tục tên là MAIN
Tên Lệnh giả Chú giải
MAIN ENDP ;Kết thúc một thủ tục tên là MAIN
Tên Lệnh giả Chú giải
Các cấu trúc lập trình cơ bản thực hiện bằng hợp ngữ
Cấu trúc tuần tự
Cấu trúc lựa chọn
-Cấu trúc lặp
Cấu trúc tuần tự
Các lệnh được sắp xếp tuần tự, lệnh nọ tiếp theo lệnh kia. Sau khi thực hiện song lệnh cuối cùng của cấu trúc thì công việc làm cũng phải hoàn tất.
Ngữ pháp:
lênh 1
lênh 2
:
lênh n
Ví dụ: Các thanh ghi CX, BX chứa các giá trị của các biến c và b. Hãy tính giá trị của biểu thức a = 2*(c + b) và chứa kết quả trong thanh ghi AX.
XOR AX, AX ; đưa tổng về 0
ADD AX, BX ;cộng thêm vào AX giá trị b
ADD AX, CX ;cộng thêm vào AX giá trị c
SHL AX, 1 ;Nhân đôi kết quả trong AX
Cấu lựa chọn
- Cấu trúc IF . . . THEN Cấu trúc IF . . . THEN. . .ELSE
Ví dụ: Gán cho BX giá trị tuyệt đối của AX Ví dụ: Gán cho CL giá trị bít dấu của AX
CMP AX, 0 ;So sánh AX với 0 OR AX, AX ; Nếu AX >= 0 thì kết quả >=0
JNL GAN ;Nhảy nếu không bé hơn 0 ;Nếu AX < 0 thì kết quả <0
NEG AX ; AX < 0, đảo dấu JNS DG ;Nếu kết quả dương
GAN: MOV BX, AX ; BX chứa |AX| MOV CL, 1 ;Nếu kết quả âm, dấu = 1
JMP RA ;Kết thúc
DG: XOR CL, CL ; Kết quả dương CL=0
RA:
Điều kiện
Công việc
Điều kiện
Công việc 2
Công việc1
Sai
Sai
Đúng
Đúng
- Cấu trúc CASE
Ví dụ: Dùng AX để biểu hiện các giá trị khác nhau của AX, theo quy tắc:
Nếu AX < 0, = 0, > 0 thì tương ứng CX = -1 , 0 , 1
CMP AX, 0 ;Kiểm tra dấu của AX
JL AM ;Nếu AX <0
JE KHONG ;Nếu AX =0
JG DUONG ;Nếu AX >0
AM: MOV CX, -1
JMP RA
KHONG: MOV CX, 1
JMP RA
DUONG: XOR CX, CX
RA:
Biểu thức
Công việc 1
Công việc 2
Công việc n
Giá trị 1
Giá trị 2
Giá trị n
Cấu trúc FOR – DO
Cú pháp: FOR sốlầnlặp DO côngviệc
- Công việc được lặp đi lặp lại một số lần nhất định (Sốlầnlặp)
- Trong Assembly dùng lệnh LOOP để lặp CX lần (CX được nạp vào sốlầnlặp).
Ví dụ: Hiển thị một dòng ký tự ‘$’ trên màn hình.
MOV CX, 80 ;Số lần hiển thị đặt trong CX
MOV AH, 2 ;AH chứa số hiệu của hàm hiển thị
MOV DL, ‘$’ ;DL chứa ký tự cần hiển thị
HIEN: INT 21h ;Hiển thị, CX tự động giảm đi 1
LOOP HIEN ; Hiển thị cả một dòng
RA:
Khởi đầu Bôđếm
Cấu trúc FOR – DO
Cú pháp: FOR sốlầnlặp DO côngviệc
- Công việc được lặp đi lặp lại một số lần nhất định (Sốlầnlặp)
- Trong Assembly dùng lệnh LOOP để lặp CX lần (CX được nạp vào sốlầnlặp).
Ví dụ: Hiển thị một dòng ký tự ‘$’ trên màn hình.
MOV CX, 80 ;Số lần hiển thị đặt trong CX
MOV AH, 2 ;AH chứa số hiệu của hàm hiển thị
MOV DL, ‘$’ ;DL chứa ký tự cần hiển thị
HIEN: INT 21h ;Hiển thị, CX tự động giảm đi 1
LOOP HIEN ; Hiển thị cả một dòng
RA:
Công việc
Giảm Bộđếm đi 1
Bộđếm =0?
Đúng
Sai
Cấu trúc WHILE – DO Cấu trúc REPEAT – UNTIL
Ví dụ: Đếm số ký tự đọc được từ bàn phím, khi gặp ký tự CR thì thôi.
XOR CX, CX ;Tổng số các ký tự XOR CX, CX
MOV AH, 1 ;Hàm đọc ký tự từ bàn phím TIEP:
TIEP: INT 21h ; đọc một ký tự, AL chứa mã ký tự đó INC CX
CMP AL, 13 ; So sánh với Enter MOV AH, 1
JE RA ; đúng thì thoát INT 21h
INC CX ;sai, tăng tổng lên 1 CMP AL, 13
JMP TIEP ; Đọc tiếp JNE TIEP
RA: RA
Các toán tử dùng trong Assembler
Các toán tử số học: +, -, *, /, MOD, SHL, SHR,
Các toán tử logic: AND, OR, NOT, XOR
Các toán tử quan hệ: EQ, NE, LT, LE, GT, GE
Các toán tử cung cấp thông tin về biến và nhãn:
SEG Biểu_thức: Cho địa chỉ đoạn của Biểu_thức,
Biểu_thức có thể là một biến, nhãn, tên Segment, hay các toán hạng bộ nhớ.
OFFSET Biểu_thức: Cho địa chỉ lệch của Biểu_thức,
- Biểu_thức có thể là một biến, nhãn hay các toán hạng bộ nhớ trực tiếp khác.
Ví dụ: Chuyển segment và offset của biến Table vào cặp thanh ghi DS:DX
Table DB ?
MOV AX, SEG Table
MOV DS, AX
MOV DX, OFFSET Table
[ ]: Toán tử chỉ số thường dùng chung với toán hạng bộ nhớ.
Ví dụ: Var DB 3Ch
MOV AL, [Var]
: segment : Expression: Toán tử này quy định cách đánh địa chỉ của một biến hay một nhãn đối với đoạn segment được chỉ. Toán tử này thường dùng chung với toán tử [ ]
Ví dụ: ES:[DI]
TYPE Biểu_thức: Trả về kích thước của Biểu_thức (tính theo số byte)
DB: 1
DW: 2
DD: 4
LENGTH var: Số đơn vị mà biến var được cung cấp
SIZE var: Cho số byte mà biến var được cung cấp
Ví dụ: var DW 50 DUP(0)
Thì LENGTH var = 50
SIZE var = 100
PTR
HIGH
LOW
: segment : Expression: Toán tử này quy định cách đánh địa chỉ của một biến hay một nhãn đối với đoạn segment được chỉ. Toán tử này thường dùng chung với toán tử [ ]
Ví dụ: ES:[DI]
TYPE Biểu_thức: Trả về kích thước của Biểu_thức (tính theo số byte)
DB: 1
DW: 2
DD: 4
LENGTH var: Số đơn vị mà biến var được cung cấp
SIZE var: Cho số byte mà biến var được cung cấp
Ví dụ: var DW 50 DUP(0)
Thì LENGTH var = 50
SIZE var = 100
PTR
HIGH
LOW
Macro
Là một dãy các câu lệnh của Assembler, mà nó có thể xuất hiện nhiều lần trong một chương trình. Giống như chương trình con. Mỗi Macro có một tên riêng.
Khi một Macro được định nghĩa, thì trong chương trình thay vì viết một dãy các câu lệnh đã được định nghĩa trong Macro, ta chỉ cần viết tên của Macro đó.
Cách định nghĩa một Macro
Tên MACRO dãy_các_tham_số
Phần thân
ENDM
Phần đầu: - Dùng để khai báo một Macro
- dãy_các_tham_số được cách nhau bởi dấu phẩy (,)
Phần thân: Gồm tập hợp các câu lệnh Assembler mà macro cần định nghĩa.
Phần cuối: Là chỉ dẫn ENDM. Dùng để đánh dấu điểm kết thúc của Macro.
Ví dụ: Xuất hai ký tự ‘A’, ‘B’ ra màn hình.
Nếu không sử dụng chương trình con hay Macro. Ta có thể viết chương trình như sau:
MOV DL, ‘A’
MOV AH, 02H
INT 21H
MOV DL, ‘B’
MOV AH, 02H
INT 21H
Nếu sử dụng chương trình con Out_Char
Out_Char PROC
MOV AH, 02H
INT 21H
Out_Char ENDP
Ta có thể viết lại chương trình trên như sau:
MOV DL, ‘A’
Out_Char
MOV DL, ‘A’
Out_Char
Nếu sử dụng Macro
@Out_Char MACRO Char
MOV AH, 02H
MOV DL, Char
INT 21h
ENDM
Ta có thể viết lại chương trình như sau:
Out_Char ‘A’
Out_Char ‘B’
Các chỉ dẫn dùng trong Macro.
Local: Dùng để định nghĩa các ký hiệu, mà các ký hiệu này chỉ được dùng trong Macro đó.
Ví dụ: Xét Macro sau:
Wait MACRO Count
PUSH CX
MOV CX, Count
Next:
LOOP Next
POP CX
ENDM
Một nhãn chỉ có thể được dùng duy nhất một lần trong chương trình. Do đó Macro này chỉ có thể được dùng một lần trong chương trình. Do đó để có thể dùng nhiều lần trong chương trình ta phải sửa lại đoạn chương trình trên như sau:
Wait MACRO Count
LOCAL Next ; Đặt ngay sau phần khai báo tên Macro
PUSH CX
MOV CX, Count
Next:
LOOP Next
POP CX
ENDM
Chỉ dẫn LOCAL dung trong phần thân của Macro để báo cho assembler biết các nhãn được khai báo bởi chỉ dẫn LOCAL được đổi lại thành một tên nhãn mới trong chương trình mỗi khi Macro này được gọi. Tên nhãn mới có dạng ??Number
(Number là một số có giá trị trong khoảng từ 0000h đến FFFFh)
Cách thực thi của Macro trên:
Lần đầu gọi chương trình: ví dụ Wait 1000, thì assembler dịch macro Wait như sau: PUSH AX
MOV CX, 1000
??0000 ‘Next được thay bằng nhãn mới ??0000
LOOP ??0000
POP CX
Lần thứ hai gọi chương trình : Ví dụ Wait 3000, thì assembler dịch macro Wait như sau: PUSH AX
MOV CX, 1000
??0001 ‘Next được thay bằng nhãn mới ??0001
LOOP ??0001
POP CX
EXITM: - Dùng để thoát khỏi một Macro hoặc một khối lặp repeat
- Khi gặp chỉ dẫn này chương trình dịch sẽ chấm dứt Macro trước khi phải xử lý toàn bộ các câu lệnh của Macro.
- Nếu EXITM được dùng trong một macro lồng hoặc một khối lặp repeat lồng vào nhau thì lệnh EXITM chỉ thoát khỏi Macro hay repeat chứa nó.
Các chỉ dẫn điều kiện
Khi truyền thiếu hoặc các tham số để trống, thì assembler gán cho giá trị 0;
IFB;
;Các lệnh của assembler nếu Tham_số là blank
ELSE
; Các lệnh của assembler nếu Tham_số là not blank
ENDIF
IFNB
; Các lệnh của assembler nếu Tham_số là not blank
ELSE
;Các lệnh của assembler nếu Tham_số là blank
ENDIF
Gồm tất cả các chương trình soạn thảo:
- Có thể của Pascal, C, Notepad, Bked, v. . V. .
- hoặc Tại dấu nhắc DOS gõ: Edit
Sử dụng bản Turbo Assembly (TASM) để biên dịch và thực hiện chương trình.
TASM. EXE để dịch chương trình nguồn.
Ví dụ: C:>Tasm hello.asm - Dùng trình hợp dịch TASM (Enter)
hello.obj
- Dùng trình liên kết TLINK. EXE để liên kết chương trình với các thư viện.
Ví dụ: C:>Tlink hello.obj (Enter)
hello.exe
- Thực thi chương trình
Kết quả: Hello world
Ví dụ 1: In dòng chữ “Hello Assembler” ra màn hình.
.model small
.stack 100h
.data
msg db "Hello Assembler$"
.code
start:
mov ax,@data ;Dua dia chi du lieu vao ax
mov ds,ax ;Cho DS tro vao
mov ah,09h ;Ham nay in chuoi do dx tro toi
mov dx, offset msg
int 21h
mov ax,4c00h
int 21
end start
Khung của một chương trình Hợp ngữ
+ Chương trình mã máy trong bộ nhớ bao gồm các vùng nhớ khác nhau, gồm:
Vùng chứa mã lệnh
Vùng chứa dữ liệu
Vùng ngăn xếp phục vụ hoạt động của chương trình.
+ Chương trình viết bằng Assembly có cấu trúc tương tự, được trình biên dịch Assembler dịch ra ngôn ngữ máy như trên.
Các khối của chương trình:
Khai báo quy mô bộ nhớ:
Xác định kích thước bộ nhớ dành cho đoạn mã và đoạn dữ liệu trong một chương trình, nhờ hướng dẫn chương trình dịch như sau:
.model Kiểu_kích_thước_bộ nhớ
Khai báo đoạn ngăn xếp:
- Khai báo một vùng nhớ có kích thước đủ lớn để phục vụ hoạt động của chương trình khi có chương trình con.
. Stack kích_thước
- Kích thước sẽ quy định số byte cho ngăn xếp, thông thường từ 100-256 byte là đủ. Nếu không chỉ định rõ, chương trình mặc định là 1KB (đây là kích thước quá lớn đối với chương trình của chúng ta)
Khai báo đoạn dữ liệu
- Chứa toàn bộ các định nghĩa cho các biến của chương trình. Các hằng cũng nên định nghĩa ở đây để đảm bảo tính hệ thống của chương trình.
Ví dụ:
. Data
msg DB ‘hello !$’
CR DB 13
LF EQU 10
Khai báo đoạn mã:
Chứa mã lệnh của chương trình
. code
Các dòng lệnh được tổ chức hợp lý, đúng ngữ pháp dưới dạng một chương trình chính (CTC). Trong chương trình chính có thể có các chương trình con (ctc) được gọi bằng lệnh CALL.
Ví dụ:
Tên_CTC proc
; Các lệnh của thân chương trình chính
CALL Tên_ctc ; gọi chương trình con
Tên_CTC endp
Tên_ctc Proc
; các lệnh của thân chương trình con
RET
Tên_ctc endp
Hai dạng chính của một chương trình hợp ngữ:
* Khung chương trình hợp ngữ để dịch ra dạng *. Exe
.model small
.stack 100h
.data
; Các định nghĩa cho các biến và hằng để tại đây
.code
Main proc
;khởi đầu cho đoạn DS
mov ax,@data ;Dua dia chi du lieu vao ax
mov ds,ax ;Cho DS tro vao
;Các lệnh của chương trình chính để tại đây
;Trở về DOS dùng hàm 4Ch của ngắt INT 21h
mov ax,4c00h
int 21h
Main endp
; Các chương trình con nếu có để tại đây
Đặc điểm:
- Khi một chương trình *. Exe được nạp vào bộ nhớ . DOS sẽ tạo ra một mảng gồm 256byte gọi là đoạn mào đầu chương trình(PSP) để chứa các thông tin liên quan đến chương trình. DOS cũng đưa các thông số liên quan đến chương trình vào đoạn DS, ES. Cho nên để chương trình chạy đúng phải khởi đầu cho các thanh ghi ES, và DS.
Khung chương trình hợp ngữ để dịch ra dạng *.com
- Ta thấy chương trình *. Exe có đầy đủ các đoạn. Trong các chương trình *.com thì các đoạn mã, đoạn dữ liệu, đoạn stack thành một đoạn duy nhất là đoạn mã.
Tiết kiệm thời gian và bộ nhớ khi chạy chương trình, ngoài ra còn tiết kiệm không gian lưu trữ trên ổ đĩa.
Ví dụ:
.Model tiny
.Code
ORG 100h; gán địa chi bắt đầu cho chương trình tại 100h
start: jmp continue
; các định nghĩa cho các biến của chương trình chính để tại đây
continue:
main proc
;Các lệnh của chương trình chính để tại đây
INT 20h ;trở về DOS
main endp
; các chương trình con nếu có để tại đây
end start
Đoạn đầu của chương trình(PSP)
Jmp continue
Dữ liệu nằm tại đây
Continue:
(chiều diễn tiến của mã và dữ liệu)
(chiều diễn tiến của ngăn xếp)
IP
SP
100h
000h
FFFEh
Địa chỉ lệch
Hình 4.1: Tệp chương trình *.com trong bộ nhớ
Bộ ký tự của hợp ngữ:
Bộ kỹ tự: - Các chữ cái
- các chữ số
- các ký tự đặc biệt
Từ vựng:
- Từ khoá (keyword): là các từ dành riêng của hợp ngữ, như:
- tên các thanh ghi
- tên các lệnh gợi nhớ
- Tên các toán tử
(các từ khoá có thể viết bằng chữ hoa, hoặc chữ thường)
- Tên (symbol, name): Một dãy các ký tự biểu thị tên biến, tên hằng, tên ctc, tên đoạn. . .
Quy tắc:
- Ký tự đầu của một tên không được là số.
- Dấu chấm không được dùng trong một tên, chỉ dùng làm ký tự đầu của nhãn
Dữ liệu cho chương trình:
- hệ 2
-hệ 16
- hệ 10
- các ký tự
Khi cung cấp dữ liệu ở hệ nào thì phải kèm đuôi hệ đón (trừ hệ 10)
Với hệ 16 nếu số đó bắt đầu bằng a,b,c,d,e,f hoặc A,B...F thì thêm 0 vào trước để chương trình dịch không nhầm là nhãn.
Vi dụ: 0011B ;Số hệ 2
1234 ;Số hệ 10
0ABBAh ; Số hệ 16
1EF1H ;Số hệ 16
Khi dữ liệu là ký tự hoặc chuỗi ký tự thì chúng được đóng trong cặp dấu trích dẫn đơn hoặc kép. Chương trình sẽ dịch ra mã ASCII. Vì vậy ta có thề cung cấp mã ASCII thay vì ký tự. Ví dụ “0” thay bằng 30h
Biến và hằng
Một biến phải được định nghĩa là kiểu byte hay kiểu từ, và được chương trình gán cho một địa chỉ nhất định trong bộ nhớ.
DB (define byte) ; định nghĩa biến kiểu byte
DW
DD
* Biến byte
Chiếm 1 byte trong bộ nhớ:
Tên DB giá_trị_khởi_đầu
Ví dụ: B1 DB 4
Nếu không muốn khởi đầu giá trị thì thay giá trị khởi đầu bằng ?
Trường hợp đặc biệt của biến kiểu byte là biến ký tự:
Ví dụ: C1 DB ‘$’
C2 DB 34 ;thay bằng mã ASCII
Biến từ
Tên DW giá_trị_khởi_đầu
Ví dụ: W1 DW 40
Tương tự có thể dùng dấu ?
Biến mảng
-Một dãy các phần tử liên tiếp cùng loại byte, hoặc từ
Ví dụ: M1 DB 4,5,6,7,8,9
Phần tử đầu có địa chỉ ứng với M1, phần tử tiếp theo có địa chỉ là M1+1.
Khi khai báo có cùng giá trị khởi đầu, ta khai báo:
M2 DB 100 DUP(0)
M3 DB 100 DUP(?)
Biến kiểu xâu ký tự:
Là một trường hợp đặc biệt của biến mảng:
Ví dụ: STR1 DB ‘string’
STR1 DB 73h, 74h, 72h, 69h, 6Eh, 67h
STR1 DB 73h, 74h, ‘r’, ‘i’, 6Eh, 67h
Hằng có tên
Các hằng được gán tên làm cho chương trình hợp ngữ dễ đọc hơn
Hằng có thể là kiểu ký tự, hoặc kiểu số
Việc gán được thực hiện bằng lệnh giả (EQU:EQUate):
CR EQU 0Dh ;CR là Carriage Reture: Về đầu dòng
LF EQU 0Ah ;LF là Line Feed: Thêm dòng mới
Hằng cũng có thể là chuỗi ký tự.
CHAO EQU ‘HELLO!’
Ta có thể dùng hằng này để định nghĩa một biến mảng khác:
MSG DB CHAO,’$’
Chú ý: Lệnh giả (EQU) không dành chỗ bộ nhớ cho tên của hằng nên ta có thể đặt nó khá tự do tại những chỗ thích hợp trong chương trình. Tuy nhiên, thực tế người ta thường đặt chúng trong đoạn dữ liệu.
* Cú pháp tổng quát của một dòng lệnh: Gồm các trường sau
Tên Mã_lênh Các_toán_hạng Chú giải
Trường Tên:
Chứa các nhãn, tên biến, hoặc thủ tục
Các tên và nhãn này được chương trình dịch gán bằng địa chỉ cụ thể của ô nhớ.
Các tên và nhãn có độ dài tối đa là 31 ký tự, không chứa dấu cách, không bắt đầu bằng số. Các ký tự đặc biệt có thể dùng là ? . @ _ $ % (dấu ‘.’ phải được đặt ở vị trí đầu tiên của tên). Nói chung cứ đặt một tên bình thường và có ý nghĩa sẽ ít khi bị sai.
Một nhãn thường kết thúc bằng dấu hai chấm:
Trường mã lệnh
Có các lệnh thật hoặc lệnh giả.
Lệnh thật: Chứa các mã lệnh gợi nhớ. Được chương trình dịch dịch ra mã máy
Lệnh giả: nằm trong các hướng dẫn chương trình dịch. Không được dịch ra mã máy.
Trường toán hạng:
Với lệnh thật: Trường này chứa các toán hạng của lệnh. Tuỳ theo từng loại lệnh mà ta có thể có 0,1,2 toán hạng trong một lệnh. Với 1 toán hạng thì toán hạng đó có thể là toán hạng đích hoặc gốc. Với 2 toán hạng thì một toán hạng là đích còn toán hạng còn lại là gốc.
* Trường chú giải:
Lời giải thích phải được bắt đầu bằng dấu (;). Dành cho người lập trình ghi các lời giải thích cho các lệnh với mục đích giúp cho người đọc chương trình dễ hiểu các thao tác của chương trình hơn.
Ví dụ1:
TIEP: MOV AH, [BX] [SI] ;Nạp vào AH nội dung ô nhớ có địa chỉ DS:(BX+SI)
Tên Mlệnh Thđích, gốc Chú giải
Ví dụ2: Dòng lệnh với các hướng dẫn chương trình dịch
MAIN PROC ;Bắt đầu một thủ tục tên là MAIN
Tên Lệnh giả Chú giải
MAIN ENDP ;Kết thúc một thủ tục tên là MAIN
Tên Lệnh giả Chú giải
Các cấu trúc lập trình cơ bản thực hiện bằng hợp ngữ
Cấu trúc tuần tự
Cấu trúc lựa chọn
-Cấu trúc lặp
Cấu trúc tuần tự
Các lệnh được sắp xếp tuần tự, lệnh nọ tiếp theo lệnh kia. Sau khi thực hiện song lệnh cuối cùng của cấu trúc thì công việc làm cũng phải hoàn tất.
Ngữ pháp:
lênh 1
lênh 2
:
lênh n
Ví dụ: Các thanh ghi CX, BX chứa các giá trị của các biến c và b. Hãy tính giá trị của biểu thức a = 2*(c + b) và chứa kết quả trong thanh ghi AX.
XOR AX, AX ; đưa tổng về 0
ADD AX, BX ;cộng thêm vào AX giá trị b
ADD AX, CX ;cộng thêm vào AX giá trị c
SHL AX, 1 ;Nhân đôi kết quả trong AX
Cấu lựa chọn
- Cấu trúc IF . . . THEN Cấu trúc IF . . . THEN. . .ELSE
Ví dụ: Gán cho BX giá trị tuyệt đối của AX Ví dụ: Gán cho CL giá trị bít dấu của AX
CMP AX, 0 ;So sánh AX với 0 OR AX, AX ; Nếu AX >= 0 thì kết quả >=0
JNL GAN ;Nhảy nếu không bé hơn 0 ;Nếu AX < 0 thì kết quả <0
NEG AX ; AX < 0, đảo dấu JNS DG ;Nếu kết quả dương
GAN: MOV BX, AX ; BX chứa |AX| MOV CL, 1 ;Nếu kết quả âm, dấu = 1
JMP RA ;Kết thúc
DG: XOR CL, CL ; Kết quả dương CL=0
RA:
Điều kiện
Công việc
Điều kiện
Công việc 2
Công việc1
Sai
Sai
Đúng
Đúng
- Cấu trúc CASE
Ví dụ: Dùng AX để biểu hiện các giá trị khác nhau của AX, theo quy tắc:
Nếu AX < 0, = 0, > 0 thì tương ứng CX = -1 , 0 , 1
CMP AX, 0 ;Kiểm tra dấu của AX
JL AM ;Nếu AX <0
JE KHONG ;Nếu AX =0
JG DUONG ;Nếu AX >0
AM: MOV CX, -1
JMP RA
KHONG: MOV CX, 1
JMP RA
DUONG: XOR CX, CX
RA:
Biểu thức
Công việc 1
Công việc 2
Công việc n
Giá trị 1
Giá trị 2
Giá trị n
Cấu trúc FOR – DO
Cú pháp: FOR sốlầnlặp DO côngviệc
- Công việc được lặp đi lặp lại một số lần nhất định (Sốlầnlặp)
- Trong Assembly dùng lệnh LOOP để lặp CX lần (CX được nạp vào sốlầnlặp).
Ví dụ: Hiển thị một dòng ký tự ‘$’ trên màn hình.
MOV CX, 80 ;Số lần hiển thị đặt trong CX
MOV AH, 2 ;AH chứa số hiệu của hàm hiển thị
MOV DL, ‘$’ ;DL chứa ký tự cần hiển thị
HIEN: INT 21h ;Hiển thị, CX tự động giảm đi 1
LOOP HIEN ; Hiển thị cả một dòng
RA:
Khởi đầu Bôđếm
Cấu trúc FOR – DO
Cú pháp: FOR sốlầnlặp DO côngviệc
- Công việc được lặp đi lặp lại một số lần nhất định (Sốlầnlặp)
- Trong Assembly dùng lệnh LOOP để lặp CX lần (CX được nạp vào sốlầnlặp).
Ví dụ: Hiển thị một dòng ký tự ‘$’ trên màn hình.
MOV CX, 80 ;Số lần hiển thị đặt trong CX
MOV AH, 2 ;AH chứa số hiệu của hàm hiển thị
MOV DL, ‘$’ ;DL chứa ký tự cần hiển thị
HIEN: INT 21h ;Hiển thị, CX tự động giảm đi 1
LOOP HIEN ; Hiển thị cả một dòng
RA:
Công việc
Giảm Bộđếm đi 1
Bộđếm =0?
Đúng
Sai
Cấu trúc WHILE – DO Cấu trúc REPEAT – UNTIL
Ví dụ: Đếm số ký tự đọc được từ bàn phím, khi gặp ký tự CR thì thôi.
XOR CX, CX ;Tổng số các ký tự XOR CX, CX
MOV AH, 1 ;Hàm đọc ký tự từ bàn phím TIEP:
TIEP: INT 21h ; đọc một ký tự, AL chứa mã ký tự đó INC CX
CMP AL, 13 ; So sánh với Enter MOV AH, 1
JE RA ; đúng thì thoát INT 21h
INC CX ;sai, tăng tổng lên 1 CMP AL, 13
JMP TIEP ; Đọc tiếp JNE TIEP
RA: RA
Các toán tử dùng trong Assembler
Các toán tử số học: +, -, *, /, MOD, SHL, SHR,
Các toán tử logic: AND, OR, NOT, XOR
Các toán tử quan hệ: EQ, NE, LT, LE, GT, GE
Các toán tử cung cấp thông tin về biến và nhãn:
SEG Biểu_thức: Cho địa chỉ đoạn của Biểu_thức,
Biểu_thức có thể là một biến, nhãn, tên Segment, hay các toán hạng bộ nhớ.
OFFSET Biểu_thức: Cho địa chỉ lệch của Biểu_thức,
- Biểu_thức có thể là một biến, nhãn hay các toán hạng bộ nhớ trực tiếp khác.
Ví dụ: Chuyển segment và offset của biến Table vào cặp thanh ghi DS:DX
Table DB ?
MOV AX, SEG Table
MOV DS, AX
MOV DX, OFFSET Table
[ ]: Toán tử chỉ số thường dùng chung với toán hạng bộ nhớ.
Ví dụ: Var DB 3Ch
MOV AL, [Var]
: segment : Expression: Toán tử này quy định cách đánh địa chỉ của một biến hay một nhãn đối với đoạn segment được chỉ. Toán tử này thường dùng chung với toán tử [ ]
Ví dụ: ES:[DI]
TYPE Biểu_thức: Trả về kích thước của Biểu_thức (tính theo số byte)
DB: 1
DW: 2
DD: 4
LENGTH var: Số đơn vị mà biến var được cung cấp
SIZE var: Cho số byte mà biến var được cung cấp
Ví dụ: var DW 50 DUP(0)
Thì LENGTH var = 50
SIZE var = 100
PTR
HIGH
LOW
: segment : Expression: Toán tử này quy định cách đánh địa chỉ của một biến hay một nhãn đối với đoạn segment được chỉ. Toán tử này thường dùng chung với toán tử [ ]
Ví dụ: ES:[DI]
TYPE Biểu_thức: Trả về kích thước của Biểu_thức (tính theo số byte)
DB: 1
DW: 2
DD: 4
LENGTH var: Số đơn vị mà biến var được cung cấp
SIZE var: Cho số byte mà biến var được cung cấp
Ví dụ: var DW 50 DUP(0)
Thì LENGTH var = 50
SIZE var = 100
PTR
HIGH
LOW
Macro
Là một dãy các câu lệnh của Assembler, mà nó có thể xuất hiện nhiều lần trong một chương trình. Giống như chương trình con. Mỗi Macro có một tên riêng.
Khi một Macro được định nghĩa, thì trong chương trình thay vì viết một dãy các câu lệnh đã được định nghĩa trong Macro, ta chỉ cần viết tên của Macro đó.
Cách định nghĩa một Macro
Tên MACRO dãy_các_tham_số
Phần thân
ENDM
Phần đầu: - Dùng để khai báo một Macro
- dãy_các_tham_số được cách nhau bởi dấu phẩy (,)
Phần thân: Gồm tập hợp các câu lệnh Assembler mà macro cần định nghĩa.
Phần cuối: Là chỉ dẫn ENDM. Dùng để đánh dấu điểm kết thúc của Macro.
Ví dụ: Xuất hai ký tự ‘A’, ‘B’ ra màn hình.
Nếu không sử dụng chương trình con hay Macro. Ta có thể viết chương trình như sau:
MOV DL, ‘A’
MOV AH, 02H
INT 21H
MOV DL, ‘B’
MOV AH, 02H
INT 21H
Nếu sử dụng chương trình con Out_Char
Out_Char PROC
MOV AH, 02H
INT 21H
Out_Char ENDP
Ta có thể viết lại chương trình trên như sau:
MOV DL, ‘A’
Out_Char
MOV DL, ‘A’
Out_Char
Nếu sử dụng Macro
@Out_Char MACRO Char
MOV AH, 02H
MOV DL, Char
INT 21h
ENDM
Ta có thể viết lại chương trình như sau:
Out_Char ‘A’
Out_Char ‘B’
Các chỉ dẫn dùng trong Macro.
Local: Dùng để định nghĩa các ký hiệu, mà các ký hiệu này chỉ được dùng trong Macro đó.
Ví dụ: Xét Macro sau:
Wait MACRO Count
PUSH CX
MOV CX, Count
Next:
LOOP Next
POP CX
ENDM
Một nhãn chỉ có thể được dùng duy nhất một lần trong chương trình. Do đó Macro này chỉ có thể được dùng một lần trong chương trình. Do đó để có thể dùng nhiều lần trong chương trình ta phải sửa lại đoạn chương trình trên như sau:
Wait MACRO Count
LOCAL Next ; Đặt ngay sau phần khai báo tên Macro
PUSH CX
MOV CX, Count
Next:
LOOP Next
POP CX
ENDM
Chỉ dẫn LOCAL dung trong phần thân của Macro để báo cho assembler biết các nhãn được khai báo bởi chỉ dẫn LOCAL được đổi lại thành một tên nhãn mới trong chương trình mỗi khi Macro này được gọi. Tên nhãn mới có dạng ??Number
(Number là một số có giá trị trong khoảng từ 0000h đến FFFFh)
Cách thực thi của Macro trên:
Lần đầu gọi chương trình: ví dụ Wait 1000, thì assembler dịch macro Wait như sau: PUSH AX
MOV CX, 1000
??0000 ‘Next được thay bằng nhãn mới ??0000
LOOP ??0000
POP CX
Lần thứ hai gọi chương trình : Ví dụ Wait 3000, thì assembler dịch macro Wait như sau: PUSH AX
MOV CX, 1000
??0001 ‘Next được thay bằng nhãn mới ??0001
LOOP ??0001
POP CX
EXITM: - Dùng để thoát khỏi một Macro hoặc một khối lặp repeat
- Khi gặp chỉ dẫn này chương trình dịch sẽ chấm dứt Macro trước khi phải xử lý toàn bộ các câu lệnh của Macro.
- Nếu EXITM được dùng trong một macro lồng hoặc một khối lặp repeat lồng vào nhau thì lệnh EXITM chỉ thoát khỏi Macro hay repeat chứa nó.
Các chỉ dẫn điều kiện
Khi truyền thiếu hoặc các tham số để trống, thì assembler gán cho giá trị 0;
IFB
;Các lệnh của assembler nếu Tham_số là blank
ELSE
; Các lệnh của assembler nếu Tham_số là not blank
ENDIF
IFNB
; Các lệnh của assembler nếu Tham_số là not blank
ELSE
;Các lệnh của assembler nếu Tham_số là blank
ENDIF
* Một số tài liệu cũ có thể bị lỗi font khi hiển thị do dùng bộ mã không phải Unikey ...
Người chia sẻ: Phạm Văn Mùi
Dung lượng: |
Lượt tài: 0
Loại file:
Nguồn : Chưa rõ
(Tài liệu chưa được thẩm định)