.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