Win32汇编教程基础.docx

上传人:b****6 文档编号:6229233 上传时间:2023-01-04 格式:DOCX 页数:24 大小:26.37KB
下载 相关 举报
Win32汇编教程基础.docx_第1页
第1页 / 共24页
Win32汇编教程基础.docx_第2页
第2页 / 共24页
Win32汇编教程基础.docx_第3页
第3页 / 共24页
Win32汇编教程基础.docx_第4页
第4页 / 共24页
Win32汇编教程基础.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

Win32汇编教程基础.docx

《Win32汇编教程基础.docx》由会员分享,可在线阅读,更多相关《Win32汇编教程基础.docx(24页珍藏版)》请在冰豆网上搜索。

Win32汇编教程基础.docx

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字符集API

Win32API中凡是与字符有关的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头文件中):

WINBASEAPI

HMODULE

WINAPI

GetModuleHandleA(

LPCSTRlpModuleName

);

WINBASEAPI

HMODULE

WINAPI

GetModuleHandleW(

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):

UINTTYPEDEFDWORD

LPSTRTYPEDEFPTRBYTE

LPCSTRTYPEDEFLPSTR

PVOIDTYPEDEFPTR

HANDLETYPEDEFPVOID

HWNDTYPEDEFHANDLE

MB_ICONINFORMATION=00000040h

MB_OK=00000000h

MessageBoxAPROTOstdcall,:

HWND,:

LPCSTR,:

LPCSTR,:

UINT

ExitProcessPROTOstdcall,:

UINT

源程序(MSGBOX.ASM):

.386p

.MODELflat,stdcall

INCLUDEMSGBOX.INC

.STACK4096

.DATA

WindowTitleBYTE'MsgBox',0

Message1BYTE'ThisisasimpleMessageBox

Win32application.',0

.CODE

_start:

INVOKEMessageBoxA,0,ADDRMessage1,ADDRWindowTitle,

MB_ICONINFORMATIONorMB_OK

INVOKEExitProcess,0

PUBLIC_start

END

汇编连接本程序的命令如下:

ml/c/coff/Cpmsgbox.asm

link/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,程序如下:

#include

staticcharszWindowClass[]="SIMPLE";

LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAM

lParam);

intWINAPIWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPSTR

lpCmdLine,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;

wcex.lpszClassName=szWindowClass;

wcex.hIconSm=LoadIconA(hInstance,IDI_APPLICATION);

if(!

RegisterClassExA(&wcex))returnFALSE;

}

hWnd=CreateWindowExA(0,szWindowClass,"SIMPLE",

WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT,

CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

0,0,hInstance,NULL);

if(!

hWnd)returnFALSE;

ShowWindow(hWnd,nShowCmd);

UpdateWindow(hWnd);

while(GetMessageA(&msg,0,0,0))

{

TranslateMessage(&msg);

DispatchMessageA(&msg);

}

returnmsg.wParam;

}

LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAM

lParam)

{

HDChDC;

PAINTSTRUCTps;

switch(message)

{

caseWM_PAINT:

hDC=BeginPaint(hWnd,&ps);

EndPaint(hWnd,&ps);

return0;

caseWM_DESTROY:

PostQuitMessage(0);

return0;

default:

returnDefWindowProcA(hWnd,message,wParam,lParam);

}

return-1;

}

本程序与一般的显示一个窗口的C语言程序基本相同,只是只使用ANSI字符集。

现在笔者用Win32汇编语言程序实现本程序的功能,程序如下:

包含文件(SIMPLE.INC):

UINTTYPEDEFDWORD

LONGTYPEDEFDWORD

LPSTRTYPEDEFPTRBYTE

LPCSTRTYPEDEFLPSTR

PVOIDTYPEDEFPTR

LPVOIDTYPEDEFPVOID

HANDLETYPEDEFPVOID

HINSTANCETYPEDEFHANDLE

HWNDTYPEDEFHANDLE

HMENUTYPEDEFHANDLE

HDCTYPEDEFHANDLE

HGDIOBJTYPEDEFHANDLE

HICONTYPEDEFHANDLE

HCURSORTYPEDEFHANDLE

HBRUSHTYPEDEFHANDLE

tagWNDCLASSEXASTRUCT

cbSizeUINT?

styleUINT?

lpfnWndProcDWORD?

cbClsExtraDWORD?

cbWndExtraDWORD?

hInstanceDWORD?

hIconDWORD?

hCursorDWORD?

hbrBackgroundDWORD?

lpszMenuNameDWORD?

lpszClassNameDWORD?

hIconSmDWORD?

tagWNDCLASSEXAENDS

WNDCLASSEXATYPEDEFtagWNDCLASSEXA

tagPOINTSTRUCT

xLONG?

yLONG?

tagPOINTENDS

POINTTYPEDEFtagPOINT

tagMSGSTRUCT

messageUINT?

wParamDWORD?

lParamDWORD?

timeDWORD?

ptPOINT<>

tagMSGENDS

MSGTYPEDEFtagMSG

LPMSGTYPEDEFPTRMSG

tagRECTSTRUCT

leftLONG?

topLONG?

rightLONG?

bottomLONG?

tagRECTENDS

RECTTYPEDEFtagRECT

tagPAINTSTRUCTSTRUCT

hdcDWORD?

fEraseDWORD?

rcPaintRECT<>

fRestoreDWORD?

fIncUpdateDWORD?

rgbReservedBYTE32DUP(?

tagPAINTSTRUCTENDS

PAINTSTRUCTTYPEDEFtagPAINTSTRUCT

LPPAINTSTRUCTTYPEDEFPTRPAINTSTRUCT

NULL=0

TRUE=0ffffffffh

FALSE=0

SW_SHOWDEFAULT=10

CS_HREDRAW=0002h

CS_VREDRAW=0001h

IDI_APPLICATION=32512

IDC_ARROW=32512

COLOR_WINDOW=5

WS_OVERLAPPEDWINDOW=00cf0000h

CW_USEDEFAULT=80000000h

WM_PAINT=000fh

WM_DESTROY=0002h

GetModuleHandleAPROTOstdcall,:

LPCSTR

GetCommandLineAPROTOstdcall

ExitProcessPROTOstdcall,:

UINT

LoadIconAPROTOstdcall,:

HINSTANCE,:

LPCSTR

LoadCursorAPROTOstdcall,:

HINSTANCE,:

LPCSTR

RegisterClassExAPROTOstdcall,:

PTRWNDCLASSEXA

CreateWindowExAPROTOstdcall,:

DWORD,:

LPCSTR,:

LPCSTR,:

DWORD,:

DWORD,:

DWORD,:

DWORD,:

DWORD,:

HWND,:

HMENU,:

HINSTANCE,:

LPVOID

ShowWindowPROTOstdcall,:

HWND,:

DWORD

UpdateWindowPROTOstdcall,:

HWND

GetMessageAPROTOstdcall,:

LPMSG,:

HWND,:

UINT,:

UINT

TranslateMessagePROTOstdcall,:

PTRMSG

DispatchMessageAPROTOstdcall,:

PTRMSG

BeginPaintPROTOstdcall,:

HWND,:

LPPAINTSTRUCT

EndPaintPROTOstdcall,:

HWND,:

PTRPAINTSTRUCT

PostQuitMessagePROTOstdcall,:

DWORD

DefWindowProcAPROTOstdcall,:

HWND,:

UINT,:

DWORD,:

DWORD

源程序(SIMPLE.ASM):

.386p

.MODELflat,stdcall

INCLUDESIMPLE.INC

WinMainPROTOstdcall,:

HINSTANCE,:

HINSTANCE,:

LPSTR,:

DWORD

.STACK4096

.DATA

WindowClassBYTE'SIMPLE',0

WindowTitleBYTE'SIMPLE',0

hInst1HINSTANCE0

lpCmdLine1LPSTR0

.CODE

_start:

INVOKEGetModuleHandleA,NULL

movhInst1,eax

INVOKEGetCommandLineA

movlpCmdLine1,eax

INVOKEWinMain,hInst1,NULL,lpCmdLine1,SW_SHOWDEFAULT

INVOKEExitProcess,eax

WinMainPROChInst:

HINSTANCE,hPrevInst:

HINSTANCE,lpCmdLine:

LPSTR,

nShowCmd:

DWORD

LOCALwcex:

WNDCLASSEXA

LOCALhWnd:

HWND

LOCALmsg:

MSG

.IF!

hPrevInst

movwcex.cbSize,SIZEOFWNDCLASSEXA

movwcex.style,CS_HREDRAWorCS_VREDRAW

movwcex.cbClsExtra,0

movwcex.cbWndExtra,0

movwcex.lpfnWndProc,OFFSETWndProc

moveax,hInst

movwcex.hInstance,eax

INVOKELoadIconA,hInst,IDI_APPLICATION

movwcex.hIcon,eax

INVOKELoadCursorA,0,IDC_ARROW

movwcex.hCursor,eax

movwcex.hbrBackground,COLOR_WINDOW+1

movwcex.lpszMenuName,NULL

movwcex.lpszClassName,OFFSETWindowClass

INVOKELoadIconA,hInst,IDI_APPLICATION

movwcex.hIconSm,eax

INVOKERegisterClassExA,ADDRwcex

.IF!

eax

moveax,FALSE

ret

.ENDIF

.ENDIF

INVOKECreateWindowExA,0,ADDRWindowClass,ADDRWindowTitle,

WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,

CW_USEDEFAULT,0,0,hInst,NULL

movhWnd,eax

.IF!

eax

moveax,FALSE

ret

.ENDIF

INVOKEShowWindow,hWnd,nShowCmd

INVOKEUpdateWindow,hWnd

.

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1