首先说明笔者的学习环境:win7,Masm for Windows 集成实验环境 2012.5
任何种类的语言,总是有基本的源程序结构规范,同样win32 汇编程序也有,现在写下一个HelloWorld的汇编程序
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
include kernel32.inc
includelib user32.lib
includelib kernel32.lib
.data
szTitle db "HelloWorld",0
szCaption db "first experinment",0
.code
start:
invoke MessageBox,NULL,offset szTitle,offset szCaption,MB_OK
invoke ExitProcess,0
end start
现在解释下以上的各个语句前三行呢,就是模式和源程序格式定义语句
.386 ;确定了本程序中使用的指令集
;.386呢,确定了汇编程序工作在80386及以上的处理器中
;额外解释:后面带p的伪指令则表示程序中可以使用特权指令-即.386p
;这样程序就可以运行在ring0层上
.model ;定义了程序的工作模式
.model 内存模式,语言模式
.model flat,stdcall
内存模式可以有一下的几种选择
tiny 用于建立com文件,所有的代码,数据,堆栈都在同一个64K空间内
small 建立代码和数据分别用一个64K段的exe文件
medium 代码段可以有多个64K段,数据段则只有一个64K段
compact 代码段只有一个64K段,数据段则有多个段
large 代码段和数据段都可以有多个段
huge 同large,数据段中的一个数组则可以超过64K段
flat win32程序使用的模式,代码段和数据段可以使用一个4GB
stdcall 定义了调用模式,表示API函数参数自右向左压入堆栈,并由函数自身清理堆栈
;option casemap:none 定义了该程序是区分字母大小写的
另外程序中的start标号,则是该程序的入口标号,对于单模块的程序而言,一般我们都会在.code中进行标号,但是标号的有误并非是确定的,也可以没有start,程序同样可以
运行,除此之外入口标号不一定是start,second也是可以的!
还有就是段的定义有.data和.data?两个段,但是两个是有不同的
.data
szBuffer db 100*1024 dup(?)
.data段中,编译器认为这些数据在程序装入的开始就必须有效,所以他在生成可执行程序的时候就保留了该100KB的控件,如果程序其他内容是50KB,那么生成后就是150KB
.data?
szBuffer db 100*1024* dup(?)
.data? 编译器则会认为该数据在开始执行时才会用到,所以在生成可执行程序时,不会开辟这些空间,只是保留了大小信息