32位汇编:实验12动态链接库

创建动态链接库(Sample.dll)

步骤1:创建导出定义文件 Sample.def

在实验目录下新建文本文件:

EXPORTS _Mod

步骤2:创建DLL源代码 Sample.asm

同一目录下创建Sample.asm

.386 .model flat, stdcall option casemap :none ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; Include 文件定义(根据实际路径修改) ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> include D:\\BYQ\\masm32v11r\\masm32\\include\\windows.inc ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .data? dwCounter dd ? ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .code ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; dll 的入口函数 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DllEntry proc _hInstance,_dwReason,_dwReserved mov eax,TRUE ret DllEntry Endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; dll 的导出函数 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _Mod proc uses ecx edx _dwNumber1,_dwNumber2 xor edx,edx mov eax,_dwNumber1 mov ecx,_dwNumber2 .if ecx div ecx mov eax,edx .endif ret _Mod endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> End DllEntry

步骤3:创建头文件 Sample.inc

创建Sample.inc供调用方使用:

`;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; Version 1.0 ; Date: 2004.05.01 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; Sample.dll 导出函数: ; ;invoke _Mod,dwNumber1,dwNumber2 ; 输入:dwNumber1 和 dwNumber2 为两个整数 ; 输出:两数的模 dwNumber1 % dwNumber2 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

_Mod proto dwNumber1:dword,dwNumber2:dword`

步骤4:编译和链接DLL

打开命令提示符,执行:

; 汇编生成目标文件 ml /c /coff Sample.asm

发现环境变量忘记添加了

这里因为个人环境原因我们设置临时环境变量

再次进行汇编

汇编成功 ; 链接生成DLL Link /subsystem:windows /Dll /Def:Sample.def Sample.obj

目录下生成 Sample.dll, Sample.lib, Sample.exp


创建调用程序(UseDll.exe)

步骤5:创建资源文件 UserDll.rc

准备图标文件Main.ico

创建UserDll.rc

#include <resource.h> //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> #define ICO_MAIN 1000 #define DLG_MAIN 1000 #define IDC_NUM1 1004 #define IDC_NUM2 1005 #define IDC_MOD 1006 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ICO_MAIN ICON "Main.ico" //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> DLG_MAIN DIALOG 186, 132, 173, 79 STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU CAPTION "DLL例子" FONT 9, "宋体" { GROUPBOX "取模函数测试", -1, 4, 37, 164, 32, BS_GROUPBOX EDITTEXT IDC_NUM1, 11, 50, 43, 12, ES_NUMBER LTEXT "%", -1, 57, 52, 5, 8 EDITTEXT IDC_NUM2, 64, 50, 43, 12, ES_NUMBER LTEXT "=", -1, 110, 52, 5, 8 EDITTEXT IDC_MOD, 117, 50, 43, 12, ES_READONLY }

步骤6:创建调用程序源码 UserDll.asm

创建UserDll.asm

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .386 .model flat, stdcall option casemap :none ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; Include 文件定义(根据实际路径修改) ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> include D:\\BYQ\\masm32v11r\\masm32\\include\\windows.inc include D:\\BYQ\\masm32v11r\\masm32\\include\\user32.inc includelib D:\\BYQ\\masm32v11r\\masm32\\lib\\user32.lib include D:\\BYQ\\masm32v11r\\masm32\\include\\kernel32.inc includelib D:\\BYQ\\masm32v11r\\masm32\\lib\\kernel32.lib include Sample.inc includelib Sample.lib ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ; Equ 等值定义 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ICO_MAIN equ 1000 DLG_MAIN equ 1000 IDC_NUM1 equ 1004 IDC_NUM2 equ 1005 IDC_MOD equ 1006 ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> .code ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> _ProcDlgMain proc uses ebx edi esi hWnd,wMsg,wParam,lParam mov eax,wMsg .if eax == WM_CLOSE invoke EndDialog,hWnd,NULL .elseif eax == WM_COMMAND mov eax,wParam .if ax == IDC_NUM1 || ax == IDC_NUM2 invoke GetDlgItemInt,hWnd,IDC_NUM1,NULL,FALSE push eax invoke GetDlgItemInt,hWnd,IDC_NUM2,NULL,FALSE pop ecx invoke _Mod,ecx,eax invoke SetDlgItemInt,hWnd,IDC_MOD,eax,FALSE .endif .else mov eax,FALSE ret .endif mov eax,TRUE ret _ProcDlgMain endp ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> start: invoke GetModuleHandle,NULL invoke DialogBoxParam,eax,DLG_MAIN,NULL,offset _ProcDlgMain,NULL invoke ExitProcess,NULL ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> end start


编译和运行调用程序

编译资源、汇编、链接

在工作目录下依次执行:

`; 编译资源 rc UserDll.rc

; 汇编 ml /c /coff UserDll.asm

; 链接 Link /subsystem:windows UserDll.obj UserDll.res`

成功生成exe文件

步骤10:运行程序

UserDll.exe


知识梳理

一、Windows DLL 的基本概念与生命周期

  • 什么是 DLL(动态链接库):运行时由操作系统装载的可执行模块(PE 格式)。它把函数/资源打包供其它程序(或其它 DLL)在运行时调用。好处:代码复用、节省内存、可替换升级。

  • 加载时机

    • 显式加载:LoadLibrary / FreeLibrary

    • 隐式加载:程序在链接时引用了 DLL(通过 .lib),进程启动时由 loader 自动加载

  • 生命周期回调 :系统在装载/卸载或线程创建/退出时会调用 DLL 主入口 DllMain(也叫 DllEntry)。

    • DllMain(hinst, DLL_PROCESS_ATTACH, NULL):进程装载

    • DLL_PROCESS_DETACH:进程卸载

    • DLL_THREAD_ATTACH / DLL_THREAD_DETACH:线程事件(注意:不一定会收到线程事件)

  • DLL 必须返回 TRUE 才能被成功载入 (实验中 mov eax, TRUE 即返回 TRUE)。


二、PE/链接器相关(.def、.lib、.exp、导出表)

  • .def(Module-Definition)文件

    指定导出的符号(函数名/序号)。示例:EXPORTS _Mod。它告诉 linker 将 _Mod 写入导出表(Export Table)。

  • 导出方式

    • 使用 .def(显式列出)

    • 使用编译器关键字 __declspec(dllexport)(C/C++)

  • 生成的文件

    • .dll:运行时要的库

    • .lib(import library):链接时使用(目标程序用它生成对 DLL 的引用),并非静态库

    • .exp:导出信息(中间文件)

  • Export Table / IAT

    • Export Table:DLL 中记录可被外部调用的函数(名字/序号/地址)

    • Import Address Table (IAT):可执行文件或另一个 DLL 的表,运行时被 loader 修补为指向目标 DLL 的实际函数地址(thunk)


三、Calling Convention(调用约定)

实验用的是 stdcall (MASM option casemap:none + invoke 默认用 stdcall)------必须理解:

  • stdcall 特点

    • 参数由右向左压栈(最后一个参数先压)

    • 调用方调用 CALL,被调用方(callee)负责清理栈(ret N

    • 返回值放在 EAX(32-bit 整数),但某些操作(如 div)余数放 EDX

  • cdecl(对比)

    • 同样右向左压栈,但调用者清理栈 ,用于可变参数函数(printf
  • fastcall 等 :部分参数传寄存器(MSVC 有 __fastcall,有平台差异)

  • 在汇编层面要留意 uses 子句_Mod proc uses ecx edx _dwNumber1,_dwNumber2 表示该过程会改写 ecx/edx,MASM 会自动保存/恢复这些寄存器给调用者(自动 push/pop),以防破坏调用者期望的寄存器值(callee-saved vs caller-saved 概念)。

相关推荐
我在人间贩卖青春3 天前
汇编之伪指令
汇编·伪指令
我在人间贩卖青春4 天前
汇编之伪操作
汇编·伪操作
济6174 天前
FreeRTOS基础--堆栈概念与汇编指令实战解析
汇编·嵌入式·freertos
myloveasuka4 天前
汇编TEST指令
汇编
我在人间贩卖青春4 天前
汇编编程驱动LED
汇编·点亮led
我在人间贩卖青春4 天前
汇编和C编程相互调用
汇编·混合编程
myloveasuka5 天前
寻址方式笔记
汇编·笔记·计算机组成原理
请输入蚊子5 天前
《操作系统真象还原》 第六章 完善内核
linux·汇编·操作系统·bochs·操作系统真像还原
myloveasuka5 天前
指令格式举例
汇编·笔记·计算机组成原理
我在人间贩卖青春5 天前
汇编之分支跳转指令
汇编·arm·分支跳转