LOGO

HỢP NGỮ và LẬP TRÌNH HỆ THỐNG

Phạm Công Hòa GV: Tel: 091.552.9889 Email: conghoaf1@gmail.com

NỘI DUNG HỌC PHẦN

NGÔN NGỮ ASSEMBLER (ASM) VÀ CÁCH LẬP TRÌNH

I

LIÊN KẾT NGÔN NGỮ BẬC CAO VỚI ASM

II

III LẬP TRÌNH HỆ THỐNG

LIÊN KẾT NGÔN NGỮ BẬC CAO VỚI ASM

II

1. Ngôn ngữ C và hợp ngữ

2. Ngôn ngữ Pascal và hợp ngữ

1. Ngôn ngữ C và hợp ngữ

- Mục đích: Tận dụng được sức mạnh của hai loại ngôn ngữ. - Để liên kết các đoạn chương trình hợp ngữ vào ngôn ngữ C/C++ (hoặc Pascal) thì người ta thường sử dụng một trong hai cách:

+ Sử dụng inline assembly (viết dòng lệnh ASM trong C/C++). + Viết tách biệt các module.

1. Ngôn ngữ C và hợp ngữ

1.1. Sử dụng inline assembly

- Chèn các khối lệnh hợp ngữ vào chương trình được viết bằng ngôn ngữ C

- Cú pháp (Turbo C):

Các lệnh ASM

asm { }

Chú ý: Từ khóa asm và dấu ‘{‘ phải cùng nằm trên một dòng.

1. Ngôn ngữ C và hợp ngữ

1.1. Sử dụng inline assembly

-Với môi trường DevC, Visual C++ ta sử dụng các thanh ghi 32 bit (EAX, EBX,…). Đoạn lệnh có cú pháp:

asm("assembly code");

hoặc:

__asm__ ("assembly code");

1. Ngôn ngữ C và hợp ngữ

1.1. Sử dụng inline assembly

float a,b,tong; printf("Nhap 2 so thuc: " ); scanf ("%f%f", &a, &b ); __asm__ ("fld %1;"

printf("%f+%f = %f\n",a,b,tong);

- Đoạn lệnh sau tính và hiện tổng 2 số thực ra màn hình (DevC) "fld %2;" "faddp;" "fstp %0;":"=g"(tong):"g"(a),"g"(b)) ;

1. Ngôn ngữ C và hợp ngữ

- Ví dụ 1: Viết chương trình C khai báo và khởi gán 1 xâu ký tự. Dùng các lệnh ASM hiện xâu ký tự ra màn hình.

lea dx,s mov ah,9 int 21h

char s[]="Hello World!$"; clrscr(); asm{ } getch();

(tệp vd01.c) #include void main() { }

1. Ngôn ngữ C và hợp ngữ

- Chú ý: Các biến được khai báo trong C được coi như các biến “toàn cục” sử dụng chung cho cả C và các inline - assembly. Ví dụ chương trình dưới đây tính tổng 2 số nguyên x và y rồi lưu kết quả vào biến sum.

mov ax,x add ax,y mov sum,ax

int x,y, sum; printf (“x = ”); scanf(“%d”,&x); printf (“y = ”); scanf(“%d”,&y); asm { } printf (“Tong la: %d”, sum); getch();

(tệp vd02.c) #include #include void main() { }

1. Ngôn ngữ C và hợp ngữ

 Nhược điểm của phương pháp Inline Assembly:

- Inline assembly liên quan đến kích cỡ của các biến tự động của ngôn ngữ C.

- Các lệnh nhảy trong phương pháp liên kết Inline Assembly chỉ có thể nhảy đến các nhãn C.

- Việc bảo vệ thanh ghi segment.

1. Ngôn ngữ C và hợp ngữ

 Ví dụ về Inline Assembly

• Ví dụ 3: (tệp vd03.c) Viết chương trình inline asm nhập 2 số nguyên a và b, hiện ra màn hình giá trị nhỏ nhất giữa a và b.

• Ví dụ 4: (tệp vd04.c) Viết chương trình inline asm nhập một mảng N phần tử nguyên, tính và hiện tổng các số âm của mảng. Trong đó phần inline thực hiện chức năng (hàm) tính tổng âm.

1. Ngôn ngữ C và hợp ngữ

- Đối với các chương trình lớn thì các module được tổ chức trong các file khác nhau. Ta có thể viết các module C và hợp ngữ hoàn toàn tách biệt, sau đó tiến hành dịch riêng rẽ từng module và liên kết chúng với nhau trước khi cho chạy. Cuối cùng ta thu được một file thực hiện được (exe) bằng cách trộn các file được viết bằng C và ASM.

1.2. Viết tách biệt các module hợp ngữ và C

Tệp *.C

Tệp *.ASM

Liên kết tlink

Tệp *.exe

1. Ngôn ngữ C và hợp ngữ

tệp ngôn ngữ C (file_name1.c)

tệp ngôn ngữ Assembly (file_name2.asm)

Assemble

Compile

Turbo

Turbo C

Dịch

Dịch

Assembler

tệp mã máy .obj

tệp mã máy .obj

(file_name1.obj)

(file_name2.obj)

Tlink

TLINK

Liên kết

tệp thực hiện được dạng .exe (file_name1.exe)

1.2. Viết tách biệt các module hợp ngữ và C

1. Ngôn ngữ C và hợp ngữ

 Các vấn đề cần phải giải quyết khi viết tách các module C và module hợp ngữ

 Module C:

• Các biến/hàm khai báo toàn cục trong C cũng được hiểu là public trong các module asm. • Muốn sử dụng một nhãn (chương trình con bên ASM) phải khai báo với từ khóa extern: extern tên_biến/tên_hàm

1. Ngôn ngữ C và hợp ngữ

 Module hợp ngữ (asm):

 Phải sử dụng sự sắp xếp các đoạn bộ nhớ (segment) tương thích với ngôn ngữ C.

 Khai báo PUBLIC trước những nhãn (tên biến, tên hàm…) mà các file khác sẽ sử dụng đến.  Khai báo EXTRN trước những biến ngoài được file này sẽ sử dụng đến.  Thêm dấu _ (underscore) vào trước các nhãn, biến, hàm dùng chung.

1. Ngôn ngữ C và hợp ngữ

 Vấn đề truyền tham số:

• Thông qua biến toàn cục. • Thông qua ngăn xếp.

1. Ngôn ngữ C và hợp ngữ

Kiểu khai báo dữ liệu trong ngôn ngữ C/C++ Kiểu khai báo dữ liệu trong ngôn ngữ Assembly

word

unsigned short, short, unsigned int, int

unsigned char, char, enum byte

unsignd long, long, float dword

double qword

long double tword

near* word

17

far* dword

1. Ngôn ngữ C và hợp ngữ

- Các bước chuẩn bị và dịch chương trình liên kết:

• Soạn thảo tệp tepC.c • Soạn thảo tệp tepASM.asm

(tệp của C) (tệp của ASM)

+ Xem chi tiết trong “Hướng dẫn cài đặt môi trường liên kết ASM và C” trên site môn học.

- Sau khi soạn thảo xong 2 tệp trên, chạy tệp run.bat để dịch thành tệp kết quả (.exe)

1. Ngôn ngữ C và hợp ngữ

 Ví dụ 5: Viết chương trình liên kết giữa asm và C thực hiện:

 Một số ví dụ

o Tệp C: Nhập 3 số nguyên a,b,c. Gọi hàm tìm Min(a,b,c) bên asm và hiện giá trị nhỏ nhất ra màn hình. (demo: tệp vd05a.asm và vd05c.c) *)Chú ý: 2 tệp C và ASM phải đặt tên khác nhau)

o Tệp asm: Tìm giá trị nhỏ nhất của 3 số nguyên a,b,c (a,b,c nhận từ module C truyền sang)

1. Ngôn ngữ C và hợp ngữ

 Vấn đề về truyền tham số với các hàm ASM

- Các hàm của ngôn ngữ C/C++ có thể có đối số hoặc không.

- Các hàm của ngôn ngữ Assembly thuần túy (hàm và chương trình gọi nó đều được viết bằng ngôn ngữ Assembly) không có đối.

=> Người viết ngôn ngữ C đưa các tham số thực vào ngăn xếp và người viết hàm bằng ngôn ngữ Assembly phải vào ngăn xếp lấy các giá trị đó ra để xử lý.

Hai vấn đề cần giải quyết: - Chuyển giao tham số như thế nào? - Việc sử dụng các thanh ghi và việc bảo tồn nó?

1. Ngôn ngữ C và hợp ngữ

a) Chuyển giao tham số

- Khi gọi hàm các tham số sẽ chuyển cho hàm vào ngăn xếp theo thứ tự từ phải sang trái:

Lệnh gọi hàm:

test(i,j,k);

( địa chỉ trở về 2 byte (NEAR) và 4 byte (FAR)

1. Ngôn ngữ C và hợp ngữ

- Sử dụng BP để lưu lại vị trí của các tham số i,j,k

1. Ngôn ngữ C và hợp ngữ

- Để ngăn xếp nhận chính xác các tham số (không phụ thuộc near hay far) ta dùng điều khiển ARG:

ARG tên tham số: kiểu dữ liệu

Ví dụ:

ARG i:word, j:word, k:word PUSH BP mov BP,SP AX,i mov mov BX,j mov CX,k … POP BP

1. Ngôn ngữ C và hợp ngữ

b) Vấn đề sử dụng và bảo tồn các thanh ghi

- Khi gọi hàm ta cần bảo vệ các thanh ghi liên quan đến segment: BP, SP, CS, DS và SS.

- Nếu trong chương trình viết bằng ngôn ngữ C có sử dụng biến khai báo kiểu register thì việc bảo vệ giá trị các thanh ghi SI và DI là cần thiết.

1. Ngôn ngữ C và hợp ngữ

- Giá trị trả về: Kiểu giá trị trả về

Nơi đặt giá trị trả về của hàm

AX

unsigned char, char, enum, unsigned short, short, unsigned int, int, near*

unsignd long, long, far* DX:AX

float, double, long double

25

Đỉnh ngăn xếp 80x87, thanh ghi ST(0)

1. Ngôn ngữ C và hợp ngữ

+ Nhập 2 số nguyên a và b + Gọi hàm tìm ước số chung lớn nhất bên ASM + Hiện kết quả

- Ngôn ngữ C: - Ngôn ngữ ASM:

+ Xây dựng hàm tìm ước số chung lớn nhất của a và b

Ví dụ 6: Viết chương trình hợp ngữ ASM liên kết với C thực hiện yêu cầu: Tìm USCLN của a và b

1. Ngôn ngữ C và hợp ngữ

Khai báo a,b; Nhập a,b; Gọi hàm Uoc_so_chung_lon_nhat của a và b);

Ngôn ngữ C:

extern int USCLN(int a,int b); void main() { }

ARG a:word,b:word

mov REG, [BP+k] ;k là số byte ()

Ngôn ngữ ASM (sử dụng ARG): (demo: tệp vd06a.asm và vd06c.c) Ngôn ngữ ASM (sử dụng stack): (demo: tệp vd06a1.asm và vd06c1.c)

1. Ngôn ngữ C và hợp ngữ

 Ví dụ 7: Viết chương trình nhập một mảng N phần tử nguyên, tính và hiện tổng các phần tử của mảng ra màn hình bằng cả 3 cách: ASM thuần túy, Inline ASM và liên kết giữa ASM và C:

o Tệp asm: Viết chương trình con TONG để tính tổng các phần tử của dãy, kết quả đưa vào thanh ghi AX.

o Tệp C: Nhập mảng N phần tử nguyên. Hiện các phần tử của mảng ra màn hình. Gọi hàm TONG bên module ASM và hiện kết quả.

- Demo ví dụ 6 với các phương án:

(vd07.asm) - xem chương 1 (vd07c.c) - xem ví dụ 3 chương 2 (vd07a1.asm & vd07c1.c)

• ASM thuần túy • Inline ASM • Truyền tham số qua stack

28

LIÊN KẾT NGÔN NGỮ BẬC CAO VỚI ASM

II

1. Ngôn ngữ C và hợp ngữ

2.Ngôn ngữ Pascal và hợp ngữ

29

2. Ngôn ngữ Pascal và hợp ngữ

Tham khảo (học viên tự đọc thêm) các giáo trình

Bài tập thực hành

Bài số 1: Viết chương trình tìm giá trị nhỏ nhất trong hai số bằng ngôn ngữ C có chèn các lệnh của ngôn ngữ Assembly (Inline Assembly).

Bài số 2: Hãy viết chương trình tính tổng dãy số tự nhiên liên tiếp khi cho biết giá trị số đầu và số lượng số cần tính bằng cả 2 cách: Inline Assembly và liên kết C với sự phân công như sau: - Tệp ngôn ngữ C: Nhận giá trị số đầu và số lượng số cần tính. Gọi hàm tính tổng do ngôn ngữ Assembly viết. Hiện kết quả tổng. - Tệp ngôn ngữ Assembly: Viết hàm tính tổng.

Bài số 3: Hãy viết chương trình tính an (với a là số nguyên và n là số nguyên dương) với sự phân công như sau: - Module C: Nhận số a và n. Gọi hàm tính an được viết bằng ngôn ngữ Assembly. Hiện kết quả ra màn hình. - Module Assembly : Viết hàm tính an.

Bài tập thực hành

Bài số 4: Hãy viết chương trình đếm số lượng các phần tử âm của một mảng với sự phân công như sau: - Module C: Nhập mảng nguyên n phần tử. Gọi hàm đếm số lượng phần tử âm được viết bằng ngôn ngữ Assembly. Hiện kết quả ra màn hình. - Module Assembly : Viết hàm đếm số lượng phần tử âm của mảng.

Q & A