.386 ;.8086,.186,.286,.386/.386p,.486/.486p,.586/.586p等 告诉编译器本程序使用的指令集,带P的指令,表示程序可以使用特权指令
.model flat,stdcall ;::程序的模式和源程序格式定义,;;定义程序的工作模式 .model 内存模式[,语言模式][,其他模式]
;内存的模式有 tiny,small,medium,compact,large,huge,flat,定义了flat MASM自动对各段寄存器定义为:ASSUME cs:FLAT,ds:FLAT,ss:FLAT,es:FLAT,fs:ERROR,gs:ERROR
;语言模式:参数的传递次序和堆栈的平衡方法,其他类型有:C,SysCall,BASIC,FORTRAN,PASCAL
option casemap:none;定义子程序中的变量名和子程序名是否对大小写敏感
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;数据段
.data
szCaption db 'A MessageBox !',0
szText db 'Hello,World !',0
;代码段
.code
start: invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK
invoke ExitProcess,NULL
end start
invoke 函数名[,参数1][,参数2]...........
API函数的返回值:一般情况下是存放在eax里面的。如果返回值的长度eax存放不了,采用的方法一般是在eax中返回一个指向该数据的指针,或者是在调用参数中提供一个缓冲区地址,把数据存放到缓冲区.
函数的声明:函数名 proto [距离] [语言] [参数1]:数据类型,[参数2]:数据类型................ 距离可以是NEAR,FAR,NEAR16,FAR16,NEAR32,FAR32 Win32中只有一个平坦的段,无所谓距离,所以定义时是忽略的;语言类型是.model那些类型,如果忽略,则使用.model定义的默认值.
include 语句:
该程序中用到了两个API函数:MessageBox和ExitProcess,它们分别在User32.dll和Kernel32.dll ,在MASM32 SDK 软件包中包括了所有DLL中API函数的声明列表,每个DLL对应<DLL 名.inc>文件,在源程序中只要使用include语句包含进来就可以不用声明了.
include 语法:include 文件名 或 include <文件名> 当用到的文件名有可能和MASM关键字引起混淆的情况时,可以用<>将文件名包括起来.
includelib 语句:
includelib的作用是定位程序中所调用的API函数存放在哪个DLL中,语法:includelib 库文件名 或 includelib <库文件名>
windows.inc的作用是包含等值的定义,API 函数的参数等值定义,某些宏,常量,数据结构等等
标号:当程序中要跳转到另一个位置时,需要有一个标号来指引。在指令中使用标号,想当于使用地址。
标号和变量的命名规范:1.可以用字母、数字、下划线以及符号@ $ 和 ? 2.第一个字符不能使数字 3.长度不能超过240个字符 4.不能使用关键字 5. 在作用域必须唯一
标号既可以定义在目的指令同一行的头部(标号名: 目的指令),也可以在目的指令前一行单独使用.
标号定义的格式:1.标号名: 目的指令 或 2.标号名:: 目的指令
第一种标号格式的作用域是当前的子程序,在单个子程序中标号不能同名.
第二种标号格式的作用域是整个程序,
@@
当用@@做标号时,可以用@F和@B来引用它,@F表示本条指令后的第一个@@标号,@B表示本条指令前的第一个@@标号,程序中有多个@@标号,但@B和@F只寻找匹配最近的一个.
全局变量
Win32汇编全局变量定义在.data 或 .data?段内,可以同时定义变量的类型和长度.
变量名 类型 初始值1,初始值2,................
变量名 类型 重复数量 dup (初始值1,初始值2,...........)
变量的类型
---------- --------------- ---------------- ---------------
名称 表达方式 缩写 长度(字节)
字节 Byte db 1
字 word dw 2
双字 dword dd 4
三字 fword df 6
四字 qword dq 8
十字节BCD码 tbyte dt 10
有符号字节 sbyte 1
有符号字 sword 2
有符号双字 sdword 4
单精度浮点数 Real4 4
双精度浮点数 Real8 8
10字节浮点数 Real10 10
--------------- --------------- ---------------------- ----------------------
所有使用变量类型的情况中,只有定义全局变量的时候,类型才可以使用缩写.
在byte类型变量的定义中,可以用引号定义字符串和数值定义的方法混用.
局部变量:定义在子程序内部.作用域是单个子程序,在进入子程序的时候,通过修改堆栈指针esp来预留出需要的空间,在用ret指令返回主程序之前,同样通过回复esp丢弃这些空间.
local 变量名1 [[重复次数]] [:类型] , 变量名2 [[重复次数]] [:类型], ...........,local 必须紧跟在子程序定义的伪指令 proc 后,其他指令开始前。
------------------下面通过一个简单的代码,分析反汇编之后,局部变量的情况--------------
TestProc proc
local @loc1:dword,@loc2:word
local @loc3:byte
mov eax,@loc1
mov ax,@loc2
mov al,@loc3
ret
TestProc endp
反汇编:
:00401000 55 push ebp
:00401001 8BEC mov ebp,esp
:00401003 83C4F8 add esp,FFFFFF8
:00401006 8B45FC mov eax,dword ptr [ebp-04]
:00401009 668B45FA mov ax,word ptr [ebp-06]
:0040100D 8A45F9 mov al,byte ptr [ebp-07]
:00401010 C9 leave
:00401011 C3 ret
浙公网安备 33010602011771号