0%

汇编语法速览

汇编语言是一种低级语言,与计算机的硬件架构密切相关,用于直接控制硬件。以下是汇编语言的基本语法及相关概念,基于 x86/x86-64 架构(适用于 NASM、MASM 等汇编器)。


一、汇编语言的基本结构

1.1 程序结构

汇编程序通常分为以下几部分:

  1. 数据段 (data): 定义全局变量和常量。
  2. 代码段 (code): 包含可执行指令。
  3. 堆栈段 (stack): 管理函数调用和本地变量。

示例:基本结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
section .data           ; 数据段
message db "Hello, World!", 0

section .bss ; 未初始化数据段
buffer resb 64 ; 预留64字节的内存

section .text ; 代码段
global _start ; 声明程序入口点
_start: ; 程序开始位置
mov eax, 4 ; 系统调用:write
mov ebx, 1 ; 文件描述符:stdout
mov ecx, message ; 消息地址
mov edx, 13 ; 消息长度
int 0x80 ; 调用内核
mov eax, 1 ; 系统调用:exit
xor ebx, ebx ; 返回码 0
int 0x80 ; 调用内核

二、基本语法

2.1 指令格式

汇编指令通常由以下部分组成:

1
[标签]: 指令 [操作数1], [操作数2]
  • 标签: 可选,用于定义位置,类似标记。
  • 指令: 汇编指令,如 mov, add, sub
  • 操作数: 可以是寄存器、内存地址或立即数。

示例

1
2
3
start:         ; 标签
mov eax, 10 ; 将立即数 10 移动到 eax 寄存器
add eax, 5 ; eax = eax + 5

2.2 数据定义

  • .data中定义初始化的数据。
  • .bss中定义未初始化的数据。
伪指令 描述 示例
db 定义字节(8位) var1 db 10
dw 定义字(16位) var2 dw 1000
dd 定义双字(32位) var3 dd 12345678h
dq 定义四字(64位) var4 dq 1234567890h
resb 分配字节(未初始化) buffer resb 64
resw 分配字(未初始化) array resw 10

2.3 寄存器

通用寄存器

寄存器 说明 示例
eax 累加器 mov eax, 5
ebx 基址寄存器 mov ebx, eax
ecx 计数器寄存器 loop_start: ...
edx 数据寄存器 mov edx, 100

栈指针与基址指针

寄存器 说明
esp 栈顶指针
ebp 基址指针(函数调用中使用)

2.4 指令类型

数据传输指令

用于在寄存器、内存和立即数之间传递数据。

指令 功能 示例
mov 数据传输 mov eax, 10
lea 加载地址 lea esi, [var1]
xchg 交换数据 xchg eax, ebx
push 压入栈 push eax
pop 弹出栈 pop eax

算术指令

用于执行加减乘除等运算。

指令 功能 示例
add 加法 add eax, 5
sub 减法 sub eax, 3
imul 有符号乘法 imul eax, ebx
idiv 有符号除法 idiv ecx
inc 自增 inc eax
dec 自减 dec ebx

逻辑指令

用于位操作和逻辑判断。

指令 功能 示例
and 按位与 and eax, 0xF0
or 按位或 or eax, 0x01
xor 按位异或 xor eax, eax
not 按位取反 not eax
shl 左移 shl eax, 2
shr 右移 shr eax, 1

跳转指令

用于流程控制。

指令 功能 示例
jmp 无条件跳转 jmp label
je/jne 等于跳转/不等跳转 je equal_label
jg/jl 大于跳转/小于跳转 jg greater_label
loop 循环跳转 loop loop_start

2.5 栈操作

栈是一种后进先出的数据结构,用于函数调用或数据存储。

压栈和弹栈

1
2
push eax      ; 将 eax 压入栈
pop ebx ; 将栈顶值弹出到 ebx

函数调用

1
2
call myFunction   ; 调用函数
ret ; 返回调用点

2.6 条件判断

结合跳转指令和比较指令实现条件判断。

1
2
cmp eax, ebx       ; 比较 eax 和 ebx
je equal_label ; 如果相等则跳转到 equal_label

三、示例代码

3.1 Hello World

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
section .data
msg db "Hello, World!", 0

section .text
global _start

_start:
mov eax, 4 ; 系统调用号:write
mov ebx, 1 ; 文件描述符:stdout
mov ecx, msg ; 消息地址
mov edx, 13 ; 消息长度
int 0x80 ; 调用内核
mov eax, 1 ; 系统调用号:exit
xor ebx, ebx ; 返回值 0
int 0x80 ; 调用内核

3.2 加法运算

1
2
3
4
5
6
7
8
9
10
11
12
section .data
result db 0 ; 存储结果

section .text
global _start

_start:
mov al, 5 ; 加数1
add al, 10 ; 加数2
mov [result], al ; 将结果存入 result
mov eax, 1 ; 系统调用号:exit
int 0x80 ; 调用内核退出

3.3 条件跳转

section .text
    global _start

_start:
    mov eax, 5
    mov ebx, 10
    cmp eax, ebx         ; 比较 eax 和 ebx
    jl less_label        ; 如果 eax < ebx,跳转
    jmp end_label

less_label:
    ; eax 小于 ebx 的逻辑