Не уверен, почему мы добавляем регистры% 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? Спасибо за любую помощь.
Ответы
Ответ 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-битный адрес не влияет на результат, но стоит байт.