Даже если бы оно было кодируемым, вы бы никогда не захотели его использовать.
Если вы хотите поместить константу в регистр, вы никогда не должны использовать lea
.mov $1234, %eax
короче и эффективнее lea 1234, %eax
(абсолютный адрес в режиме адресации disp32).
Единственным вариантом использования LEA для статических адресов является 64-битный код с режимами адресации, относящимися к RIP,как lea symbol(%rip), %rax
(7 байт), в случаях, когда mov $symbol, %eax
(5 байт) не может быть использован, потому что вам нужен независимый от позиции код, и / или адрес не помещается в 32-битный с немедленным расширением нуля.
См. Разница между movq и movabsq в x86-64 , чтобы узнать больше о том, почему mov $symbol, %rdi
не лучший выбор.
В 32-битном коде lea symbol, %edi
имеет размер 6 байт (код операции + modrm + disp32) и работает только на одном порту 1 или 5 на процессорах семейства Intel Sandybridge.(https://agner.org/optimize/)
mov $symbol, %edi
составляет 5 байтов ( код операции + краткая форма imm32 без байта ModRM ) и работает на любом порту ALU.
То же для 16-битный код: mov $symbol, %di
- 3 байта, а lea symbol, %di
- 4 байта с одинаковыми различиями портов выполнения (или в синтаксисе NASM: lea di, [symbol]
против mov di, symbol
или mov di, OFFSET symbol
в GAS .intel_syntax
или MASM.)
LEA, тем не менее, полезен в режимах адресации base = register. Как и lea symbol(%rdi), %rax
, если адрес соответствует 32-битному расширенному знаку disp32.
Или для произвольного использования сдвига и добавления, например, lea 123(%rdi, %rdi, 2), %eax
для выполнения eax = 3*edi + 123
. Использование LEA для значений, которые не являются адресами / указателями?