Tài liệu PH ẦN 1: LẬP TRÌNH HỢP NGỮ CHO HỌ x86 doc - Pdf 10

PHẦN 1: LẬP TRÌNH HỢP NGỮ CHO HỌ x86
BÀI 1: CĂN BẢN VỀ HỢP NGỮ
1. MỤC ĐÍCH
Làm quen với ngôn ngữ lập trình Assembly
Biết cách viết, dịch, chạy một vài chương trình đơn giản trên chương trình mô phỏng
Emu8086
2. TÓM TẮT LÝ THUYẾT
Hợp ngữ (assembler) là ngôn ngữ bậc thấp, giúp cho người lập trình không phải ghi nhớ mã
máy (opcode) mà sử dụng các từ ngữ gợi nhớ (pseudo-code) gần với ngôn ngữ tự nhiên để miêu
tả công việc cần thực hiện. Tuy vậy, assembler rất gần với ngôn ngữ máy, đòi hỏi người lập trình
phải hiểu biết tương đối đầy đủ về cấu trúc phần cứng máy tính.
Với mỗi kiểu kiến trúc của bộ vi xử lý, có một bộ lệnh riêng, do đó, có một ngôn ngữ
assembler riêng cho nó. Ở đây, chúng ta nghiên cứu assembler cho các bộ vi xử lý Intel thuộc họ
x86. Các chương trình sẽ được viết trên chương trình mô phỏng Emu8086. Tuy chương trình mô
phỏng không thể hiện được đầy đủ các tập lệnh có trong họ 8086. Ngược lại, chương trình mô
phỏng giúp ta tìm hiểu về hợp ngữ một cách trực quan và dễ hiểu.
2.1. Cấu trúc thông thường của một chương trình hợp ngữ được viết trên Emu8086:
#make_COM# <Khai báo chương trình dang .com>
.stack <Khai báo kích thước ngăn xếp>
.data <Khai báo dữ liệu>
.code
ORG 100h ; COM file is loaded at CS:0100h
<Các lệnh>
End
Chúng ta có bỏ qua các khai báo về “.model”, “.stack”, “.data”, “.code” và “end” khi chạy trên
chương trình mô phỏng.
Ví dụ: Chương trình sau in ra màn hình dòng chữ “Hello, World!”
#make_COM# ; Standard header
ORG 100H
JMP START ; Jump to start:
msg DB 13, 10, 'Hello, World!$‘ ; Data

Để biên dịch chương trình, ta chọn Compile. Ta có thể mô phỏng trực tiếp bằng cách chọn
Emulate. Màn hình sẽ hiện thị lên như hình 1.2
Hình 1.2: Giao diện chương trình mô phỏng
Trên chương trình mô phỏng, ta có thể quan sát được nội dụng các thanh ghi, dữ liệu lưu
trong bộ nhớ, màn hình, bộ ALU, Stack, thanh ghi cờ… Ngoài ra, ta có thể chạy chương trình
(chọn Run) hoặc thực hiện từng lệnh (Single Step).

2.4. Một số lệnh cơ bản
MOV des,src : chép dữ liệu từ src sang des
INC des : tăng des một đơn vị
DEC des : giảm des một đơn vị
ADD des,src : des = des + src
SUB des,src : des = des – src
INT num : gọi ngắt
3. THỰC HÀNH
3.1. Bài tập
B à i 1. Viết CT nhập vào 1 ký tự, xuất ra ký tự đó
V í dụ :
Nhap 1 ky tu: b
Ky tu vua nhap: b
B à i 2. Viết chương trình xuất ra màn hình một số dòng chữ
Ví dụ:
Dai hoc Quoc gia Thanh pho Ho Chi Minh
Truong Dai hoc Khoa hoc tu nhien
Khoa Dien tu – Vien thong
Bài 3. Viết CT nhập vào 1 ký tự, xuất ra ký tự liền trước và liền sau.
V í dụ :
Moi ban nhap 1 ky tu: b
Ky tu lien truoc: a
Ky tu lien sau: c

DB 10,13,9,“ Truong Dai hoc Khoa hoc tu nhien”
Bài 3, 4. Kí tự hoa và kí tự thường của cùng một chữ cái tiếng Anh cách nhau 20h. Do đó, để
chuyển đổi chữ hoa thành chữ thường và ngược lại, chỉ cần dùng lệnh ADD, SUB.
Bài 5. Để chuyển đổi các kí tự ‘0’ – ‘9’ thành số 0 – 9 chỉ cần thực hiện phép trừ đi 48 (mã của
‘0’). Sau khi thực hiện phép tính, chuyển đổi thành kí tự và in ra màn hình (có thể dùng biểu diễn
Hex).
BÀI 2: CÁC CHỈ THỊ LOGIC VÀ ĐIỀU KHIỂN
1. MỤC ĐÍCH
Hiểu cách so sánh hai số trong hợp ngữ
Hiểu cách thay đổi thứ tự thực hiện các lệnh
Biết cách sử dụng các lệnh so sánh, nhảy và lặp
2. TÓM TẮT LÝ THUYẾT
2.1. Lệnh so sánh
Trong hợp ngữ, muốn so sánh hai số, ta phải thực hiện một phép toán số học hoặc logic trên
hai số đó và căn cứ vào các bit trong thanh ghi cờ rồi đưa ra kết luận. Để làm việc này, có thể
dùng lệnh CMP và TEST.
Bản chất của lệnh CMP Des,Src là lệnh SUB Des,Src (thực hiện phép tính Des – Src)
nhưng kết quả của phép tính không được lưu vào Des như trong lệnh SUB.
Ví dụ: so sánh hai số nguyên dương
MOV AH,1
MOV AL,2
CMP AH,AL
Sau khi thực hiện hai lệnh trên, cờ Carry (CF) bật, báo hiệu rằng AH < AL
Bản chất của lệnh TEST Des,Src là lệnh AND Des,Src (thực hiện phép tính Des AND Src)
nhưng kết quả của phép tính không được lưu vào Des như trong lệnh AND.
Ví dụ: kiểm tra hai bit cuối cùng của AL
TEST AL,3 ; 3h = 11b
Nếu cờ Zero (ZF) bật, có nghĩa là cả hai bit 0 và 1 của AL đều bằng 0.
2.2. Lệnh nhảy
Thông thường, khi một lệnh (instruction) được thực hiện, giá trị của thanh ghi IP (instruction


Calculate: ; công việc 1

Check: ; công việc 2 – nơi cần nhảy
đến

Output: ; công việc 3

• JMP <con trỏ 4 byte> (far indirect jump). Tương tự trường hợp trên,
nhưng con trỏ gồm cả segment và offset. Chỉ khác ở khai báo con trỏ
Ví dụ:
myPointer DD Prepare, Calculate, Check, Output

MOV bx,1 ; chỉ số trong mảng con trỏ
MOV cl,2
SHL bx,cl ; nhân 4
JMP myPointer[bx]

Prepare: ; công việc 0

Calculate: ; công việc 1 – nơi cần nhảy
đến

• JMP <thanh ghi 2 byte> (indirect jump via regs). Nhảy đến địa chỉ lưu
trong thanh ghi AX.
Ví dụ:
MOV ax, offset Calculate

JMP ax ; (IP ← AX)
 Lệnh nhảy có điều kiện

có dấu), JBE (nhảy nếu nhỏ hơn hay bằng, không dấu), JLE (nhảy nếu nhỏ hơn
hay bằng, có dấu).
• JNE, JNZ (nhảy nếu không bằng).
Ví dụ: nếu AL là số nguyên không dấu thì đoạn chương trình ở trên phải sửa lại như sau:
MOV AH,AL
CMP AH,1
JAE Greater
. . .
Greater:
Lệnh lặp
Bằng cách dùng các lệnh nhảy có thể tạo ra vòng lặp. Tuy nhiên, để viết chương trình tiện lợi
và ngắn gọn, có thể dùng thêm các lệnh lặp như LOOP, LOOPZ,…
Lệnh LOOP <Label> tự động giảm CX một đơn vị, sau đó kiểm tra xem CX có bằng 0,
nếu không bằng thì nhảy đến nhãn <Label>
Lệnh LOOPZ <Label> tự động giảm CX một đơn vị, sau đó kiểm tra xem CX có bằng 0
hoặc cờ ZF có bật không, nếu cả hai điều này không xảy ra thì nhảy đến nhãn <Label>
Ví dụ: Nhập mảng A gồm 10 ký tự
MOV SI, 0 ; chỉ số mảng
MOV CX, 10 ; số lần lặp
LAP:
;nhập ký tự
MOV AH, 1
INT 21H
MOV A[SI], AL
INC SI
; xuất ký tự
MOV AH, 2
INT 21H
LOOP LAP
Các lệnh lặp

A[N] = {3,1,2,7,4}
=> max = 7, min = 1, tổng = 17.
Bài 9. Cài đặt thuật toán Bubble Sort dùng ASM.
Thuật toán Bubble Sort theo ngôn ngữ C như sau:
for (int i = 0; i< N-1; i++)
for(int j=N-1;j > i; j )
if(a[j] < a[j-1])
Hoan_Vi (a[j], a[j-1]);
Bài 10. Nhập và xuất mảng A hai chiều.
a. Tính tổng các phần tử trên đường chéo chính, đường chéo phụ.
b. Đếm số phần tử 0 và phần tử khác 0 trong mảng.
c. Tìm phần tử max của mỗi dòng, mỗi cột. Tính tổng của mỗi dòng, mỗi cột.
d. Nhập 1 mảng hai chiều B, tạo một mảng hai chiều C có các phần tử trên dòng chẵn
bằng với các phần tử trên dòng chẵn của A, các phần tử trên dòng lẻ bằng các phần tử trên dòng
lẻ của B.
Hướng dẫn
Bài 1. Xem ví dụ:
.MODEL SMALL
.STACK 100H
.DATA
CBS DB "CHAO BUOI SANG$"
CBT DB "CHAO BUOI TRUA$"
CBC DB "CHAO BUOI CHIEU$"
.CODE
MOV AX, @DATA
MOV DS, AX
;nhập 1 ký tự bất kỳ
MOV AH, 1
INT 21H
CMP AL, 'S'

Bài 3. Để nhập một số nguyên, có thể làm như sau: đầu tiên nhập xâu kí tự chứa các số từ 0 đến
9, sau đó đổi từng kí tự ra số và nhân với các lũy thừa tương ứng của 10 và cộng lại.
Bài 9. Xem ví dụ sau: Lặp gồm 2 vòng lặp (xếp mảng A có N phần tử tăng dần)
MOV N, 10 ;giả sử mảng A gồm N ký tự, trong ví dụ này N=10
MOV CX, N
DEC CX
MOV SI, 0
FOR_I:
PUSH CX
MOV CX, N
MOV DI, 0
MOV DL, A[SI]
FOR_J:
CMP DL, A[DI]
JB LAP
MOV BL, A[DI]
MOV A[DI], DL
MOV A[SI], BL
MOV DL, A[SI]
LAP:
INC DI
LOOP FOR_J
INC SI
POP CX
LOOP FOR_I
Làm việc với số nguyên
Mục đích
 Biết sử dụng các phép toán logic, số học
 Biết cách đổi giữa các cơ số nhị phân, thập phân và thập lục phân
Tóm tắt lý thuyết

Ví dụ : SUB BL, 10H -> BL = BL – 10H
Chú ý : Các phép toán cộng trừ trực tiếp giữa các ô nhớ là không hợp lệ. Ngoài ra
ta cũng có thể sử dụng INC hoặc DEC để cộng hoặc trừ 1 đơn vị vào nội dung
một ô nhớ hoặc một thanh ghi.
3. Nhân MUL, IMUL: MUL (IMUL) nguồn
Lệnh MUL thực hiện phép nhân không dấu, còn IMUL là lệnh nhân có dấu. Nếu nguồn
là byte (8 bit) thì kết quả chứa trong AX và AX = AL * nguồn. Nếu nguồn là word (16
bit) thì kết quả chứa trong DX:AX và DX:AX = AX * nguồn. Nếu nguồn là double (32
bit) thì kết quà chứa trong EDX:EAX và EDX:EAX = EAX * nguồn.
4. Chia DIV, IDIV : DIV (IDIV) số chia
Lệnh DIV thực hiện chia không dấu, còn IDIV là lệnh chia có dấu. Nếu số chia là byte
(8 bit) thì số bị chia là AX và kết quả gồm: phần dư = AH, phần thương = AL. Nếu số chia là
word (16 bit) thì số bị chia là DX:AX và kết quả gồm phần dư = DX, phần thương = AX. Nếu số
chia là double thì sô bị chia là EDX:EAX và kết quả gồm phần dư = EDX, phần thương = EAX.
Chú ý : phải xoá giá trị DX hoặc EDX trước khi nhân, hoặc chia.
Tài liệu tham khảo
1. Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 7, ĐHKHTN, 2002
2. Randal Hyde, The art of assembly language programming – Chapter 9.
3. Norton Guide
4. Dan Rollins, TechHelp v.6.0
Bài tập
1. Viết chương trình (VCT) đổi một số dạng thập phân sang thập lục phân.
Ví dụ: Nhập một số hệ 10 : 26
Dạng thập lục phân: 1A
2. VCT nhập một số hệ thập phân rồi xuất ra biểu diễn dạng nhị phân của nó.
Ví d ụ : Nhập số hệ 10: 26
Dạng nhị phân: 11010
3. VCT đổi một số dạng thập lục phân sang sang thập phân.
Ví d ụ : Nhập số hệ thập lục phân: 1a (hoặc 1A)
Dạng thập phân của nó là: 26


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status