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

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

Да, это правильно. В случае сомнений обратитесь к официальному справочнику по набору инструкций. Обратите внимание, что адрес памяти, конечно, может использовать регистр или смещение (без $, поскольку это было бы немедленно).

Jester 26.10.2018 00:11

Спасибо. Я искал справочный документ в Интернете, но не уверен, где он находится.

user10082400 26.10.2018 00:12
Руководства для разработчиков программного обеспечения для архитектур Intel® 64 и IA-32 PS: использует синтаксис Intel, отличный от & t, поэтому вам придется потрудиться в уме :)
Jester 26.10.2018 00:13

@Jester Спасибо. Какие виды умственной работы?

user10082400 26.10.2018 00:21

Перевод с intel на at & t. Например. С [base+index*scale+displacement] на displacement(base, index, scale)

Jester 26.10.2018 00:37

@fuz, вы можете удалить этот комментарий и попробовать еще раз.

prl 26.10.2018 05:26

Также меняем порядок операндов (Intel - dest, src, а AT&T - src, dest).

fuz 26.10.2018 11:13
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
7
88
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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

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

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

Другие вопросы по теме