3.3 内存引用

x86-64 提供灵活的内存寻址模式,可以高效地计算地址并访问内存。最通用的形式是 Imm(Reg, Reg, Scale) 格式。

通用寻址格式

地址 = Imm + Reg1 + Reg2 × Scale
组成部分含义可取值
Imm立即数偏移1, 2 或 4 字节的常数
Reg1基址寄存器任意通用寄存器
Reg2变址寄存器任意通用寄存器(除 %rsp)
Scale比例因子1, 2, 4, 8

寻址模式分类

1. 立即数寻址

仅包含立即数偏移,用于访问静态全局变量。

movq    0x1234, %rax        # 从地址 0x1234 读取
movq    global_var, %rax    # 从符号 global_var 的地址读取

2. 寄存器间接寻址

最常用的形式,按寄存器中的地址访问内存。

movq    (%rax), %rbx        # rbx = *(uint64_t *)rax
movq    %rbx, (%rax)        # *(uint64_t *)rax = rbx

对应 C 语言的指针解引用:

long val = *ptr;   // movq (%rax), %rbx
*ptr = val;        // movq %rbx, (%rax)

3. 基址+偏移量寻址

常用于访问结构体成员或栈上局部变量。

movq    8(%rbp), %rax       # 从 rbp+8 地址读取
movl    -4(%rbp), %eax      # 从 rbp-4 地址读取(局部变量)

对应 C 语言的结构体访问:

struct S { long a; long b; };
struct S s;
s.b = 10;    // movq $10, 8(%rdi)  其中 %rdi 指向 s

4. 变址寻址

常用于数组访问。

movq    (%rdi, %rsi, 8), %rax    # rax = *(rdi + rsi*8)

对应 C 语言的数组访问:

long arr[N];
long val = arr[i];   // movq (%rdi, %rsi, 8), %rax
// %rdi = &arr[0], %rsi = i

5. 比例变址寻址

结合所有组件。

movq    8(%rdi, %rsi, 4), %rax   # rax = *(rdi + rsi*4 + 8)

所有寻址模式总表

类型AT&T 格式地址计算使用场景
立即数ImmImm全局变量
寄存器(Reg)Reg指针解引用
基址+偏移Imm(Reg)Reg + Imm结构体/栈访问
变址(Reg, Reg)R1 + R2数组(元素大小为 1)
比例变址(Reg, Reg, S)R1 + R2×S数组 access (S=元素大小)
基址+比例变址+偏移Imm(Reg, Reg, S)Imm + R1 + R2×S复合场景

常见应用模式

数组遍历

# int arr[N];  元素大小 4 字节
# 假设 %rdi = &arr[0], %rsi = i
movl    (%rdi, %rsi, 4), %eax    # arr[i]

二维数组

# long A[M][N];  元素大小 8 字节,每行 N 个元素
# 访问 A[i][j]:地址 = A + i*N*8 + j*8
# %rdi = A, %rsi = i, %rdx = j
imulq   $N, %rsi, %rsi           # rsi = i * N
addq    %rsi, %rdi               # rdi = A + i*N*8  (隐式×8)
movq    (%rdi, %rdx, 8), %rax    # rax = A[i][j]

详见 。

结构体访问

# struct S { int x; long y; int z; };
# %rdi 指向 struct S
movl    (%rdi), %eax             # s.x (偏移 0)
movq    8(%rdi), %rdx            # s.y (偏移 8, 因对齐)
movl    16(%rdi), %ecx           # s.z (偏移 16)

地址计算与 lea 指令

利用寻址模式的计算能力,在不访问内存的情况下完成算术运算:

leaq    (%rdi, %rsi, 4), %rax    # rax = rdi + rsi*4 (不访问内存)

相关笔记

    • 内存引用作为操作数
    • 地址计算与算术运算
    • 数组的内存布局与访问
    • 结构体成员的内存偏移

链接到