Подтвердить что ты не робот

Не уверен, почему мы добавляем регистры% rdx и% rax, когда код сборки использует% eax и% edx

Здравствуйте, мне нужна помощь в понимании того, что происходит в этом ассемблере:

        .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

Я точно понимаю, что происходит с UNTIL. Я получаю .L5. Здесь команда leal(%rdx, %rax), eax - это то, что меня смущает. До сих пор ive перемещал значения в eax и edx и теперь im добавляло значения в rdx и rax. Откуда берутся rdx и rax и какие значения они держат? Это просто еще один способ написания eax и edx? Спасибо за любую помощь.

4b9b3361

Ответ 1

См. этот связанный ответ. Он объясняет разные регистры и их эволюцию. В этом случае регистр %rax представляет собой 64-битный регистр. %eax - 32-битный, а %ax - 16 бит. %ah относится к высоким 8 битам из 16 бит в регистре, а %al относится к нижнему концу.

Эта небольшая диаграмма была взята из другого ответа на тот же вопрос, но это хорошо показывает...

|63..32|31..16|15-8|7-0|
               |AH.|AL.|
               |AX.....|
       |EAX............|
|RAX...................|

Ответ 2

Это "действительно просто" другие способы описания регистра. В зависимости от "префикса" они либо 64, 32, 16, либо 8 бит:

  • rax - 64 бит
  • eax - 32 бит
  • ax - 16 бит
  • ah - верхние 8 бит ax
  • al - нижние 8 бит ax

Ответ 3

Потому что в 64-битном режиме lea с 64-битным "адресом" и 32-разрядным назначением является самой короткой кодировкой.

Сделать 32-битный адрес не влияет на результат, но стоит байт.