汇编-Win32 Example

搞了一个星期,哥才发现原来汇编是代码是不可通用的,真是坑啊,弃坑弃坑.

Code Example

.386                    ; 指明32位指令集
.model flat, stdcall    ; flat为Windows程序使用的模式,stdcall为API调用时右边的参数先入栈
.stack 4096             ; 堆栈为4096字节
COMMENT &
    这是一段注释.
    定义了一个ExitProcess函数,它是标准的Windows服务.PROTO是原型关键字,
    并定义了一个DWORD类型的输入参数,函数返回0认为我们执行成功.
&
ExitProcess PROTO, dwExitCode: DWORD    

.data
    sum  DWORD 0    ; 定义变量

.code
main PROC           ; 定义主函数开始位置
    mov eax, 5      ; 将eax寄存器的值设置为5
    add eax, 6      ; 为eax寄存器加5
    mov sum, eax    ; 将eax的设置给sum变量
    INVOKE ExitProcess, 0   ; 退出程序,0也可以用NULL代替
main endp           ; endp表示函数结束位置
end main            ; 设置了函数的入口与出口

Win32下的汇编模式与格式的定义语句

1. 第一行指定使用的指令集.

Win32环境工作在80x86CPU,所以必须指定指令集,可以用.386,也可以用.486.586,这是一个伪指令.如果程序中要用到特权指令,即保护方式下,那么则必须使用.386p.486.586.

2. 第二行定义程序的工作模式.

对Win32程序来说,只有一种内存模式,即flat(平坦)模式; STDCALL告诉编译器参数的传递约定.参数的传递约定是指参数传达时的顺序(从左到右或从右到左)和由谁恢复堆栈指针(调用者或被调用者).在Win16下有两种约定: CPASCAL. C 约定规定参数传递顺序是从右到左,即最右边的参数最先压栈,由调用者恢复堆栈指针.

3. 第三行 option

option的语句定义选项有很多,如option languageoption segment等.但在WIN32中,由于Win32 API中的API名称区分大小写,所以必须定义option casemap:none,来表明程序中的变量和子程序名对大小写敏感,否则API调用时会出现问题.

4. .stack: 指定堆栈大小.

5. .data: WIN32下是没有段(SEGMENT)的概念.但可以将代码分成不同的分段.一个分段的开始即是另一个分段的结束.WIN32中只有两种性质的分段:.code.data.

.code:

.code其实是代码分段.由于Windows下只有4GB的段,Windows程序中的分段表现在当程序装载时,赋予不同的分段不同的属性,比如说当你的程序加载时,对于工作在的Ring3程序来说,.code段是不可写的,而.data段是可写的,如果你尝试象在Dos下写自己的代码部分,你会得到一个蓝屏错误.

.data

其实.data下又分为3种:

  1. .data: 其中包括已初始化的数据.

  2. .data?: 其中包括未出世的数据.

  3. .const: 包括常量定义.这些常量在程序运行过程中是不可更改.

一个程序其实并不完全需要以上三个分段,可以根据需求定义.