目标:
以创建一个简单的对话框程序为例搭建环境,目标是用到最少的资源,这样我们能够知道一个程序的来龙去脉。
实现:
从Visual Studio 安装环境中拷贝 ML宏汇编器和LINK链接器;拷贝部分.h头文件和.lib链接库文件。
分析:
[工具]C和C++的编译器为CL.EXE,汇编语言的编译器为ML.EXE,这两个程序都能生成COFF格式的目标文件OBJ;然后用通用的LINK.EXE链接器将OBJ文件链接为EXE文件。编译和链接工具准备完毕。
[lib库]Windows系统是基于DLL的,PE文件会记录他引用的所有DLL和这些DLL中的API,链接器LINK必须根据LIB文件才能将OBJ文件链接为EXE,也就是说LIB文件记录API在DLL中的偏移量,必不可少!如果你只做底层测试,我觉得USER32.LIB、KERNEL32.LIB、GDI32.LIB、ADVAPI32.LIB、NTDLL.LIB、NTOSKRNL.LIB就足够了。
[头文件]至于头文件,你可以将Platform SDK 的.h头文件转换为MASM认可的格式,或者根据引用的API在你的源代码中声明下原型,再或者偷懒的方法,从网络上的MASM32集成开发环境直接拷贝,inc扩展名无所谓!
例如,在msdn站点查询到MessageBox函数的原型如下:
int MessageBox(HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption,UINT uType);
对应的汇编一眼声明方式如下:( ExitProcess PROTO :DWORD )
MessageBox proto:dword,:dword,:dword,:dword
我想,照葫芦画瓢,这没什么难度,下面是简单的对话框程序:
;ml /c /coff MessageBox.asm
;link /subsystem:windows MessageBox.obj user32.lib kernel32.lib
.386
.model flat,stdcall
ExitProcess PROTO :DWORD
MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD
MessageBox equ <MessageBoxA>
.data
szContent db 'MessageBox from MASM32! It is so powerful!',0
szCaption db 'MessageBox MASM32',0
.code
start:
;invoke MessageBox,0,offset szContent,addr szCaption,40h
push 40h
lea eax,szCaption
push eax
lea eax,szContent
push eax
push 0
call MessageBox
invoke ExitProcess,0
end start
[环境变量]如上述代码,内置API原型的声明,链接器也直接知名了要引用的lib库,可以不用关心inc头文件,但至少lib库要知道从哪里去查找,还有ml和link工具的路径也需要设置,还需设置lib库和include头文件的环境变量,如下我用到了RadASM这一IDE,我把我的源程序放到c:\codes\masm32,可以新建一个批处理MASM32.BAT:
set include=C:\RadASM\masm32\Include;%include%
set lib=C:\RadASM\masm32\lib;%lib%
set path=C:\RadASM\masm32\bin;%path%
cd C:\codes\MASM32
但批处理运行后就直接退出,你就无法在console上运行ml和link指令流,所以还需要cmd的一个快捷方式,目标设置为%comspec% /k "C:\RadASM\masm32\Masm32.bat" 。如此,环境变量设置完毕!
用include环境变量指明头文件的路径,lib环境变量知名lib库文件的路径,path环境变量知名ml和link的路径,且拷贝了inc头文件和lib库文件的情况下,你的代码和编译方式如下:
;ml /c /coff MessageBox.asm
;link /subsystem:windows MessageBox.obj
.386
.model flat,stdcall
include user32.inc
include kernel32.inc
includelib kernel32.lib
includelib user32.lib
.data
szContent db 'MessageBox from MASM32! It is so powerful!',0
szCaption db 'MessageBox MASM32',0
.code
start:
invoke MessageBox,0,offset szContent,addr szCaption,40h
invoke ExitProcess,0
end start
Easy Code 1.06.0.0020 Masm 推荐编辑器。