1. NASM编译器介绍:
1) Netwide Assembler,是目前唯一开源且免费的汇编器;
2) 该汇编器只提供编译的功能,但不提供连接的功能,在Linux下编译器产生.o文件后还需要使用ld链接器和操作系统的库链接才能形成可执行文件,而在Windows下需要使用MASM的ml链接器连接形成.exe文件;
3) 这里我们先介绍实模式编程,由于Linux以及Windows都是运行在保护模式下的,因此我们会将编译好的程序写进虚拟硬盘的主引导扇区中,然后由虚拟机启动来观察程序运行效果,在Windows中使用Oracle Virtual Box以及VHD,在Linux中使用Bochs和dd磁盘工具;
4) NASM和MASM一样都是遵从Intel汇编语法,因此指令集(即指令的名称相同)相同、语法相同,仅仅就是内存寻址形式以及其它的一些语法的细微处有不同地方;
2. 符号命名规则以及立即数的表示形式、越界问题:
1) 对于指令、寄存器名称以及立即数中的字母,都对大小写不敏感;
2) 但是对于标号是大小写敏感的!比如Tag:和tag:就是两个完全不同的标号;
3) 标号必须以字母开头,或者是以'_'、'.'、'@'、'?'开头,当然标号当中也可以包含这些符号,并且标号也可以只包含这些符号,比如'@@'等,但是如果以特殊符号开头而不是以字母开头,对于NASM有特殊含义(之后会详细讲解);
4) 立即数的表示:
i. 规则基本和MASM一样,可以用H、没有后缀、B来区分十六进制、十进制、二进制,并且后缀的大小写随意;
ii. 后缀法表示十六进制时,如果是以字母开头的就必须加一个0前缀,否则编译器会认为这是一个标号而不是一个立即数而报错!(注意:标号基本上是以字母开头的)
iii. 但是NASM还支持更加传统的十六进制表示形式,就是C语言的0x前缀表示法,用这种方式十六进制如果是以字母开头就无需加0前缀了,并且无需任何后缀,x的大小写随意;
iv. NASM允许使用下划线来使较长的立即数更加清晰,并且对于任意一种表示法都有效,比如100_0_11_11B、0F_E_3H、33_3_33、0x89_EF等,但是下划线不能放在开头,否则汇编器会将其误认为标号而报错;
!注意:任何汇编语言都不允许立即数作为目的操作数,因为目的操作数具有存放运算结果的功能,而立即数没有自己的空间,因此不能作为目的操作数使用!
5) 立即数越界问题:就是指立即数的范围超出目的操作数的范围大小,比如mov cl, 0623EFA823H、mov byte [bx], 3242342342325等,这种情况编译器不会报错,但是会警告提示范围过大,如果执意运行而忽视警告,则在运行时会做截断处理而损失精度,极大可能会导致程序错误或异常崩溃!所以不能忽视立即数越界问题;
6) 良好的符号命名习惯:
i. 所有指令和寄存器名称都小写;
ii. 立即数的后缀都大写;
iii. 立即数中的字母都大写;
iv. 0x中的x小写;
v. 全局标号以大写字母开头,后面跟小写字母(和Java的类名相似);
vi. 局部标号全小写;(关于全局标号和局部标号的概念后面会详细介绍)
7) 字符串的表示:
i. 字符串也是一种立即数;
ii. 既可以使用' '也可以使用" "来表示字符串立即数;