这章主要还是讲一些masm这个编译器所适用的一些语法,和win32汇编语法
目录)
第三章
完整的程序结构
3.1.1
先看一个helloworld程序
代码前三行,第一行基本是固定的,想用别的模式去看书(p48)。
另外说下第二行内存模式,因为win32每个程序都假装给了4gb,所以就是flat,而语言模式主要决定在于汇编的时候如何处理处理子程序的堆栈平衡。第三行就是说下面的代码区分大小写(API函数是有大小写之分的)。
后面的include跟c语言的意思差不多,includelib提供库的位置。
3.1.2段
分段(注意每个段前面有个点),stack段没有了,因为系统会自动分配。
data段 .data 表示下面是一些已经初始化了的数据或者说,给下面的数据实际分配了这么多。
.data? 表示只是说明一下给我留个位置,但并没有实际分配到那么多,也可以用来一些未初始化的数据。
.const 只能读不能写的数据。
3.1.4注释和换行
注释:分号后面的就是注释(不在字符串里面的分号),就像c语言里//后面是注释。
换行:如果源码太长不好阅读,用反斜杠(\)
3.2.2调用函数
调用用invoke,直接上书声明用proto,比如函数要写到start:后面
3.2.3API中的等值定义
比如调用MessageBox时候的最后一个参数就是表示用什么按钮这些字母每一个都对应一个数值,表示一些固定按钮的数值。
3.3标号,变量,数据结构
标号要跳转到哪个位置的时候,只要jmp 标号就行了,要在哪标号就到该代码前写 标号名:代码… 。masm里面有@@标号
全局变量: 就是在一开始data段中声明的数据
局部变量: 用在函数定义后面,用local声明
当程序翻译成汇编的时候会加上收尾工作这个就是由一开始的.model这个位置写的语言所决定的,并且ebp会作为局部变量的指针存在,因为局部变量的储存位置是栈空出变量的位置,用完后栈恢复初始位置就好了 ,在子程序翻译成汇编的时候,开头和结尾都会保护好esp,让ebp作为栈的指针而移动,顺便空出局部变量的位置。注意下图多的语句add就是为局部变量空出位置,在细品leave语句(在书本p67)数据结构 定义如下,左边是数据名称,右边是大小
若要使用自己定义的这个数据结构,如下
数据结构还可以嵌套 就在上面的图的最后几行。
3.3.5变量的使用
1.用ptr限定要访问的大小,若大小与寄存器不符会报错。而且这个并不会检查溢出,如果你规定的大小超过你变量的大小,一样以ptr限定的为准。
2.movzx指令和movsx指令就弥补了上面ptr的不足
3.sizeof和lengthof 有时候一些API会用到这些
4.取变量地址,offset 、addr 和lea指令的说明
3.4使用子程序
其实就是像c语言里面设置一个函数,可以去看些例子
后面的关于堆栈的就是不同语言有不一样。
3.5高级语法
3.5.1条件测试语句
表达式跟c语言是一样的,但是翻译成汇编就不一样了
注意表达式左边只能是变量或者寄存器,不能是常量。表达式两边不能同时为变量,可以同时为寄存器。因为反汇编成汇编的时候没有cmp 0,eax的。
**还有稍微特殊一点表示,如下
3.5.2分支语句
学过c语言就很好理解了,直接上图
3.5.3循环语句
跟if一样,直接上图,仅供回忆
但是 .untilcxz还是有特别之处的,因为会用到loop来进行反汇编,看如下说明
3.6代码风格
稍稍注意一下看书上的代码也会轻松很多,API基本也是这种规范命名,还是记录一下
1.在定义变量名时
2.对于普通函数还是API,全局还是局部变量
3.一般习惯把子程序写在前面,start在最后