.WHILE TRUE ; Enter message loop invoke GetMessage, ADDR msg,NULL,0,0 .BREAK .IF (!eax) invoke TranslateMessage, ADDR msg invoke DispatchMessage, ADDR msg .ENDW mov eax,msg.wParam ; return exit code in eax ret WinMain endp
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM .IF uMsg==WM_DESTROY ; if the user closes our window invoke PostQuitMessage,NULL ; quit our application .ELSE invoke DefWindowProc,hWnd,uMsg,wParam,lParam ; Default message processing ret .ENDIF xor eax,eax ret WndProc endp
end start
分析:
看到一个简单的 Windows 程序有这么多行,您是不是有点想撤? 但是您必须要知道的是上面的大多数代码都是模板而已,模板的意思即是指这些代码对差不多所有标准 Windows 程序来说都是相同的。在写 Windows 程序时您可以把这些代码拷来拷去,当然把这些重复的代码写到一个库中也挺好。其实真正要写的代码集中在 WinMain 中。这和一些 C 编译器一样,无须要关心其它杂务,集中精力于 WinMain 函数。唯一不同的是 C 编译器要求您的源代码有必须有一个函数叫 WinMain。否则 C 无法知道将哪个函数和有关的前后代码链接。相对C,汇编语言提供了较大的灵活性,它不强行要求一个叫 WinMain 的函数。
下面我们开始分析,您可得做好思想准备,这可不是一件太轻松的活。
.386 .model flat,stdcall option casemap:none
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD
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
您可以把前三行看成是"必须"的.
.386告诉MASN我们要用80386指令集。 . model flat,stdcall告诉MASM 我们用的内存寻址模式,此处也可以加入stdcall告诉MASM我们所用的参数传递约定。
接下来是函数 WinMain 的原型申明,因为我们稍后要用到该函数,故必须先声明。我们必须包含 window.inc 文件,因为其中包含大量要用到的常量和结构的定义,该文件是一个文本文件,您可以用任何文本编辑器打开它, window.inc还没有包含所有的常量和结构定义,不过 hutch 和我一直在不断加入新的内容。如果暂时在 window.inc 找不到,您也可以自行加入。
我们的程序调用驻扎在 user32.dll (譬如:CreateWindowEx, RegisterWindowClassEx) 和 kernel32.dll (ExitProcess)中的函数,所以必须链接这两个库。接下来我如果问:您需要把什么库链入您的程序呢 ? 答案是:先查到您要调用的函数在什么库中,然后包含进来。譬如:若您要调用的函数在 gdi32.dll 中,您就要包含gdi32.inc头文件。和 MASM 相比,TASM 则要简单得多,您只要引入一个库,即:import32.lib。<译者注:但 Tasm5 麻烦的是 windows.inc 非常的不全面,而且如果在 Windows.inc 中包含全部的 API 定义会内存不够,所以每次你得把用到的 API 定义拷贝出来>
(编辑:aniston)
|