1. Trang chủ
  2. » Kỹ Thuật - Công Nghệ

Bài tập lập trình hợp ngữ asembly

29 29,3K 52

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 29
Dung lượng 2,32 MB

Nội dung

Bài tập lập trình hợp ngữ asembly

Trang 1

Bài thực hành số 1

Nhập môn

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 và chẩn lỗi (debug) một vài chương trình đơn giản

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 cho chế độ thực (real mode) trong DOS và được biên dịch bằng Turbo Assembler

Cấu trúc thông thường của một chương trình hợp ngũ

.model <Khai báo kiểu chương trình>

.stack <Khai báo kích thước ngăn xếp>

Trang 2

Khai báo biến trong hợp ngữ

Cú pháp:

<tên biến> D<Kiểu DL> <giá trị khởi tạo>

hoặc

<tên biến> D<Kiểu DL> <số phần tử> dup(<giá trị khởi tạo>)

Các kiểu dữ liệu: B (1 byte), W (2 bytes), D (4 bytes)

Nếu không khởi tạo, dùng dấu hỏi “?”

Dịch, liên kết, chạy và chẩn lỗi chương trình từ dấu nhắc DOS

Cần có các file: tasm.exe (dịch), tlink.exe (liên kết), td.exe (chẩn lỗi) Các bước như sau:

 B1 Thiết lập đường dẫn

path = %path%;<đường dẫn đến thư mục chứa các file kể trên>

 B2 Biên dịch từ file ASM sang file OBJ

Tasm <tên file chương trình>.ASM

 B3 Biên dịch từ file OBJ sang file EXE

Tlink <tên file>.OBJ

%1

Trang 3

(%1 là lấy tham số thứ nhất trong command line)

Sau đó để biên dịch, liên kết và thực thi chương trình hello.ASM ta chỉ cần gõ :

RunASM hello

Công cụ EditPlus

Đây là công cụ soạn thảo văn bản tiện dụng, cho phép tự động đổi màu chữ theo cú pháp Ngoài ra còn có thể thiết đặt phím tắt để gọi các tiện ích khác Để dùng cho soạn thảo chương trình assembler, cần copy file định nghĩa cú pháp vào thư mục cài đặt và đăng kí sử dụng nó cho những file có tên mở rộng “.asm”

 B0 Cấu hình Edit Plus: xem trong file hướng dẫn

 B1 Biên dịch file ASM : nhấn Ctrl + 1 sẽ biên dịch file đang soạn thảo thành OBJ

 B2 Liên kết : nhấn Ctrl + 2 sẽ biên dịch file OBJ thành EXE

 B3 Chạy chương trình : nhấn Ctrl + 3 sẽ chạy chương trình EXE

 B4 Chẩn lỗi chương trình : nhấn Ctrl + 4 sẽ debug chương trình EXE

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

Tài liệu tham khảo

1 Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 1, ĐHKHTN, 2002

2 Randal Hyde, The art of assembly language programming – Chapter 1

Ví dụ:

De chay duoc 1 CT hop ngu ban can thuc hien cac buoc sau:

Dich file ASM thanh file OBJ

Trang 4

Lien ket file OBJ thanh file EXE Chay file EXE

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 Bài 4 Viết CT nhập vào 1 ký tự thường In ra ký tự Hoa

Mở rộng

1 Tự tìm hiểu xem hàm nào trong ngắt 21h dùng để nhập một xâu kí tự ? Ngoài ngắt 21h, còn ngắt nào có thể dùng để nhập xuất từ bàn phím ? (dùng NortonGuide hoặc TechHelp)

2 Viết chương trình nhập tên và in ra màn hình câu “Hello ” + tên đã nhập

3 Tìm hiểu xem tại sao không có lệnh MOV x1, x2 (x1,x2 là hai biến trong bộ nhớ)

4 Hai lệnh “INC AX” và “ADD AX, 1” khác nhau chỗ nào ?

Hướng dẫn

Bài 1 Để nhập 1 một ký tự sử dụng hàm 1 của ngắt 21h, để xuất, sử dụng hàm 2

Ví dụ:

mov AH,1

int 21h ; kết quả trong AL

mov DL,AL ; kí tự cần xuất trong DL

mov AH,2

int 21h

Bài 2 Cặp kí tự xuống dòng là 10,13 Có thể khai báo nhiều xâu kí tự hoặc chung một xâu

Ví dụ:

Msg3 DB 10,13,9,“1 Dich file ASM thanh file OBJ.$”

Msg4 DB 10,13,9,“2 Lien ket file OBJ thanh file EXE.$” Hoặc

Trang 5

Msg34 DB 10,13,9,“1 Dich file ASM thanh file OBJ.”

DB 10,13,9,“2 Lien ket file OBJ thanh file EXE.$”

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)

Trang 6

Bài thực hành số 2

Lệnh so sánh – Lệnh nhảy – Lệnh lặp

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

Tóm tắt lý thuyết

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

 Lệnh nhảy không điều kiện

JMP <target>

Có các trường hợp sau:

JMP SHORT <tên nhãn> (short jump) Khi đó trong mã lệnh lưu 1 byte khoảng

cách (offset) giữa vị trí hiện tại và vị trí cần nhảy đến Kiểu này chỉ nhảy trong phạm

vi từ –128 đến +127 byte so với vị trí hiện tại

Ví dụ: JMP SHORT Calculate

JMP <tên nhãn> (near jump) Khi đó trong mã lệnh lưu 2 byte khoảng cách

Trang 7

(offset) giữa vị trí hiện tại và vị trí cần nhảy đến Kiểu này nhảy tùy ý trong phạm vi segment

Ví dụ: JMP Calculate

JMP FAR PTR <tên nhãn> (far jump) Khi đó trong mã lệnh lưu offset và segment của vị trí cần nhảy đến Kiểu này nhảy đến bất kì chỗ nào

Ví dụ: JMP FAR PTR Calculate

JMP <con trỏ 2 byte> (near indirect jump) Khi đó trong mã lệnh lưu địa

chỉ offset của một ô nhớ Khi thực hiện, IP sẽ được gán bằng giá trị lưu tại địa chỉ này Có thể kết hợp dùng với định vị chỉ số

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ỏ

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

Trang 8

 Lệnh nhảy có điều kiện

Đối với bộ vi xử lý 80286 trở xuống, lệnh nhảy có điều kiện có độ dài 2 byte, byte đầu tiên chứa

mã lệnh, byte thứ hai chứa khoảng cách tương đối từ lệnh đến nhãn, vì vậy <Label> trong lệnh nhảy

có điều kiện phải nằm trong khoảng từ -128 đến 127 so với vị trí lệnh nhảy Muốn nhảy xa hơn ta phải dùng kết hợp lệnh nhảy không điều kiện JMP

Từ 80386 trở lên, bộ lệnh được bổ sung, cho phép sử dụng lệnh nhảy có điều kiện có độ dài 4 byte, do đó <Label> có quyền nằm tùy ý trong cùng phạm vi segment

Khi sử dụng lệnh nhảy có điều kiện sau khi thực hiện phép so sánh, phải đặc biệt lưu ý toán hạng trong phép so sánh là số có dấu (signed) hay không có dấu (unsigned) để lựa chọn lệnh cho phù hợp

Một số lệnh nhảy có điều kiện thường dùng (tham khảo thêm trong SGK trang 81):

JE, JZ (nhảy nếu bằng)

JA (nhảy nếu lớn hơn, không dấu), JG (nhảy nếu lớn hơn, có dấu), JB (nhảy nếu nhỏ hơn, không dấu), JL (nhảy nếu nhỏ hơn, có dấu)

JAE (nhảy nếu lớn hơn hay bằng, không dấu), JGE (nhảy nếu lớn hơn hay bằng, 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>

Trang 9

Tài liệu tham khảo

1 Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 4, ĐHKHTN, 2002

2 Randal Hyde, The art of assembly language programming – Chapter 6, 10

3 Dan Rollins, TechHelp v.6.0

Ví dụ: N = 3, M = 5 => USCLN(3, 5) = 1 => 3, 5 là 2 số nguyên tố cùng nhau

Bài 5 Dùng lệnh lặp, viết chương trình nhập vào 1 chuỗi ký tự Sau khi nhập xong đếm xem chuỗi

có bao nhiêu ký tự Xuất số ký tự có trong chuỗi

Ví dụ: S = "Hello world !" ==> Số kí tự trong chuỗi là 13

Bài 6 Nhập vào 2 chuỗi số, đổi 2 chuỗi thành số, sau đó cộng hai số, đổi ra chuỗi và xuất chuỗi tổng

Ví dụ: S1 = "123" => N1 = 123

S2 = "456" => N2 = 456

N = N1 + N2 = 123 + 456 = 579 => S = "579" (xuất S ra màn hình)

Trang 10

Bài 7 Viết chương trình cho phép nhập vào một chuỗi S

Đổi tất cả ký tự thường thành ký tự hoa

Đổi tất cả ký tự hoa thành ký tự thường

Bài 8 Nhập và xuất mảng 1 chiều Tìm phần tử max, min, tính tổng các phần tử trong mảng

Ví dụ: N = 5

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

Mở rộng

1 Trong bài tập 5, làm sao để đếm số từ có trong chuỗi kí tự?

2 Trong bài tập 10, làm sao để thể hiện một menu cho phép người dùng chọn trong các kí tự từ

„a‟ đến „d‟ sau đó thực hiện công việc ứng với chữ cái đó

CBS DB "CHAO BUOI SANG$"

CBT DB "CHAO BUOI TRUA$"

CBC DB "CHAO BUOI CHIEU$"

Trang 11

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

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

Trang 12

Bài thực hành số 3

Ngăn xếp – Thủ tục – Macro

Mục đích

 Hiểu được cơ chế hoạt động của ngăn xếp, quá trình gọi một thủ tục

 Biết cách sử dụng ngăn xếp, khai báo và gọi thủ tục

 Biết cách tạo và sử dụng macro

Tóm tắt lý thuyết

Ngăn xếp

1 Một số lưu ý:

 Ngăn xếp (Stack) là vùng nhớ đặc biệt được truy cập theo cơ chế “vào trước ra sau”

(LIFO – Last In First Out), nghĩa là dữ liệu nào đưa vào sau sẽ được lấy ra trước

Ngăn xếp gồm nhiều phần tử, mỗi phần tử là một từ (2 bytes)

 Vị trí của ngăn xếp trong bộ nhớ được xác định bởi cặp thanh ghi SS:SP (SS chứa địa chỉ đoạn, SP chứa địa chỉ ô của đỉnh ngăn xếp) Khi chưa sử dụng, ngăn xếp rỗng, vị trí được xác định bởi SP lúc đó là đáy ngăn xếp

2 Khai báo:

.STACK <kích thước của ngăn xếp>

Ví dụ: khai báo một vùng ngăn xếp có kích thước 256 bytes:

.STACK 100h

3 Các thao tác:

 Đưa trị vào (đỉnh) ngăn xếp:

PUSH <nguồn> ; đưa nguồn (thanh ghi hay từ nhớ

; 16 bit) vào đỉnh ngăn xếp

PUSHW <hằng> ; đưa trực tiếp một hằng16 bit vào

; đỉnh ngăn xếp

PUSHF ; đưa nội dung thanh ghi cờ vào đỉnh ; ngăn xếp

 Lấy trị (ở đỉnh) ra khỏi ngăn xếp:

POP <đích> ; lấy giá trị (2 bytes) ở đỉnh ngăn xếp

; đưa vào đích (thanh ghi (trừ thanh

; ghi IP) hay từ nhớ 16 bit)

POPF ; lấy giá trị (2 bytes) ở đỉnh ngăn xếp

; đưa vào thanh ghi cờ Chú ý : Các lệnh PUSH, PUSHF, POP và POPF không ảnh hưởng tới các cờ

Ví dụ: Chương trình xuất chuỗi ngược dùng stack:

Trang 13

Nhập ký tự „c‟:

Xuất ký tự „a‟:

0FCh 0FCh SS:SP 

000h

0FCh 0FCh SS:SP 

0FCh 0FCh SS:SP 

000h

100h

0FCh 0FCh SS:SP 

000h

100h

0FCh 0FCh

Trang 14

3 Hoạt động của lời gọi thủ tục:

Khi thực hiện lời gọi thủ tục (CALL) thì:

 Địa chỉ ô của lệnh kế lệnh CALL (*) sẽ được cất vào ngăn xếp

 Địa chỉ ô của lệnh đầu tiên trong thủ tục được đưa vào IP

Khi thực hiện lệnh RET để quay về trình gọi thì:

 Địa chỉ trong ngăn xếp được lấy ra và được vào IP

Do đó, nếu trong thủ tục có thao tác với ngăn xếp thì trong thủ tục, trước khi thao tác với ngăn xếp ta nên lưu lại địa chỉ (*) ở trên (chính là giá trị hiện thời trong ngăn xếp) để quay trở về trình gọi Xem mô tả trong ví dụ sau

Ví dụ: Nhập xuất chuỗi kí tự

Trang 15

5 Trả lại địa chỉ quay về

BX = địa chỉ lệnh “CALL Xuat”

000h

0FCh 0FCh 100h SS:SP 

0FCh 0FCh SS:SP 

0FCh 0FCh SS:SP 

000h

0FCh 100h 0FCh SS:SP 

Trang 16

Macro

1 Một số lưu ý:

 Khi chúng ta có nhiều đoạn code giống nhau, chúng ta có thể sử dụng macro để thay thế, giống như chúng ta dùng define ở trong C

Bản chất là thay thế lời gọi macro bằng các lệnh trong thân macro

 Các macro nên phục hồi những thanh ghi mà nó sử dụng trừ những thanh ghi chứa

Tạo macro trực tiếp trong chươnng trình:

Các macro thường được khai báo ở đầu chương trình trước phần code

Ví dụ: Xuất một chuỗi ra màn hình sử dụng macro

.model small stack 100h data

chuoi1 db “hello”,10,13,‟$‟

chuoi2 db “bye”,10,13,‟$‟

@xuatchuoi macro chuoi

lea dx,chuoi mov ah,9 int 21h endm

 Xây dựng thư viện các macro:

Tạo 1 thư viện (tập tin) chứa các macro

include vào chương trình (thường trước phần code) bằng lệnh include

Ví dụ: Xuất một chuỗi ra màn hình sử dụng thư viện macro

THUVIEN.INC

@xuatchuoi macro chuoi

lea dx,chuoi mov ah,9 int 21h endm

Trang 17

TestMacro.asm

.model small stack 100h data

4 Các thành phần cục bộ của macro:

 Trong macro, ta cũng có thể khai báo các biến, nhãn cục bộ để tránh gây ra lỗi khi

gọi macro nhiều lần

Cú pháp :

LOCAL <danh sách các nhãn, các biến cục bộ>

Ví dụ: Xuất một chuỗi hằng ra màn hình sử dụng macro với biến cục bộ

.model small stack 100h

@xuatchuoi macro chuoi LOCAL chuoicucbo, nhancucbo .data

chuoicucbo db chuoi,‟$‟

.code

lea dx,chuoicucbo mov ah,9

int 21h endm

.code

… nhancucbo:

Trang 18

Tài liệu tham khảo

1 Nguyễn Minh Tuấn, Giáo trình hợp ngữ - Chương 6, ĐHKHTN, 2002

2 Randal Hyde, The art of assembly language programming – Chapter 11,12

Bài 2: Tính giá trị biểu thức đã nhập ở bài tập 2 theo thứ tự từ trái sang phải

Bài 3: Viết lại các bài tập tuần trước dưới dạng các thủ tục

Bài 4: Xây dựng một thư viện các macro

Ngày đăng: 05/04/2014, 23:58

TỪ KHÓA LIÊN QUAN

TRÍCH ĐOẠN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w