Должен ли первый операнд leaq быть адресом памяти, а второй операнд - регистром? - PullRequest
0 голосов
/ 26 октября 2018

В языке ассемблера ATT при использовании команды leaq должен ли его первый операнд быть адресом памяти вместо регистра или константы (с префиксом $)?Должен ли его второй операнд быть регистром?Я получил такое впечатление, читая «Компьютерные системы: перспектива программиста», и никогда не видел пример, отличный от моего предположения.Благодаря.

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

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

Если вы хотите поместить константу в регистр, вы никогда не должны использовать 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 для значений, которые не являются адресами / указателями?

0 голосов
/ 26 октября 2018

Да, это правильно.Хотя lea с двумя операндами регистра технически может быть закодировано, такое кодирование недопустимо и приводит к исключению #UD.См. эту ссылку или эту для деталей.

...