CHƯƠNG IV: LẬP TRÌNH BẰNG HỢP NGỮ.
4.1. CHƯƠNG TRÌNH DỊCH HỢP NGỮ.
Như đã biết vi xử lý là một IC số hoạt động theo chương trình. Chương trình là tập hợp
của các lệnh, mỗi lệnh sẽ thực hiện một chức năng số cơ bản nào đó. Hệ thống vi xử lý
là một hệ thống điện tử số, nên các chương trình cung cấp để nó hoạt động phải ở dưới
dạng các mức điện áp cao và thấp, tương ứng với các bit nhị phân 0 và 1. Nhưng nếu
chương trình bằng toàn các số 0 và 1 sẽ rất khó nhớ, khó kiểm tra và sửa sai đối với
người lập trình. Để khắc phục tình trạng trên người ta đặt cho mỗi lệnh nhị phân thực
hiện một chức năng số cơ bản một tên dễ nhớ hơn, chúng được gọi là mã gợi nhớ. Khi
lập trình người ta sử dụng các mã gợi nhớ, còn khi cần vi xử lý thực hiện thì chương
trình sẽ được đổi thành các mã nhị phân 0, 1 để nạp vào bộ nhớ của hệ thống, công việc
này được gọi là hợp dịch (assembler) chương trình. Mỗi bộ vi xử lý ra đời sẽ có một tập
lệnh của nó dưới dạng mã gợi nhớ và mã nhị phân tương ứng, vì vậy việc hợp dịch
chương trình có thể thực hiện thủ công bằng cách tra bảng lệnh. Khi máy tính ra đời để
nhanh chóng và chính xác, việc hợp dịch thường được thực hiện bằng các chương trình
viết sẵn, các chương trình này được gọi là các chương trình hợp dịch hay chương trình
dịch hợp ngữ, chúng thường được cung cấp từ các hãng phần mềm, hoặc chính từ các
hãng sản xuất vi xử lý.
Với máy vi tính, đầu tiên các chương trình cần được soạn thảo bao gồm các lệnh gợi
nhớ dưới dạng văn bản, bằng bất kỳ một phần mềm soạn thảo văn bản nào, tất nhiên
chúng phải theo đúng cú pháp qui định của chương trình hợp dịch. Sau đó tập tin văn
bản này sẽ được dịch và liên kết bằng các chương trình chuyên dụng để tạo ra các tập tin
nhị phân có thể thực hiện trên máy vi tính, hoặc nạp vào bộ nhớ cho các hệ thống vi xử
lý khác.
Thông thường mỗi họ vi xử lý có ít nhất một chương trình hợp dịch, các chương trình
hợp dịch khác nhau cũng thường có qui định cú pháp khác nhau. Ví dụ các vi xử lý họ
Zilog có phần mềm dịch và liên kết là M80 và L80, họ Intel có MASM, LINK và
EXEC2BIN của Microsoft và TASM, TLINK của Borland, họ vi điều khiển 8051 có
M51, L51 và OH…. Tuy có qui định cú pháp khác nhau, nhưng cấu trúc các hàng lệnh
và khung chương trình cũng tương đối giống nhau, các lỗi khi soạn thảo sẽ được thông
báo khi hợp dịch hoặc có thể tìm thấy trong phần trợ giúp của chương trình. Sau đây
Thông thường phần mã lệnh trong bất cứ dòng lệnh nào cũng có chứa các lệnh gợi nhớ
hoặc các lệnh giả hợp ngữ. Các lệnh gợi nhớ sẽ được trình hợp dịch chuyển thành mã
máy nhị phân. Các lệnh giả chỉ có tác dụng hướng dẫn cho các trình hợp dịch mà không
được dịch ra mã máy trong chương trình.
• Phần toán hạng.
Đối với các mã lệnh gợi nhớ, phần này chứa các toán hạng của lệnh như đã mô tả trong
các cách định vị địa chỉ. Tuỳ theo từng lệnh mà phần toán hạng có thể bao gồm 0, 1
hoặc 2 toán hạng. Thông thường khi không có phần toán hạng, thì toán hạng thao tác
trong lệnh sẽ được hiểu ngầm, nếu chỉ có một toán hạng nó sẽ được gọi là toán hạng
đích, nếu có hai toán hạng sẽ có một toán hạng nguồn và một toán hạng đích.
Đối với các lệnh giả phần này sẽ chứa các thông tin liên quan đến lệnh giả đó.
• Phần chú giải.
Phần này được tính bắt đầu từ sau dấu ‘;’ trên một dòng lệnh (có thể không có các phần
khác). Nó cho phép ghi vào các lời giải thích về dòng lệnh hoặc về hoạt động của
chương trình, nó giúp ích cho người lập trình dễ nhớ hơn khi đang viết chương trình,
hoặc khi đọc lại chương trình. Khi hợp dịch các lời giải thích này sẽ không được dịch ra
mã lệnh, có nghĩa là nó không có giá trị gì trong chương trình mã máy.
4.2.2. Dữ liệu cho chương trình.
Dữ liệu trong một chương trình hợp ngữ rất đa dạng. Các dữ liệu có thể được cho dưới
dạng hệ nhị phân, thập phân, bát phân hoặc thập lục phân. Khi số cho ở hệ nào cần phải
có ký tự chỉ thị cho hệ đó ở phía sau: hệ nhị phân là chữ B (Binary), hệ bát phân là chữ
O (Octal), hệ 16 là chữ H (Hexadecimal), riêng hệ thập phân có thể không cần viết ký tự
phía sau. Chú ý trong hệ 16, khi các dữ liệu được bắt đầu bằng các ký tự chữ, để phân
biệt với các tên hoặc nhãn cần phải viết thêm một số 0 lên phía trước.
Nếu dữ liệu là một chuỗi ký tự thì chúng phải được để trong dấu nháy, chương trình sẽ
dịch ra mã ASCII tương ứng của nó. Ví dụ dữ liệu 41H sẽ tương ứng với ‘A’.
4.2.3. Biến và hằng.
Biến và hằng khái báo trong một chương trình hợp ngữ cũng có các chức năng giống
như trong một chương trình ngôn ngữ cấp cao. Một biến cần phải được định kiểu bằng
các lệnh giả như:
tương ứng của chúng. Các dòng lệnh sau cùng định nghĩa một xâu ký tự nhưng gán cho
chúng các tên khai báo cho chúng khác nhau:
STR1 DB 'string'
STR2 DB 73h, 74h, 72h, 69h, 6Eh, 67h
STR3 DB 73h, 74h, 'r', 'i', 'n', 67h
• Hằng có tên.
Các hằng số trong các chương trình hợp ngữ cung thường được gán tên để dễ nhớ và dễ
đọc hơn. Hằng có thể là kiểu số hoặc kiểu ký tự. Việc gán tên cho hằng được thực hiện
bằng lệnh EQU (equate) như sau:
CR EQU 0Dh ; CR là ký tự về đầu hàng (Carriage return)
LF EQU 0Ah ; LF là ký tự xuống hàng (Line Feed)
Hằng cũng có thể là một chuỗi ký tự, ví dụ có thể tên cho một chuỗi ký tự sau đó sử
dụng để định nghĩa cho một biến mảng khác.
Chao EQU 'Hello'
MSG DB CHAO, '$'
73
Do EQU là một lệnh giả không dành chỗ của bộ nhớ cho tên hằng nên có thể đặt dòng
lệnh khai báo này ở bất kỳ vị trí nào trong chương trình. Tuy nhiên trong thực tế người
ta thường đặt chúng trong phần khai báo dữ liệu.
4.3. LẬP TRÌNH VÀ CHO CHẠY MỘT CHƯƠNG TRÌNH HỢP NGỮ.
4.3.1. Khung của một chương trình hợp ngữ.
Một chương trình hợp ngữ chạy trên các hệ thống vi xử lý họ Intel bao gồm các đoạn
vùng nhớ khác nhau để chứa mã lệnh, dữ liệu và ngăn xếp. Các đoạn này sẽ được khai
báo bằng các lệnh giả hợp ngữ theo đúng cú pháp của trình biên dịch tạo thành khung
của chương trình. Sau đây chúng ta sẽ xem xét các từ khoá tối thiểu trong một chương
trình hợp ngữ với các trình hợp dịch MASM và TASM.
• Khai báo qui mô sử dụng bộ nhớ.
Dung lượng bộ nhớ dành cho đoạn mã lệnh và đoạn dữ liệu được xác định nhờ lệnh giả
'.MODEL', lệnh này phải luôn đặt trước tất cả các lệnh khác trong chương trình.
Cú pháp lệnh:.MODEL Kiểu kích thước bộ nhớ
thể được khai báo trong phần này. Việc khai báo dữ liệu được thực hiện bằng lệnh giả
.DATA. Các chương trình với kiểu Tiny cũng không có khai báo này.
• Khai báo đoạn mã.
74
Đoạn mã là nơi chứa các lệnh gợi nhớ của chương trình. Việc khai báo đoạn mã được
thực hiện bằng lệnh giả .CODE. Chương trình sẽ thực hiện lệnh đầu tiên nằm sau
lệnh .CODE sau đó là các lệnh kế tiếp tùy theo cấu trúc điều khiển của nó. Các chương
trình con cũng được viết trong đoạn này, nhưng chú ý rằng chúng chỉ được chuyển tới
bằng các lệnh gọi (CALL).
• Khung của chương trình hợp ngữ để dịch ra dạng .EXE.
Từ các khai báo của chương trình đã trình bày ở trên có thể xây dựng một khung tổng
quát cho các chương trình hợp ngữ với kiểu kích thước bộ nhớ nhỏ, các chương trình
loại này sau khi hợp dịch sẽ tạo ra một tập tin có thể thực hiện được (executable) với
đuôi .EXE. Khung các chương trình loại này biểu diễn như sau:
. Model Small
.Stack 100
. Data
; Các định nghĩa cho biến và hằng để tại phần này
.Code
Main Proc
MOV AX,@Data ; khởi tạo DS
MOV DS, AX ; nếu cần phải viết thêm lệnh MOV ES,AX
; các lệnh của chương trình chính.
MOV AH,4CH
INT 21H ; Trở về DOS
Main Endp
; các chương trình con để tại phần này.
End Main ; kết thúc toàn bộ chương trình
Khi một chương trình .EXE được nạp vào bộ nhớ để thực hiện, DOS sẽ tạo ra một
mảng 256 byte gọi là đoạn mào đầu chương trình (Program Segment Prefix- PSP) dùng
chương trình.
• Cách tạo và thực hiện một chương trình hợp ngữ trên máy vi tính.
Máy vi tính IBM PC là tạo và thực hiện các chương trình hợp ngữ cho họ Intel. Các
bước để thực hiện công việc này như sau:
- Dùng các phần mềm soạn thảo văn bản (SK, NC…) để soạn thảo các chương trình
nguồn được mặc định có đuôi .ASM.
- Dùng các chương trình hợp dịch MASM hoặc TASM để dịch tập tin nguồn .ASM ra
dạng mã máy có đuôi .OBJ. Các dòng lệnh dưới dấu nhắc DOS như sau:
Với MASM: C:\MASM filename.ASM
Với TASM: C:\TASM filename.ASM
- Dịch và liên kết các tập tin .OBJ thành tập tin có thể chạy được:
Với MASM dùng LINK để liên kết các tập tin .OBJ tạo ra chương trình .EXE, nếu
chương trình nguồn viết dưới dạng dịch ra .EXE thì tập tin này có thể thực hiện được.
Nếu viết dưới dạng .COM thì cần phải sử dụng EXE2BIN để dịch ra tập tin .COM mới
có thể chạy được.
Với TASM dùng TLINK để liên kết và tạo ra tập tin chạy .EXE, nếu viết dưới dạng
.COM phải dùng dòng lệnh TLINK/t để tạo ra tập tin .COM.
4.4. Các cấu trúc lập trình cơ bản.
Các lệnh của một ngôn ngữ, nhất là các lệnh hợp ngữ thường chỉ thực hiện các tác vụ
cơ bản. Vì vậy để viết một chương trình người ta thường chia nó ra thành các khối chức
năng nhỏ hơn, các khối chức năng nhỏ này lại chia thành các khối chức năng nhỏ hơn
nữa. Việc phân chia này được thực hiện cho tới khi mỗi khối chức năng trở nên đơn giản
và dễ dàng thực hiện bằng các lệnh.
Các khối chức năng thành phần thường được thực hiện bằng các cấu trúc lập trình cơ
bản. Phương pháp chia chương trình thành các khối chức năng thành phần như trên làm
cho chương trình trở nên có cấu trúc, dễ dàng trong việc hiệu chỉnh, cải tiến và lập tài
liệu lưu trữ cho nhiều người sử dụng. Có ba cấu trúc lập trình cơ bản thường được sử
dụng khi giải quyết các công việc khác nhau là :
+ Cấu trúc tuần tự.
+ Cấu trúc lựa chọn.
THOAT:
• Cấu trúc IF – THEN – ELSE.
Ngữ pháp: IF Điều kiện THEN Công việc1 ELSE Công việc 2.
Giải thuật của cấu trúc trình bày trên hình 4.2. trong cấu trúc này nếu thỏa điều kiện thì
công việc 1 được thực hiện, nếu không thì công việc 2 được thực hiện. Trong hợp ngữ
điều này tương đương với việc sử dụng các lệnh nhảy có điều kiện và không điều kiện
đến các nhãn khác nhau.
77
Công việc
Điều kiện
Đúng
Sai
Hình 4.1. Giải thuật cấu trúc IF – THEN.
Ví dụ : Tìm số nhỏ hơn trong hai số chứa trong AH và BH gán cho AL.
CMP AH,BH ;AH<BH?
JNL GAN ; Nếu đúng gán AH cho AL
MOV AL,BH; Nếu không lấy số nhỏ hơn trong BH vào AH
JMP RA
GAN:MOV AL,AH ; AL sẽ chứa số nhỏ hơn.
RA:
• Cấu trúc CASE.
Ngữ pháp: CASE Biểu thức
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
Giải thuật của cấu trúc biểu diễn trên hình 4.3. Trong cấu trúc này nếu biểu thức có giá
trị 1 thì công việc 1 được thực hiện, nếu biểu thức có giá trị 2 công việc 2 được thực
hiện …. Trong hợp ngữ có thể sử dụng các lệnh nhảy có điều kiện và không có điều kiện
MOV AX,0 ;Khởi động tổng bằng 0
MOV DX,1 ; Số thứ nhất
MOV CX,99 ; Tất cả bao gồm 99 số
LAP: ADD AX,DX ; Tổng := Tổng + 1
INC DX ; Tăng để có số tiếp theo
LOOP LAP ; Lặp cho tới khi hết 99 số.
79
Công việc 1 Công việc 2 Công việc N
Biểu thức
……
Hình 4.3: Giải thuật cấu trúc CASE.
Công việc
Sai
Điều kiện
Đúng
Hình 4.4. Giải thuật cấu trúc WHILE – DO.
Khởi động bộ đếm
Giảm bộ đếm