Tài liệu Xây dựng thư viện liên kết động trong MASM doc - Pdf 87



Trang 1
Xây dựng thư viện liên kết động trong MASM
Translated and Written by NhatPhuongLe
www.reaonline.net

Tutorial 17
Building a DLL in MASM32


trong ngôn ngữ lập trình C là ví dụ dễ thấy nhất.
Liên kết tĩnh không hiệu quả bởi vì đoạn mã để thực thi một hàm thường phải nhúng
nhiều lần vào các tập tin .EX
E khác nhau. Không gian đĩa cứng của bạn sẽ tốn nhiều bộ
nhớ để lưu trữ các bản sao của hàm. Tuy nhiên, phương pháp này có thể chấp nhận được
bởi vì thường chỉ có một chương trình được gọi thực thi trên bộ nhớ. Tuy nhiên, dưới nền
tảng Windows thì việc tiết kiệm bộ nhớ được quan tâm hơn bởi vì có thể có nhiều chương
trình chạy cùng lúc. Lúc này, bộ nhớ được chia
nhau sử dụng bởi các chương trình, và nếu
như chương trình bạn càng lớn thì nó sẽ “ngốn” bộ nhớ càng nhiều. Windows đã đưa ra
hướng giải quyết cho vấn đề này là thư viện liên kết động. Windows sẽ không nạp các bản
sao của một DLL lên bộ nhớ vì thế thậm chí có nhiều thể hiện của chương trình đang chạy
cùng 1 lúc, cũng chỉ có duy nhất một bản sao của DLL
mà chương trình đang sử dụng được
nạp lên bộ nhớ.
Tôi giải thích rõ hơn cho bạn hiểu. Thực ra, tất cả các tiến trình đều sử dụng chung
một DLL, mà DLL này chính là bản sao của chính nó. Điều này thì tương tự như là có nhiều
bản sao của DLL trong bộ nhớ. Nhưng trong thực tế, Windows sẽ “thực hiện” điều này bằng
cách phân trang bộ nhớ và tất cả các tiến trình sẽ chia sẻ m
ã nguồn của cùng 1 DLL. Vì thế
trong bộ nhớ vật lý, chỉ có duy nhất một bản sao của mã nguồn DLL. Tuy nhiên, mỗi tiến
trình sẽ có một section dữ liệu của DLL cho riêng nó.
Chương trình liên kết với DLL lúc thực thi không giống như kiểu liên kết tĩnh cũ. Đó
là lý do tại sao nó được gọi là thư viện liên kết động. Bạn cũng có thể giải phóng DLL tại
thời điểm biên dịch khi bạn không sử dụng nó
nữa. Nếu như chỉ có một chương trình của
bạn sử dụng DLL, nó sẽ được giải phóng ra khỏi bộ nhớ ngay lập tức. Nhưng nếu như DLL
này vẫn được sử dụng bởi các chương trình khác, thì DLL vẫn còn nằm trên bộ nhớ cho
đến khi chương trình cuối cùng sử dụng nó xong và yêu cầu giải phóng nó ra khỏi bộ nhớ.
Tuy nhiên, trình linker sẽ có một nhiệm vụ khó hơn phải làm đó là fi

trình của bạn không thể run thậm chí nếu như DLL không thật sự cần t
hiết cho xử lý
trong chương trình chính đang gọi. Nhưng khi bạn nạp DLL theo cách của bạn thì khi
DLL không được tìm thấy và nó không cần thiết cho xử lýu của chương trình, thì
chương trình chỉ thông báo cho bạn biết và chương trình vẫn run tốt.
 Nếu bạn sử dụng LoadLibrary, bạn phải gọi hàm GetProcAddress cho mỗi hàm mà
bạn muốn gọi. GetProAddress sẽ cho bạn địa chỉ entrypoint của một hàm trong DLL
có liên quan. Vì thế mã nguồn của bạn có thể dài
hơn một tí và chậm hơn một chút
khi thực thi. Tuy nhiên, nó không đáng kể so với thuận lợi, bạn có thể nạp DLL
không cần nhờ loader.
Thấy được ưu và khuyết điểm của việc gọi hàm LoadLibrary, chúng ta sẽ đi vào chi tiết
làm thế nào để tạo một DLL.
Đây là cấu trúc của một DLL chuẩn:
DLLSkeleton.asm
.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

DllEntry proc hInstance:HINSTANCE,reason:DWORD, reserved1:DWORD
...
mov eax,TRUE
ret
DllEntry Endp

nhãn END

End DllEntry
Hàm này nhận vào 3 tham số, trong đó có 2 tham số quan trọng là hInstance và
reversed1:
 Tham số đầu tiên mà hàm này sử dụng là mã thể hiện của thư viện hay còn gọi
là instance handle (tìm hiểu sâu vào kiến trúc Windows 32-bits, bạn sẽ thấy
instacne handle chính là địa chỉ vùng nhớ đầu tiên nơi thư viện DLL được nạp
vào). Nếu thư viện của bạn sử dụng đến những tài nguyên yêu cầu cung cấp mã
thể hiện của chương trình gọi (như Dialogbox chẳng hạn) thì bạn cần phải lưu
biến hInstan
ce này như một biến toàn cục.
 Tham số thứ 2 là reason, tham số này có thể mang 4 giá trị cho biết nguyên do
và tại sao Dll được Windows nạp vào bộ nhớ. Trong phần tiếp theo đây, bạn hãy
hình dung ngữ cảnh trong đó một chương trình ứng dụng được cho kích hoạt và
chạy nhiều lần song song với nhau. Mỗi lần chương trình được gọi, Windows
xem đó như là một tiến trình (process). Mỗi tiến trình nằm trong một vùng không
gian địa chỉ ảo độc lập với nhau.
Giá trị tham
số reason Ý nghĩa
DLL_PROCESS_ATTACH
 Hàm DllEntry với tham số
DLL_PROCESS_ATTACH được gọi khi process
tiến hành load DLL
 Thư viện DLL đang được Windows ánh xạ vào
vùng nhớ của tiến trình (thực hiện lời gọi DLL)
 Đây là thời điểm để DLL khởi tạo các biến, cấp
phát vùng nhớ hay những thao tác cần thiết
khác trước khi cho phép tiến trình gọi đến các
hàm của thư viện

LoadLibrary thì tất cả các t
iểu trình hiện có
(trong tiến trình) sẽ không gọi hàm DllEntry với
tham số này.
DLL_THREAD_DETACH
 Khi 1 tiểu trình kết thúc, Windows gọi hàm
DllEntry của tất cả các thư viện DLL đang được
sử dụng với tiểu trình này.
 Đây là thời điểm để giải phóng các biến dùng
cho tiểu trình
 Tham số cuối cùng truyền cho hàm DllEntry là reversed1 được hệ thống dành
cho mục đích riêng.
Bạn trả về giá
trị TRUE cho thanh ghi EAX, nếu như bạn muốn DLL chạy. Ngược lại,
nếu EAX chứa giá trị FALSE thì DLL sẽ không được nạp. Ví dụ, nếu code khởi tạo chỉ
định một số vùng nhớ và nó không thể làm điều đó thành công, thì hàm DllEntry sẽ trả
về giá trị FALSE để chỉ ra rằng DLL không thể chạy được.
Bạn có thể đặt các hàm
của bạn trong DLL trước hoặc sau entrypoint đều được.
Nhưng nếu bạn muốn nó có thể được gọi từ chương trình khác bạn phải đặt các hàm
trong export list chính là danh sách các hàm được export ra bên ngoài cho các DLL hoặc
chương trình khác sử dụng trong file định nghĩa (.DEF)
LIBRARY DLLSkelton
EXPORTS Function
Thông thường, bạn phải có dòng đầu tiên. Phát biểu LIBRARY sẽ định nghĩa tên
module bên trong của DLL. Bạn nên để nó phù hợp với tên file của DLL (trong ví dụ này
là DLLSkeleton). Phát biểu EXPORTS sẽ nói cho trình linker biết những hàm nào trong
DLL được export, đó là những hàm có thể được gọi bởi các chương trình khác. Trong ví
dụ này, chúng ta muốn các modules khác có thể gọi hàm Function, vì thế ta đặt tên của
hàm này (Function) phía sau phát biểu EXPORT.


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