13

Hello I need some help understanding what is going on in this assembly code:

        .file   "mystery.c"

        .text

        .globl mystery

              .type mystery, @function

 mystery:
   pushq    %rbp
    movq    %rsp, %rbp

   movl %edi, -20(%rbp)
   movl $1, -16(%rbp)
   movl $0, -12(%rbp)
   movl $0, -8(%rbp)
   cmpl $2, -20(%rbp)
   jg   .L2
   movl $1, %eax
   jmp  .L3

  .L2:
movl    $2, -4(%rbp)
jmp .L4

  .L5:
movl    -12(%rbp), %eax
movl    -16(%rbp), %edx
leal    (%rdx,%rax), %eax
movl    %eax, -8(%rbp)
movl    -16(%rbp), %eax
movl    %eax, -12(%rbp)
movl    -8(%rbp), %eax
movl    %eax, -16(%rbp)
addl    $1, -4(%rbp)

.L4:
movl    -4(%rbp), %eax
cmpl    -20(%rbp), %eax
jle .L5
movl    -8(%rbp), %eax

.L3:
leave
ret

I understand exactly what is going on UNTIL I get to .L5, Here the command leal(%rdx, %rax), eax is what is confusing me. Up until now ive been moving values to eax and edx and now im adding the values in rdx and rax. Where is rdx and rax coming from and what values are they holding? Are they just another way of writing eax and edx? Thanks for any help.

Yotam Omer
  • 15,310
  • 11
  • 62
  • 65
Rizwan Chaudry
  • 169
  • 1
  • 2
  • 11

3 Answers3

20

See this related answer. It explains the different registers and their evolution. In this case, the %rax register is a 64 bit register. %eax is the 32 bit one, and %ax would be 16 bits. %ah refers to the high 8 bits of the 16 bits in the register, and %al refers to the lower end.

This little diagram was taken from another answer to the same question, but it shows it well...

|63..32|31..16|15-8|7-0|
               |AH.|AL.|
               |AX.....|
       |EAX............|
|RAX...................|
Community
  • 1
  • 1
CoffeeRain
  • 4,460
  • 4
  • 31
  • 50
8

Those are "really just" other ways to describe a register. Depending on the "prefix", they're either 64, 32, 16 or 8 bits:

  • rax - 64 bits
  • eax - 32 bits
  • ax - 16 bits
  • ah - upper 8 bits of ax
  • al - lower 8 bits of ax
Linus Kleen
  • 33,871
  • 11
  • 91
  • 99
3

Because in 64bit mode, lea with a 64bit "address" and a 32bit destination is the shortest encoding.

Making it a 32bit address doesn't affect the result, but costs a byte.

harold
  • 61,398
  • 6
  • 86
  • 164
  • But why not a simple `mov eax, edx`? – phuclv Oct 03 '13 at 08:02
  • @LưuVĩnhPhúc well it adds them, it could have been an `addl %edx, %eax` (aka `add eax, edx`) though. – harold Oct 03 '13 at 08:11
  • yes I know, but why should a lea be used rather than a mov? Will it be faster/shorter – phuclv Oct 03 '13 at 08:15
  • @LưuVĩnhPhúc there is, as far as I know, no reason to ever use a `lea` if a `mov` could have been used instead. It isn't shorter, and `lea` has slightly lower throughput than `mov` on many µarchs. – harold Oct 03 '13 at 08:46