NASM-中文手册摘录笔记
第二章 运行 NASM
NASM 在碰到错误以前是不输出任何信息的, 所以除了出错信息你看不到其他信息.
所有可用的输出文件格式的列表可以通过:
1 |
|
得到.
-l
选项会生成一个源文件的列表文件, 在里面, 地址和产生的代码列在左边, 实际的源代码 (包括宏扩展, 除了那些指定不需要在列表中扩展的宏) 列在右边. 如:
1 |
|
-F
为输出文件选择一个调试格式. -g
使调试信息有效.
-I
包含文件搜索路径.
NASMENV
环境变量的值会作为命令行的附加选项部分, 其值通过空格符分隔. 若不想用空格符分隔, 可将其值以非 -
开头作为新的分隔符, 如:
1 |
|
2.2.3 NASM 不存储变量类型
因此在使用时显示表明类型:
1 |
|
第三章 NASM 语言
每一行 NASM 源代码包含 (除非是一个宏, 一个预处理操作符, 或一个汇编器操作符) 下面四个部分的全部或某几个部分:
1 |
|
NASM 使用反斜线 \
作为 续行符 .
labels 中的有效字符是:
- 字母
- 数字
- ‘-‘, ‘$’, ‘#’, ‘@’, ‘~’, ‘.’, ‘?’
只有 ‘.’, ‘_‘, ‘?’ 可以作为标识符开头.
一个标识符还可以加上一个 ‘$’ 前缀, 以表明它作为一个标识符而不是保留字来处理.
3.2 伪指令
伪指令是一些并不是真正的 x86 机器指令, 但还是被用在了 instruction 域中的指令.
db
, dd
, dw
的区别是对齐规则不同.
RESB
等用来声明未初始化的存储空间:
1 |
|
EQU
的行为就是把给出的 label 的名字定义成它的操作数 (唯一) 的值, 定义是不可更改的:
1 |
|
3.2.5 TIMES
: 重复指令或数据
前缀 TIMES
导致指令被汇编多次.
3.3 有效地址
以下也有效:
1 |
|
3.4 常数
NASM 能理解四种不同类型的常数:
- 数值
- 字符
- 字符串
- 浮点数
3.5 表达式
jmp $
可以简单表示无限循环.
%
符号被宏预处理器使用.
3.6 SEG
和 WRT
SRG
操作符返回符号所在的首选段的段基址:
1 |
|
3.9 本地 Labels
NASM 对于那些以一个句点开始的符号会作特殊处理, 一个以单个句点开始的 Label 会被处理成本地 label, 这意味着它会跟前面一个非本地 label 相关联. 感觉像是子 label:
1 |
|
第一个 .loop
实际上被定义为 label1.loop
.
第二个 .loop
实际上被定义为 label2.loop
NASM 还能定义其他的特殊符号, 比如以两个句点开始的符号, 如 ..start
被用来指定 .obj
输出文件的执行入口.
第四章 NASM 预处理
预处理指令都是以一个 %
开头.
预处理器把所有反斜杠 \
结尾的连续行合并为一行:
1 |
|
会像是单独一行那样正常工作.
4.1 单行的宏
4.1.1 最常用的方式: %define
和 C 类似:
1 |
|
用 %define
定义的宏是大小写敏感的.
使用 %idefine
( i 代表 “insensitive” )则是大小写不敏感.
可以 重载 单行宏, 预处理器能够通过参数的个数来区分:
1 |
|
foo(1)
会变成 1+1
.
foo(1,1)
会变成 1+1*1
但是, 一个不带参数的宏定义不允许对它进行带有参数 的重定义.
命令行使用 -d
来预定义宏.
4.1.2 %define
的增强版: %xdefine
其大小写不敏感形式为 %xidefine
用于当一个宏之中有其他宏定义时.
让这个宏始终为内部宏嵌入时的值,而不是内部宏修改后的值.
4.1.3 连接单行宏的符号: %+
4.1.4 取消宏定义: %undef
命令行为 -u
4.1.5 预处理器变量: %assign
大小写不敏感形式为 %iassign
.
值可以用表达式的形式指定:
1 |
|
assign
是赋值的含义, 这里也就好像赋值, i
展开的值是表达式计算的结果.
4.2 字符串处理宏 %strlen
和 %substr
4.2.1 %strlen
%strlen
宏创建的数值是一个字符串的长度:
1 |
|
4.2.2 %substr
索引值不是 0 开始:
1 |
|
4.3 多行宏: %macro
如:
1 |
|
调用:
1 |
|
相当于:
1 |
|
宏名后面的数字定义了宏可以接收的参数的个数. %1
是调用第一个参数.
4.3.1 多行宏的重载
4.3.2 Macro-Local Labels
NASM 允许你在多行宏中定义 labels, 使它们对于每一个宏调用来讲是本地的.
通过在 label 名称前面加上 %%
来实现:
1 |
|
4.3.3 不确定的宏参数个数
在 NASM 中是通过在宏的 %macro
一行上的参数个数后面加上 +
来实现.
4.3.5 %0
: 宏参数个数计数器
%0
其表示有多少个参数传给了宏.
4.3.6 %rotate
: 循环移动宏参数
%rotate
让宏参数循环左移. 其可以加一个参数指定左移的次数. 负数右移.
4.4 条件汇编
1 |
|
4.4.1 %ifdef
测试单行宏是否存在
1 |
|
4.4.2 %ifmacro
测试多行宏是否存在
4.4.7 %error
报告用户自定义错误
预处理操作符 %error
会让 NASM 报告一个在汇编时产生的错误.
1 |
|
4.5 预处理器循环: %rep
操作符 %rep
和 %endref
可以用来包围一段代码, 然后这段代码可以被复制多次, 次数由预处理器指定.
1 |
|
中途可使用 %exitrep
操作符来终止循环.
4.6 包含其他文件
通过 %include
实现:
1 |
|
可用 -I
参数增加搜索路径.
防止重复包含:
1 |
|
4.7 上下文栈
4.8 标准宏
NASM 定义了一套标准宏.