【C/C++】汇编语言基本语法

发布于:2025-06-26 ⋅ 阅读:(16) ⋅ 点赞:(0)

汇编语言基本语法(以 x86 为例)


1 汇编语言的基本组成结构

汇编语言是对机器码指令的助记符表示,不同于高级语言的抽象,它直接反映 CPU 的指令集架构。以 x86 汇编为例,程序由**若干段(section)**组成,每段有特定用途:

  • 数据段(.data):用于存放已初始化的全局或静态数据
  • 未初始化数据段(.bss):用于存放未初始化的全局或静态变量
  • 代码段(.text):用于存放程序指令
  • 只读数据段(.rodata):存放只读数据,通常是字符串常量

3.1.1 示例汇编文件结构

section .data
    hello db 'Hello, world!', 0  ; 定义字符串,以0结束

section .bss
    buffer resb 64               ; 申请64字节未初始化空间

section .text
    global _start                ; 程序入口点,全局可见

_start:
    ; 程序代码写这里
    ; ...

2 汇编指令分类与示例

汇编指令可根据功能分为几类:

类别 常用指令 功能描述
数据传输 mov, lea, xchg 寄存器与内存间移动数据
算术运算 add, sub, inc, dec, mul, div 加减乘除及自增自减
逻辑运算 and, or, xor, not 位与、位或、异或、取反
比较与跳转 cmp, test, jmp, je, jne, jg, jl 比较与条件跳转
栈操作 push, pop, call, ret 栈入栈出栈,函数调用返回
控制转移 jmp, call, ret, loop 无条件跳转,调用函数,返回
其他 nop, int, syscall 无操作,中断,系统调用

常见指令举例

mov eax, 1       ; 将立即数1放入eax寄存器
add eax, ebx     ; eax = eax + ebx
cmp eax, 10      ; 比较eax与10,设置标志位
je label_equal   ; 如果相等,跳转到label_equal
jmp label_end    ; 无条件跳转
label_equal:
    ; 执行等于时的代码
label_end:
    ; 继续执行

3 寄存器详解

x86 架构中寄存器是汇编编程的核心资源。64位模式下(x86-64)主要寄存器:

寄存器 说明
RAX 累加寄存器,算术运算默认结果寄存器
RBX 基址寄存器,保存基址数据
RCX 计数寄存器,循环控制
RDX 数据寄存器,乘除法操作使用
RSI 源索引寄存器
RDI 目的索引寄存器
RBP 基址指针,栈帧指针
RSP 栈指针
R8-R15 额外通用寄存器

每个寄存器有 64位(RAX)和其低 32/16/8 位访问部分(EAX,AX,AH/AL):

  • RAX(64位)
  • EAX(低32位)
  • AX(低16位)
  • AH(高8位)
  • AL(低8位)

4 操作数类型

汇编指令支持多种操作数类型:

  • 立即数(Immediate):常量值,如 mov eax, 1
  • 寄存器(Register):如 eax, rbx
  • 内存地址(Memory):间接寻址访问内存数据,格式多样:
mov eax, [rbp-4]    ; 访问基址寄存器rbp偏移-4地址的数据
mov rax, [rax+rcx*4+8] ; 复杂寻址模式,基址+索引*比例+偏移

3.5 标签与跳转

标签(label)是代码中跳转的目标标识符,以冒号结尾。跳转指令可用于流程控制:

start:
    cmp eax, ebx
    je equal_label
    jmp end_label

equal_label:
    ; 执行相等逻辑
    jmp end_label

end_label:
    ; 结束

6 汇编中的伪指令(伪操作)

伪指令不是CPU指令,编译时指导汇编器如何处理数据或代码:

  • db — 定义字节
  • dw — 定义字(2字节)
  • dd — 定义双字(4字节)
  • dq — 定义四字(8字节)
  • resb — 申请未初始化字节空间
  • equ — 定义常量

示例:

msg db 'Hello, World!', 0
num dw 0x1234
buffer resb 64

7 程序入口与调用规范

在 Linux 下,裸汇编程序一般以 _start 作为入口标签:

global _start
_start:
    ; 程序开始执行的代码

操作系统调用终止程序用 exit 系统调用(x86-64 Linux 用 syscall 指令):

mov rax, 60   ; exit syscall
xor rdi, rdi  ; exit code 0
syscall

8 汇编示例:Hello World(Linux x86-64)

section .data
    msg db 'Hello, World!', 10
    len equ $ - msg

section .text
    global _start

_start:
    mov rax, 1          ; syscall: write
    mov rdi, 1          ; fd stdout
    mov rsi, msg        ; msg address
    mov rdx, len        ; msg length
    syscall

    mov rax, 60         ; syscall: exit
    xor rdi, rdi        ; exit code 0
    syscall

9 常用调试与汇编查看技巧

  • 使用 nasm 进行汇编汇编:

    nasm -f elf64 hello.asm -o hello.o
    
  • 使用 ld 链接生成可执行文件:

    ld hello.o -o hello
    
  • objdump 查看反汇编:

    objdump -d hello
    
  • gdb 断点调试汇编代码


10 总结

  • 汇编语言由段和指令组成,分明的代码结构是清晰编程的基础。
  • 掌握基础指令及寄存器用法是汇编编程核心。
  • 汇编支持多种寻址方式,灵活操控内存和寄存器。
  • 标签与跳转是控制流实现的关键。
  • 伪指令帮助数据定义与空间管理。
  • 通过示例掌握程序入口和系统调用能快速入门。
  • 调试工具是理解汇编执行过程的必要利器。

网站公告

今日签到

点亮在社区的每一天
去签到