深入浅出 LEA 指令: x86 汇编中的地址计算神器


hello-assembly 深入浅出 LEA 指令: x86 汇编中的地址计算神器 Assembly 学习笔记 汇编语言 Assembly 程序设计 计算机

汇编语言

什么是 LEA 指令?

在 x86 汇编语言中,LEA(Load Effective Address)指令用于**计算一个内存地址的值并存入寄存器**,但并不访问该地址对应的内存内容。

它非常适合用来做指针运算、地址偏移等操作。

基本语法

LEA destination, source
  • destination:必须是一个寄存器(如 eax, ebx 等)
  • source:是一个有效的内存地址表达式,如 [ebx + ecx*4 + 8]

实际示例

lea eax, [ebx + ecx*4 + 8]

假设:

  • ebx = 1000
  • ecx = 3

那么上述指令的效果为:

eax = 1000 + 3 * 4 + 8 = 1020

注意:它**不会访问内存地址 1020 的内容**,只是把地址本身算出来放进 eax

LEA 的常见用途

  1. 指针运算

        mov esi, [ebp+8]     ; 从栈中读取一个指针  
        lea eax, [esi+4]     ; 相当于 pointer + 1(一个 int 是 4 字节)  
        
  2. 高效的乘法和加法

        lea eax, [eax + eax*2]   ; eax = eax * 3  
        
  3. 数组索引

        lea eax, [array + edi*4] ; 计算 array[edi] 的地址  
        

LEA 与 MOV 的区别

指令 说明
mov eax, [ebx + 4] 从内存地址 ebx + 4 中读取值到 eax
lea eax, [ebx + 4] 将地址 ebx + 4 的值计算后存入 eax

C 编译器中生成的 LEA 示例

C 代码如下:

int foo(int* arr, int i) {
    return arr[i + 2];
}

使用 GCC 编译并查看汇编输出(gcc -O2 -S foo.c -o foo.s)可能得到如下(简化后):

foo:
    lea     eax, [rsi+2]
    mov     eax, DWORD PTR [rdi+rax*4]
    ret

解释:

  • rdi 保存的是数组 arr 的首地址
  • rsi 是传入的索引 i
  • lea eax, [rsi + 2]i + 2 算好存入 eax(不访问内存)
  • 接着通过 [rdi + rax*4] 取数组中的第 i + 2 项(每项 4 字节)

64-bit 模式下 LEA 的用法

在 x86-64(即 64-bit 模式)中,LEA 同样强大,并能操作 64 位寄存器(如 rax, rbx, rsi, rdi 等)。

lea rax, [rbx + rcx*8 + 16]

这条指令的作用是:

rax = rbx + rcx * 8 + 16

常用于结构体成员访问、数组遍历、栈帧偏移等场景。

64-bit 示例:结构体成员地址计算

C 代码:

struct Point {
    int x;
    int y;
};

int* get_y(struct Point* p) {
    return &p->y;
}

对应汇编(GCC 生成,优化后):

get_y:
    lea     rax, [rdi+4]
    ret

这里假设 int 为 4 字节,y 紧随 x,所以 &p->y = p + 4。因此直接使用 lea 得到地址,而无需访问内存。

总结补充

LEA 是汇编语言中强大的工具之一。它不像名字那样“加载”数据,而是更像是一个“指针运算器”。

无论是做复杂偏移、模拟乘法、还是指针遍历,只要涉及地址计算,你都应该想到 LEA

学习汇编语言,理解 LEA 是迈向系统底层编程的关键一步。

  • 编译器很喜欢用 LEA 来做常数加法、索引乘法,而不是使用加法或乘法指令
  • LEA 在 64-bit 模式下可以处理更大的地址空间,更常见于系统级编程
  • 它提供了一种“零内存访问”的方式,极大提高了性能

汇编语言

英文:Understanding the LEA Instruction: A Powerful Tool for Address Calculation in x86 Assembly

本文一共 610 个汉字, 你数一下对不对.
深入浅出 LEA 指令: x86 汇编中的地址计算神器. (AMP 移动加速版本)
上一篇: 买借死 Buy Borrow Die: 富人如何合法避税而我们却在交税
下一篇: 用Copilot AI来审核区块链钱包代码

扫描二维码,分享本文到微信朋友圈
13ac56b35fd564ff3198c2b480f3921c 深入浅出 LEA 指令: x86 汇编中的地址计算神器 Assembly 学习笔记 汇编语言 Assembly 程序设计 计算机

评论