大会:有人可以用leaq指令解释这行吗?

时间:2012-11-13 02:32:19

标签: assembly 64-bit

我正在运行一些汇编代码,我无法弄清楚代码行的作用。代码是:

 leaq   0(,%rax,4), %rdx

我知道lea基本上是一种mov指令,但它只会移动地址。因此,我们将某些内容的地址移至%rdx(使%rdx“指向”堆栈中的内容。我知道%rax指向堆栈上的内容(比如-28(%rbp)),但我对如何将其与4相乘以获得我的答案感到困惑。 %rdx会指向4*(-28) = -112(%rbp)吗?

谢谢!

编辑: 对于上下文,以下代码在此指令之前:

pushq   %rbp 
movq    %rsp, %rbp 
movl    %esi, -28(%rbp)
movl    -28(%rbp), %eax 
cltq 
leaq    0(,%rax,4), %rdx

2 个答案:

答案 0 :(得分:4)

您的等效C代码如下:

extern int32 arr[];
int my_func(int32 n, ...) {
   int32 a=n;
   ...
   arr[a];
   ...
}

n作为单个32位寄存器esi传递,它存储在本地堆栈帧中。 然后该参数用于评估64位表达式4 * a。如果它应该由链接器重新定位到地址'arr',则可以解释'0'。

然后我的猜测是汇编代码不是由...生成的 gcc -S foo.c,但gcc -c foo.c; objdump -d foo.o

   // Similar code from a 32-bit machine
   0:   55                      push   %ebp
   1:   89 e5                   mov    %esp,%ebp
   3:   8b 45 08                mov    0x8(%ebp),%eax
   6:   8b 04 85 00 00 00 00    mov    0x0(,%eax,4),%eax
   d:   5d                      pop    %ebp
   e:   c3                      ret
   f:   90                      nop

答案 1 :(得分:1)

我相信代码正在将%rbp-28中的地址移动到%eax。这可能是一个整数。然后它只是将value*4移动到%rdx%eax的64位版本,类似于%ah%eax的高位字节的方式。 This question似乎在讨论类似的问题。