使用C库函数
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| .386 .model flat,stdcall OPTION CASEMAP:none
include msvcrt.inc include kernel32.inc
includelib user32.lib includelib kernel32.lib includelib msvcrt.lib;包含动态库 ;includelib libc.lib;包含静态库
.const MY_STRING db "51asm51asm:%d",0dh,0ah,0 MY_PAUSE db "pause",0
;代码区 .code
myadd proc ret myadd endp
strlen proto c:dword printf proto c:VARARG
START proc ;C库的使用 c调用约定 local buf1[10]:byte local buf2[10]:byte
;invoke strlen,offset MY_STRING ;invoke printf,offset MY_STRING
;push offset MY_STRING ;call printf ;add esp,4
;invoke myadd,1,2,3 ;push 3 ;push 2 ;push 1 ;call myadd ;add esp,12
invoke crt_strcpy,addr buf1,offset MY_STRING invoke crt_strcpy,addr buf2,offset MY_STRING invoke crt_printf,offset MY_STRING,10 invoke crt_system,offset MY_PAUSE invoke ExitProcess,0 ret START endp
end START
|
指令集和模型设置
1 2 3
| .386 .model flat,stdcall OPTION CASEMAP:none
|
- **
.386
**:指定代码针对80386处理器编写,这是一个32位处理器。
- **
.model flat,stdcall
**:指定内存模型为平坦(flat),调用约定为stdcall
,即所有的内存视为一个单一段。
- **
OPTION CASEMAP:none
**:指定汇编器对所有标签和符号区分大小写,不自动转换大小写。
包含头文件
1 2
| include msvcrt.inc include kernel32.inc
|
- **
include msvcrt.inc
**:包含MSVCRT库(Microsoft Visual C Runtime Library)的函数声明和宏。
- **
include kernel32.inc
**:包含Kernel32库(Windows内核库)的函数声明和宏。
链接动态库
1 2 3
| includelib user32.lib includelib kernel32.lib includelib msvcrt.lib
|
- **
includelib user32.lib
**:链接用户界面相关的User32库。
- **
includelib kernel32.lib
**:链接与操作系统核心功能相关的Kernel32库。
- **
includelib msvcrt.lib
**:链接C运行时库MSVCRT的动态库。
定义常量
1 2 3
| .const MY_STRING db "51asm51asm:%d",0dh,0ah,0 MY_PAUSE db "pause",0
|
- **
MY_STRING
**:定义一个字符串常量,内容是”51asm51asm:%d”,后面跟着回车换行符0dh, 0ah
和字符串终止符0
。
- **
MY_PAUSE
**:定义一个字符串常量,内容是”pause”,用于暂停命令行窗口。
函数定义
1 2 3
| myadd proc ret myadd endp
|
- **
myadd
**:定义一个空函数myadd
,使用proc
关键字开始函数,ret
指令返回到调用者,endp
结束函数定义。
外部函数声明
1 2
| strlen proto c:dword printf proto c:VARARG
|
- **
strlen
**:声明C库函数strlen
,用于计算字符串长度。
- **
printf
**:声明C库函数printf
,用于格式化输出。VARARG
是 printf
等函数的一个特殊调用约定,用于表示该函数可以接受可变数量的参数。
主程序开始
1 2 3
| START proc local buf1[10]:byte local buf2[10]:byte
|
- **
START proc
**:定义程序入口START
。
- **
local buf1[10]:byte
和local buf2[10]:byte
**:定义两个局部字节数组buf1
和buf2
,各自长度为10个字节。
1 2
| ;invoke strlen,offset MY_STRING ;invoke printf,offset MY_STRING
|
- 这些注释掉的代码原本是调用
strlen
和printf
函数,但当前未执行。
调用库函数
1 2 3 4
| invoke crt_strcpy,addr buf1,offset MY_STRING invoke crt_strcpy,addr buf2,offset MY_STRING invoke crt_printf,offset MY_STRING,10 invoke crt_system,offset MY_PAUSE
|
- **
invoke crt_strcpy,addr buf1,offset MY_STRING
**:将MY_STRING
复制到buf1
中,调用的是C库的strcpy
函数。
- **
invoke crt_strcpy,addr buf2,offset MY_STRING
**:将MY_STRING
复制到buf2
中,调用同样的strcpy
函数。
- **
invoke crt_printf,offset MY_STRING,10
**:使用C库的printf
函数输出格式化字符串MY_STRING
,参数为10
。
- **
invoke crt_system,offset MY_PAUSE
**:调用系统命令pause
,暂停命令行窗口的关闭。
程序结束
1 2 3
| invoke ExitProcess,0 ret START endp
|
- **
invoke ExitProcess,0
**:调用ExitProcess
函数退出程序,返回值为0
。
- **
ret
**:从程序入口返回。
- **
START endp
**:结束程序入口的定义。
运行结果
调用对话框
新建对话框
示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| .386 .model flat,stdcall OPTION CASEMAP:none
include msvcrt.inc include kernel32.inc include user32.inc include windows.inc
includelib user32.lib includelib kernel32.lib includelib msvcrt.lib;包含动态库 ;includelib libc.lib;包含静态库
IDD_DIALOG1 EQU 101
.const MY_STRING db "51asm51asm:%d",0dh,0ah,0 MY_PAUSE db "pause",0
;代码区 .code DialogProc PROC hwndDlg:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM .IF uMsg==WM_CLOSE invoke EndDialog,hwndDlg,0 mov eax,TRUE ret .endif mov eax,FALSE ret DialogProc endp
START proc local @hInstance:HINSTANCE invoke GetModuleHandle,NULL mov @hInstance,eax invoke DialogBoxParam,@hInstance,IDD_DIALOG1,NULL,OFFSET DialogProc,NULL invoke ExitProcess,0 ret START endp
end START
|
这段代码是一个汇编程序,使用Win32 API创建了一个简单的对话框应用程序。下面是每一行代码的详细解释:
指令集和模型设置
1 2 3
| .386 .model flat,stdcall OPTION CASEMAP:none
|
- **
.386
**:指定代码是为80386处理器编写的,这是一个32位的处理器。
- **
.model flat,stdcall
**:指定内存模型为平坦(flat),调用约定为stdcall
,即所有的内存视为一个单一段。
- **
OPTION CASEMAP:none
**:指定汇编器对所有标签和符号区分大小写,不自动转换大小写。
包含头文件
1 2 3 4
| include msvcrt.inc include kernel32.inc include user32.inc include windows.inc
|
- **
include msvcrt.inc
**:包含MSVCRT库(Microsoft Visual C Runtime Library)的函数声明和宏。
- **
include kernel32.inc
**:包含Kernel32库(Windows内核库)的函数声明和宏。
- **
include user32.inc
**:包含User32库(用户界面相关的Windows API)的函数声明和宏。
- **
include windows.inc
**:包含Windows API的基本数据类型和常量的定义。
链接动态库
1 2 3 4
| includelib user32.lib includelib kernel32.lib includelib msvcrt.lib;包含动态库 ;includelib libc.lib;包含静态库
|
- **
includelib user32.lib
**:链接用户界面相关的User32库。
- **
includelib kernel32.lib
**:链接与操作系统核心功能相关的Kernel32库。
- **
includelib msvcrt.lib
**:链接C运行时库MSVCRT的动态库。
includelib libc.lib
(被注释掉):这是静态库的链接声明,已被注释,不实际使用。
定义常量
- **
IDD_DIALOG1 EQU 101
**:定义一个对话框资源ID,值为101
。这是对话框资源的唯一标识符。
1 2 3
| .const MY_STRING db "51asm51asm:%d",0dh,0ah,0 MY_PAUSE db "pause",0
|
- **
MY_STRING
**:定义一个字符串常量,内容是 "51asm51asm:%d"
,后面跟着回车换行符 0dh, 0ah
和字符串终止符 0
。
- **
MY_PAUSE
**:定义一个字符串常量,内容是 "pause"
,用于暂停命令行窗口。
对话框处理过程
1 2 3 4 5 6 7 8 9
| DialogProc PROC hwndDlg:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM .IF uMsg==WM_CLOSE invoke EndDialog,hwndDlg,0 mov eax,TRUE ret .endif mov eax,FALSE ret DialogProc endp
|
- **
DialogProc
**:定义一个对话框过程函数,用于处理对话框的消息。
- **
hwndDlg:HWND
**:对话框窗口的句柄。
- **
uMsg:UINT
**:消息的类型。
wParam:WPARAM
和 **lParam:LPARAM
**:消息的附加参数。
- **
IF uMsg==WM_CLOSE
**:检查接收到的消息是否是 WM_CLOSE
,即关闭对话框的消息。
- **
invoke EndDialog,hwndDlg,0
**:调用 EndDialog
函数关闭对话框,返回值为0
。
- **
mov eax,TRUE
**:将返回值设为 TRUE
,表示消息已处理。
- **
ret
**:返回到调用者。
- **
mov eax,FALSE
**:如果消息不是 WM_CLOSE
,则返回 FALSE
,表示消息未处理。
- **
DialogProc endp
**:结束对话框过程函数的定义。
主程序开始
1 2 3 4 5 6 7 8
| START proc local @hInstance:HINSTANCE invoke GetModuleHandle,NULL mov @hInstance,eax invoke DialogBoxParam,@hInstance,IDD_DIALOG1,NULL,OFFSET DialogProc,NULL invoke ExitProcess,0 ret START endp
|
**START proc
**:定义程序的入口函数 START
。
**local @hInstance:HINSTANCE
**:定义一个局部变量 @hInstance
,类型为 HINSTANCE
,用于存储当前模块的实例句柄。
**invoke GetModuleHandle,NULL
**:调用 GetModuleHandle
函数获取当前模块的实例句柄,并将其存储在 @hInstance
中。
**mov @hInstance,eax
**:将函数返回值(当前模块的句柄)存储在 @hInstance
中。
**invoke DialogBoxParam,@hInstance,IDD_DIALOG1,NULL,OFFSET DialogProc,NULL
**:调用 DialogBoxParam
函数创建并显示对话框。参数分别为:
@hInstance
:当前模块的实例句柄。
IDD_DIALOG1
:对话框的资源ID。
NULL
:父窗口句柄(无父窗口)。
OFFSET DialogProc
:对话框过程函数的地址。
NULL
:传递给对话框过程函数的附加参数(无)。
**invoke ExitProcess,0
**:调用 ExitProcess
函数终止程序,返回值为0
。
**ret
**:返回到调用者。
**START endp
**:结束程序入口函数的定义。
运行结果