NASM汇编语言基础语法与伪指令详解

NASM汇编语言基础语法与伪指令详解

1. NASM源代码行结构

NASM源代码行通常由四个字段组成(宏、预处理指令和汇编指令除外):

label:    instruction operands        ; comment

这四个字段分别是:

  1. 标签(label):可选,以冒号结尾(冒号也可省略)
  2. 指令(instruction):机器指令或伪指令
  3. 操作数(operands):根据指令要求而定
  4. 注释(comment):以分号开始

重要特性

  • 行续接:使用反斜杠(\)作为行续接符
  • 空白符自由:NASM对行内空白没有严格限制
  • 标签命名规则
    • 有效字符:字母、数字、_、$、#、@、~、.、?
    • 首字符限制:字母、.(有特殊含义)、_和?
    • 最大长度:4095个字符
    • 可使用$前缀避免与保留字冲突(如$eax)

2. 指令与操作数

指令前缀

NASM支持多种指令前缀:

  • 锁前缀:LOCK
  • 重复前缀:REP、REPE/REPZ、REPNE/REPNZ
  • 事务内存前缀:XACQUIRE/XRELEASE
  • 边界前缀:BND/NOBND
  • 显式大小前缀:A16、A32、A64(地址大小),O16、O32、O64(操作数大小)
  • 段寄存器前缀:如es mov [bx],ax等价于mov [es:bx],ax

操作数类型

操作数可以是:

  • 寄存器:直接使用寄存器名(如ax、ebp、ebx、cr0)
  • 有效地址(见第5节)
  • 常量(见第6节)
  • 表达式(见NASM表达式相关文档)

x87浮点指令语法

NASM支持多种x87浮点指令格式:

fadd st1             ; st0 := st0 + st1
fadd st0,st1         ; 同上
fadd st1,st0         ; st1 := st1 + st0
fadd to st1          ; 同上

引用内存的x87浮点指令必须使用DWORD、QWORD或TWORD前缀指明内存操作数大小。

3. 伪指令详解

伪指令不是真正的x86机器指令,但因其便利性被放在指令字段中使用。

3.1 数据声明伪指令

初始化数据声明

| 伪指令 | 描述 | 示例 | |--------|--------------------|--------------------------| | DB | 声明字节 | db 0x55, 'a', "hello" | | DW | 声明字(2字节) | dw 0x1234, 'ab' | | DD | 声明双字(4字节) | dd 0x12345678, 1.234e20 | | DQ | 声明四字(8字节) | dq 0x123456789abcdef0 | | DT | 声明十字节(10字节) | dt 1.234567e20 | | DO | 声明八字(8字节) | | | DY | 声明YMM字(32字节) | dy 1 | | DZ | 声明ZMM字(64字节) | dz 32 |

MASM风格语法(NASM 2.15+)
db ?                  ; 未初始化字节
db 6 dup (33, 34)     ; 重复6次33,34
dw byte (?,44)        ; 未初始化字节后跟44
dd 16 dup (0xaaaa, ?, 0xbbbbbb)
未初始化数据声明

| 伪指令 | 描述 | 示例 | |--------|--------------------|--------------------------| | RESB | 保留字节 | resb 64 | | RESW | 保留字 | resw 1 | | RESD | 保留双字 | resd 10 | | RESQ | 保留四字 | resq 10 | | REST | 保留十字节 | rest 1 | | RESO | 保留八字 | reso 1 | | RESY | 保留YMM字 | resy 1 | | RESZ | 保留ZMM字 | resz 32 |

MASM风格等价写法:

buffer: db 64 dup (?)      ; 保留64字节
wordvar: dw ?              ; 保留一个字

3.2 其他重要伪指令

INCBIN:包含二进制文件
incbin "file.dat"          ; 包含整个文件
incbin "file.dat",1024     ; 跳过前1024字节
incbin "file.dat",1024,512 ; 跳过1024字节,最多包含512字节
EQU:定义常量
message db 'hello, world'
msglen equ $-message       ; 定义msglen为常量12

EQU定义的常量是绝对的,不能重新定义。

TIMES:重复指令或数据
times 64 db 0              ; 64个0字节
times 100 movsb           ; 重复movsb指令100次

TIMES的参数是临界表达式(critical expression)。

4. 有效地址语法

NASM中的有效地址语法简单统一,用方括号括起来的表达式:

mov ax,[wordvar]
mov ax,[wordvar+1]
mov ax,[es:wordvar+bx]

复杂地址形式

mov eax,[ebx*2+ecx+offset]
mov ax,[bp+di+8]

地址优化与控制

  • NASM会自动优化地址形式,如将[eax*2]优化为[eax+eax]
  • 使用BYTE、WORD、DWORD和NOSPLIT控制地址形式:
    mov eax,[dword eax+3]   ; 强制使用双字偏移
    mov eax,[byte eax]      ; 使用字节偏移(0)
    mov eax,[nosplit eax*2] ; 禁止优化为[eax+eax]
    

64位模式地址

  • 默认生成绝对地址
  • REL关键字生成RIP相对地址
  • ABS关键字覆盖REL

分离地址语法(MPX指令等)

mov eax,[ebx+8,ecx*4]   ; ebx=基址, ecx=索引, 4=比例因子, 8=位移

5. 常量类型

NASM支持四种常量类型:

5.1 数值常量

支持多种进制表示:

  • 十六进制:0x3FF、3FFh
  • 十进制:1234
  • 八进制:777q
  • 二进制:1101b

5.2 字符常量

用单引号括起,如'a'、'\n'

5.3 字符串常量

用单引号或双引号括起,如"hello", 'world'

5.4 浮点常量

支持多种浮点格式:

dd 1.234567e20     ; 单精度
dq 1.234567e20     ; 双精度
dt 1.234567e20     ; 扩展精度

本文详细介绍了NASM汇编语言的基础语法、伪指令和有效地址表示方法,是学习NASM汇编的重要参考资料。掌握这些基础知识后,开发者可以更高效地编写和优化汇编代码。

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值