一。Win32汇编源程序的结构
.386 ;告知编译器本程序使用的指令集,使用“.386p”则表示程序可以使用像“mov cr0,eax”这样的特权指令
.model flat,stdcall ;内存模式Win32使用flat,stdcall为子程序调用方式,指出了子程序或Win32API时调用参数传递的次序和堆栈平衡的方式。
option casemap:none ;用来指定是否对大小写敏感,由于Win32API区分大小写,所以必须为none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段 .data、,data?、,const都是数据段,win32汇编不必考虑堆栈,系统会为程序分配一个向下扩展的、足够大的段作为堆栈段,所以.stack定义常常被忽略
;1.可读可写的已定义变量:在源程序中已经被定义了初始值,而且在程序执行中有可能被更改,这些数据必须被定义在.data段,.data段一般存放在可执行文件的_DATA节区
;2.可读可写的未定义变量:变量一般当做缓冲区或者程序执行才开始使用的,.data段和.data?段都可以使用。但是定义在.data?段中不会增大.exe文件的大小,放在_BSS节区
;3.常亮:要显示的一些字符串信息,放在.const段,是常亮段,是可读不可写的。
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data
szCaption db 'A MessageBox !',0
szText db 'Hello, World !',0
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code ;代码段,一般放在可执行文件的_TEXT节区。代码段的属性是由可执行文件PE头中的属性位决定的。
start:
invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
invoke ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start
;当源程序的某一行过长,不利于阅读的时候,可以分行书写,使用“\”做换行符。
二 。调用API
Win32的系统功能模块放在Windows的动态链接库DLL中,DLL是Windows的一种可执行文件,采用的是和.exe文件一样的PE格式,在PE格式文件头的导出表,以字符串形式指出了这个DLL能踢狗的函数列表。
Win32API的3个核心DLL
- KERNEL32.DLL----系统服务功能。包括内存管理、任务管理和动态链接等
- GDI32.DLL----图形设备接口。利用VGA与DRV之类的显示设备驱动程序完成显示文本和矩形等功能
- USER32.DLL----用户接口服务。建立窗口和传送消息。
Win32API调用中要把参数放入堆栈,顺序是最后一个参数最先近战。
在源程序编译链接成可执行文件之后,call MessageBox语句中的MessageBox会被换成一个地址,指向可执行文件的PE头中导入表,导入表中指向MessageBox函数的实际地址会在程序装入内存的时候,根据User32.dll在内存中的位置由Windows系统动态的填入。
invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK