编写环境介绍
操作系统:Windows7、WIndows10
编写环境(IDE):Visual Studio 2017 community 在 002-【X86-汇编语言】-看C语言如何编译为汇编语言 中已经介绍过了
汇编器:MASM 此款汇编器为微软出品,捆绑在Visual Studio 2017 community中无需另行安装
建立工程编写代码
在002-【X86-汇编语言】-看C语言如何编译为汇编语言中已经介绍了如何创建工程,这里不再赘述。我们同样使用Visual C++ 空工程。建立完工程后为了启用MASM,让项目支持汇编语言需要一额外的设置
在masm前打勾
新建里一个.asm文件然后输入如下代码(可以先建立一个.cpp文件,然后将文件名后缀名改成.asm)
COMMENT $
我编写的第一汇编程序
$
.386 ;告诉汇编器我使用的是386以上的CPU,用于编写32位程序
.model flat,stdcall ;告诉编译器,使用本程序使用flat编写执行,和本程序使用stdcall模式调用过程
.stack 4096 ;堆栈段大小为4026,即4KB
ExitProcess PROTO,dwExistCode:DWORD ;声明一个系统调用名字为ExitProcess 有一个参数dwExistCode 类型为DWORD,作用是退出程序
.data ;告诉编译器,我开始写数据段了,其后的代码都是定义变量
.code ;告诉编译器,我开始写代码段了,其后的代码都是过程
firstAsm PROC ;告诉汇编器,我开始firstAsm这个过程了
MOV EAX,0FFFFFFFFh ;将十六进制数0FFFFFFFFh放到EAX寄存器中
INVOKE ExitProcess,0 ;调用ExitProcess退出程序
firstAsm ENDP; 告诉汇编器,我写完firstAsm这个过程了
END firstAsm; 告诉编译器,我已经写完了整个程序并将firstAsm设置为程序的入口
代码解释
注释(COMMENT)(为人类间的沟通而存在)
写代码注释是不可缺少的,注释有两个作用:1.记录自己当初,写这段代码的用意和思想(你要相信哪怕只过一个星期,再读自己的代码也会一头雾水);2.告诉别人,自己写这段的用意和思想。
注释与最后生成可执行文件无关,因为汇编器会忽略注释。记住注释是为人类间的沟通而存在的。
汇编器提供了两种形式的注释
第一种是单行注释,非常简单,单行注释以分号(;)开始到本行结束。可以写在汇编指令的后边,也可以单独写一行。
第二种是块注释,块注释一般用于长篇大论,注释可以跨行。块注释的方法是 【COMMENT X 注释内容 X】,COMMENT是一个伪指令,它告诉编译器我开始写注释了。X为程序编写者自己定义的符号,可以是数字、字母、符号(如# @ !)。块注释从COMMENT后的X开始,到下一次出现X为止。
指令集
汇编语言与机器指令一一对应,所以必须告诉汇编器我编写的程序要使用哪些机器指令,也就是需要使用的指令集合。程序中第一行有效代码【.386】就是告诉汇编器我们使用的是386处理的指令集合,使用32位指令和32位寄存器。因为80386处理器是第一个支持32位程序处理器。
关于Intel发展史百度贴吧中有不错的文章
模式
第二行有效代码以伪指令【.model】开始,告诉汇编器,我们开始设置一些程序的模式。
flat:是程序的运行模式,也是寻址模式。32位程序都选用这个模式,之后介绍寻址时会详细。
stdcall:是调用过程的模式,这个模式是Windows要求使用的模式,因为我们在Windows下运行程序,调用Windows的接口,所以我们必须使用这个模式,之后介绍过程调用时会详细介绍
栈段(stack segment)
【栈】是程序使用内存的一块特殊区域,程序运行基本上都要使用栈。在程序有效代码的第三行我们用【.stack】伪指令告诉编译器,我们这个程序需要4096个字节的栈空间,也就是4KB。之后介绍过程调用时会详细介绍栈。
数据段(data segment)
【数据段】是存储数据的地方,需要将使用的数据写到数据段中。本例中没有使用到变脸所以数据段是空的。用【.data】伪指令告诉汇编器【数据段】开始
代码段(code segment)
【代码段】是存储指令的地方,需要将程序指令写到代码段中。用【.code】伪指令告诉汇编器【代码段】开始
过程(PROCESS)
汇编指令使用一个一个过程封装的,每个程序有一个入口过程,编译完的可执行程序,被加载到系统后就是从入口过程的第一条指令开始执行的。
定义过程的语法是
过程名 PROC
指令1
指令2
指令3
...
指令n
过程名 ENDP
用PROC伪指令和ENDP伪指令告知汇编器一个过程的开始和结束。
本例中只有一个过程,过程名为firstAsm。此过程做两件事,第一件事将寄存器EAX的值设置成0FFFFFFFFh。第二件事调用系统接口ExitProcess结束程序,0是告诉Windows本程序正常结束了。之后会详细讲解MOV指令 和 EAX寄存器
代码结束(END)
END伪指令是告知编译器整个汇编代码结束了,END后指定一个过程名称,这是告诉汇编器当前汇编程序的入口过程。在本例中入口过程是firstAsm。
因为END是整个汇编代码的结束标志,因此在END之后再写任何东西汇编器也不会关心了