4

I'm running through some assembly code and I can't figure out what a line of code does. The code is:

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

I know lea is basically a type of mov instruction, but it only moves the address. So we are moving the address of something to %rdx (making %rdx "point" to something on the stack). I know what %rax points to on the stack (say, -28(%rbp)), but I'm confused by how to multiply that with 4 to get my answer. Would %rdx point to 4*(-28) = -112(%rbp)?

Thanks!

EDIT: For context, the following code precedes this instruction:

pushq   %rbp 
movq    %rsp, %rbp 
movl    %esi, -28(%rbp)
movl    -28(%rbp), %eax 
cltq 
leaq    0(,%rax,4), %rdx
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106
pauliwago
  • 6,373
  • 11
  • 42
  • 52
  • sometime `lea` is also used for calculations. hard to say in your case because you dont give enough code to see. – David J Nov 13 '12 at 02:39
  • Also the 0 on the outside seems unnecessary since it is just going to add nothing to the address. Unless you need it to indirectly access the memory. – emschorsch Nov 13 '12 at 02:42
  • @Fermat2357 I added a summary of the code that precedes the instruction. Hope that's enough @emschorsch I agree; I think the `0` is pointless too; it must have been generated by the compiler – pauliwago Nov 13 '12 at 02:45
  • 1
    As you can see, whatever is in `%esi` will copied on the stack and then copied to `%eax`. Next `%eax` is extended to 64bit `rax` by the machine command `cltq`. At the end the `leaq` command will multiply `%rax` by 4 and store it into `%rdx`. To be sure for what the hell it is done we need to see what will happen to `%rdx` later. – David J Nov 13 '12 at 03:37
  • Possible duplicate of [What's the purpose of the LEA instruction?](http://stackoverflow.com/questions/1658294/whats-the-purpose-of-the-lea-instruction) – Ross Ridge Mar 29 '17 at 03:04

2 Answers2

4

Your equivalent C code is something like:

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

n is passed as a single 32-bit register esi, which is stored to local stack frame. The parameter is then used in evaluation the 64-bit expression 4*a. The '0' can be explained if it's supposed to be relocated by the linker to the address 'arr'.

Then my guess is that the assembly code is not generated by gcc -S foo.c, but by 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
Aki Suihkonen
  • 19,144
  • 1
  • 36
  • 57
  • 1
    You may as well imagine the expression evaluated is &arr[4*n]. (In the disassembly I used arr[4*a], so it uses mov instead of lea.) – Aki Suihkonen Nov 13 '12 at 05:53
1

I believe the code is moving whatever is at the address in %rbp-28 into %eax. This will probably be an integer. Then it is just moving that value*4 into %rdx (The 64 bit version of %eax similar to the way %ah is the high order bytes of %eax). This question seems to discuss a similar issue.

Community
  • 1
  • 1
emschorsch
  • 1,619
  • 3
  • 19
  • 33