您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 国内外标准规范 > Win32汇编教程(基础)
汇编语言基础win32一、引言Win32应用程序一般使用C语言编程,但是在某些需要进行深层编程的情况下,例如Win32应用程序执行机制分析、病毒清除、加密解密等深层编程,或者对于某些速度要求较高的程序,需要使用汇编语言(甚至机器语言)直接编写Win32应用程序。Win32应用程序虽然和其他32位应用程序(例如32位保护模式DOS程序)一样可以使用386汇编语言和保护模式编程,但是Win32应用程序的执行机制与其他32位应用程序有一定的差别,例如消息循环、动态链接等,Win32汇编语言也有其特殊的编程方式。目前国内极少看到有关Win32汇编语言的资料,市面上的汇编语言书籍一般只介绍DOS实模式汇编语言和386保护模式汇编语言,金山公司的《深入Windows编程》一书虽然介绍了使用汇编语言写Windows应用程序的方法,可惜该书只介绍了Win16汇编语言。为了使大家能对Win32汇编语言的基本编程方法有一定的了解,近日得闲,笔者编写了本教程,旨在抛砖引玉,如果本教程能够带领你走进神秘的Win32汇编语言世界,笔者心愿足矣。使用本教程,要求读者具有C语言编写Win32应用程序(Win32SDK编程)的基础。二、进行Win32汇编语言编程的基本软件进行Win32汇编语言编程,应该准备下列基本软件:1、MASM6.11以上版本的汇编器MASM是Microsoft公司的汇编器,这是最基本的软件,必需MASM6.11以上版本才能够汇编Win32汇编语言源程序。不过进行Win32汇编语言编程不必要全套的MASM6.11,只要一个ML.EXE文件就可以了,Windows95DDK中带有MASM6.11c的ML.EXE文件,Windows98DDK中带有MASM6.11d的ML.EXE文件,都可以使用。TurboMASM5.0(TASM)是Borland公司的汇编器,也可以用来汇编Win32汇编语言源程序,但是TASM的部分语法与MASM不同,用于MASM的Win32汇编语言源程序可能需要修改后才能用TASM汇编。本教程中的所有Win32汇编语言源程序都基于MASM。2、Win32SDK进行Win32汇编语言编程需要用到Win32SDK中的资源编译器(RC.EXE)和连接器(LINK.EXE),还需要用到Win32SDK中的引入库文件(KERNEL32.LIB、USER32.LIB、GDI32.LIB等)。如果没有Win32SDK,PlatformSDK也可以,还可以安装VisualC++2.0以上版本的VisualC++,笔者使用的是VisualC++6.0。BorlandC++4.0以上版本的BorlandC++也可以使用,只是资源编译器和连接器的文件名不同,分别是BRC.EXE(BRC32.EXE)和TLINK.EXE(TLINK32.EXE),选项也不尽相同,另外BorlandC++不支持COFF格式的OBJ文件,汇编时不能使用/coff选项。3、汇编语言编辑器一个普通的文本编辑器,用于编辑Win32汇编语言源程序。EDIT、PWB等都可以,VisualC++等编程语言中的编辑器也可以,甚至WORD、WPS97等可以编辑文本文件的字处理软件都可以,不过笔者推荐使用ASMEDIT,这是一个专用的汇编语言编辑器,效果非常好。Win32汇编语言一般使用命令行方式汇编连接,经过一定的设置也可以在某些集成环境(PWB、VisualC++、ASMEDIT等)下汇编连接,还可以使用NMAKE工具,不过本教程中只使用命令行方式汇编连接,也不使用NMAKE工具。三、ANSI字符集API与UNICODE字符集APIWin32API中凡是与字符有关的API都有两种不同的类型:ANSI字符集API和UNICODE字符集API,分别对应ANSI字符和UNICODE字符,WindowsNT支持两种类型的API,Windows95/98只支持ANSI字符集API。在WINDOWS.H头文件和其他Win32API定义头文件中,凡是与字符有关的API都有两种不同的定义,ANSI字符集API以API名称加字符“A”表示,UNICODE字符集API以API名称加字符“W”表示,并使用条件编译和宏定义实现自动根据当前字符集使用对应的API定义,例如GetModuleHandle函数的定义(包括在WINBASE.H头文件中):WINBASEAPIHMODULEWINAPIGetModuleHandleA(LPCSTRlpModuleName);WINBASEAPIHMODULEWINAPIGetModuleHandleW(LPCWSTRlpModuleName);#ifdefUNICODE#defineGetModuleHandleGetModuleHandleW#else#defineGetModuleHandleGetModuleHandleA#endif//!UNICODE与字符有关的数据结构也有类似的定义。本教程考虑到汇编语言使用条件汇编会导致不太直观,全部使用ANSI字符集API,这样也可以保证在Windows95/98和WindowsNT环境下的兼容性,所以本教程中许多API名称和数据结构的名称都加有“A”字符,读者可以方便地改用UNICODE字符集API。四、一个简单的Win32汇编语言程序读者可能一听到“汇编语言”四个字就觉得十分头疼!汇编语言给人的第一印象就是一大堆难以看懂又不直观的指令,而且不结构化,大量的标号、无条件跳转指令(JMP)和条件跳转指令让你难以看懂程序;过程(或者函数)的调用参数传递又不直观,要么直接使用寄存器传递参数,不符合结构化程序设计原则;要么使用堆栈传递参数,又不能有效地检验参数类型……想必Win32汇编语言更麻烦吧!还好,MASM6.0以上版本的汇编器提供了很多结构化汇编语言伪指令,可以方便地实现汇编语言结构化程序设计,当你看完本教程以后,你可能会感觉到:Win32汇编语言并不比C语言麻烦多少。(如果读者看不懂本教程中的汇编语言源程序也不要紧,可以对照MASM6.11的帮助看)和C语言Win32编程需要WINDOWS.H头文件和其他Win32API定义头文件定义常量、数据结构和API一样,Win32汇编语言也需要包含文件(INC文件)定义常量、数据结构和API。不过笔者找了很长时间也没有找到一个完整的可用于Win32汇编语言的WINDOWS.INC文件或者WIN32.INC文件(倒是找到了用于Win16汇编语言的WINDOWS.INC文件),TurboMASM5.0中提供的WIN32.INC文件也不完整,只能用于自带的WAP32例子程序,而且与MASM6.11不太兼容(听说NASM中有完整的WIN32.INC文件,可惜没有找到,也不知道与MASM6.11是否兼容)。笔者只好自己定义常量、数据结构和API(根据WINDOWS.H头文件和其他Win32API定义头文件定义),不过这倒带来了不少好处——可以更好地了解Win32汇编语言的编程方法和原理。笔者编写了一个简单的Win32汇编语言程序,该程序的功能很简单:在屏幕上显示一个消息框。本程序只调用了两个API函数:MessageBox函数和ExitProcess函数,程序如下:包含文件(MSGBOX.INC):UINTTYPEDEFDWORDLPSTRTYPEDEFPTRBYTELPCSTRTYPEDEFLPSTRPVOIDTYPEDEFPTRHANDLETYPEDEFPVOIDHWNDTYPEDEFHANDLEMB_ICONINFORMATION=00000040hMB_OK=00000000hMessageBoxAPROTOstdcall,:HWND,:LPCSTR,:LPCSTR,:UINTExitProcessPROTOstdcall,:UINT源程序(MSGBOX.ASM):.386p.MODELflat,stdcallINCLUDEMSGBOX.INC.STACK4096.DATAWindowTitleBYTE'MsgBox',0Message1BYTE'ThisisasimpleMessageBoxWin32application.',0.CODE_start:INVOKEMessageBoxA,0,ADDRMessage1,ADDRWindowTitle,MB_ICONINFORMATIONorMB_OKINVOKEExitProcess,0PUBLIC_startEND汇编连接本程序的命令如下:ml/c/coff/Cpmsgbox.asmlink/subsystem:windows/entry:_startmsgbox.objkernel32.libuser32.lib汇编命令中的/c选项表示只汇编,不自动连接;/coff选项表示生成COFF格式的OBJ文件(如果使用Borland的连接器不能使用/coff参数);/Cp选项表示标识符区分大小写。连接命令中/subsystem:windows选项表示连接器生成普通Windows可执行文件;/entry:_start选项表示程序入口点是_start标识符。连接时连接KERNEL32.LIB和USER32.LIB引入库。运行汇编连接后生成的MSGBOX.EXE文件,屏幕上将显示出一个消息框,消息框的标题是“MsgBox”,消息框中的字符串是“ThisisasimpleMessageBoxWin32application.”。Win32汇编语言源程序应该由.386p伪指令和.MODELflat,stdcall伪指令开始,指示汇编器汇编386保护模式指令,并使用平坦内存模式(Win32内存模式)和stdcall函数调用方式(Win32标准函数调用方式)。PROTO伪指令定义函数原型(与C语言中函数原型的定义相似),可以定义函数名、调用方式和参数,INVOKE伪指令调用由PROTO伪指令定义的函数,可以方便地传递参数和检查参数类型。MSGBOX.INC文件中使用PROTO伪指令定义API函数,MSGBOX.ASM文件中使用INVOKE伪指令调用API函数,可见MASM6.0以上版本的汇编器提供的结构化汇编语言伪指令大大简化了Win32汇编语言编程(本程序一条汇编语言指令也没有用到)。本程序调用了MessageBox函数显示消息框以后,调用了ExitProcess函数终止程序的执行,ExitProcess函数的作用是终止当前进程。五、显示一个窗口的Win32汇编语言程序学习过Win32SDK编程的读者编写的第一个应用程序可能就是显示一个窗口的C语言程序,笔者也编写了这样一个C语言程序,该程序文件名为SIMPLE.C,程序如下:#includestaticcharszWindowClass[]=SIMPLE;LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam);intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTRlpCmdLine,intnShowCmd){WNDCLASSEXAwcex;HWNDhWnd;MSGmsg;if(!hPrevInstance){wcex.cbSize=sizeof(WNDCLASSEXA);wcex.style=CS_HREDRAW|CS_VREDRAW;wcex.cbClsExtra=0;wcex.cbWndExtra=0;wcex.lpfnWndProc=WndProc;wcex.hInstance=hInstance;wcex.hIcon=LoadIconA(hInstance,IDI_APPLICATION);wcex.hCursor=LoadCursorA(0,IDC_ARROW);wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);wcex.lpszMenuName=NULL;wc
本文标题:Win32汇编教程(基础)
链接地址:https://www.777doc.com/doc-2855870 .html