【问题标题】:x86-64 instruction set, AT&T syntax, confusion regarding lea and bracketsx86-64 指令集、AT&T 语法、关于 lea 和括号的混淆
【发布时间】:2020-08-01 21:31:20
【问题描述】:

有人告诉我 lea %rax, %rdx 是无效语法,因为源代码需要放在括号中,即 lea (%rax), %rdx

我想我显然误解了 lea 和括号的用途。

我以为 lea %rax, %rdx 会将存储在 %rax, 中的内存地址移动到 %rdx,但显然这就是 lea (%rax), %rdx 的作用?

让我感到困惑的是,我认为括号表示转到内存中的某个地址,并获取该地址的值。因此,通过使用方括号 lea 会将值从存储在 %rax 中的内存地址移动到目标寄存器中。

因此,如果您只是想将存储在 %rax 中的地址移动到 %rdx 中,我认为会使用 lea %rax, %rdx

在 lea 指令的情况下,有人可以向我解释括号的意义吗?

【问题讨论】:

  • 这也让我作为初学者感到困惑。它基本上只是在说“将其视为间接内存访问,具有相同的计算和约束,但最后不要取消引用它,只需给我最终地址”。但是因为除了实际访问之外,它的处理方式与间接访问相同,因此它具有相同的语法。
  • lea 对于偏移量和乘数更有用。 lea (%rax), %rdxmov %rax, %rdx 没有什么不同。但是你也可以做类似lea (%rdx, %rdx, 4), %rax 这样的事情,它本质上是rax = rdx + rdx * 4,即rax = rdx * 5,你不能用一个mov来做。这种算术用法(而不涉及任何实际内存地址)本质上是间接寻址模式允许的(有限)数学运算的副产品。
  • @CherryDT 我明白了,谢谢,所以括号只是表示我们将其视为间接内存地址,而不是内存中的值?
  • 是的,它基本上做了mov (...) 会做的所有事情,除了实际读取内存地址内容的最后一步。

标签: assembly x86-64 att instruction-set


【解决方案1】:

从不实际使用lea (%rax), %rdx。请改用mov %rax, %rdx,因为 CPU 运行它的效率更高,并且两种方式都复制一个寄存器 value(无论该值是否是有效指针)。

LEA 只能在内存寻址模式下工作,而不能在裸寄存器上工作。 LEA 有点“撤消”括号,获取地址计算的结果,而不是该地址的内存中的值。如果一开始就没有内存操作数,就不会发生这种情况。

这使您可以使用它对任意值执行移位/加法操作,无论它们是否是有效指针:Using LEA on values that aren't addresses / pointers? LEA 使用内存操作数语法和机器代码来编码移位/将操作添加到单个指令中,使用 CPU 硬件已经知道如何解码的 x86 的正常寻址模式编码。


mov 相比,它类似于C 中的& 地址运算符。而且您不能获取寄存器的地址。 (或者在 C 中,register 变量。)您只能使用它来撤消取消引用。

  register char *rax = ...;

  register char dl = *rax;       // mov   (%rax), %dl
  register char *rcx = rax;      // mov   %rax, %rcx
  register char *rdi = &rax[0];  // lea   (%rax), %rdi  // never do this, mov is more efficient
  register char *rbx = &rax[rdx*4 + 1234];  // lea 1234(%rax, %rdx, 4), %rbx  // a real use-case
  
  register char **rsi = &rax;    // lea %rax, %rsi   // ERROR: can't take the address of a register

当然,如果你让一个实际的 C 编译器来编译它,你会得到mov %rax, %rdi,而不是lea (%rax), %rdi,即使它没有优化掉代码。 这是概念上的等价物,使用 C 语法和运算符来解释 asm,而不是显示任何东西将如何或应该如何实际编译。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 2012-02-27
    • 1970-01-01
    • 2013-09-10
    • 2013-06-30
    • 1970-01-01
    相关资源
    最近更新 更多