Что такое 0x10 в инструкции по сборке «leal 0x10 (% ebx),% eax» x86?
Какова функция 0x10 в отношении этой инструкции LEAL? Является ли это умножением или добавлением или что-то еще?
leal 0x10(%ebx), %eax
Может кто-то прояснить? Это ассемблер x86 в ящике Linux.
- Что будет использоваться для обмена данными между streamами, выполняются на одном ядре с HT?
- Сколько байтов вводит push-команду в стек, если я не укажу размер операнда?
- Что отсутствует / не оптимально в этой реализации memcpy?
- x86-32 / x86-64 многоугольный fragment машинного кода, который обнаруживает 64-битный режим во время выполнения?
- Что каждый программист должен знать о памяти?
- Режимы адресации на языке сборки (IA-32 NASM)
- Какова цель инструкции «ПАУЗА» в x86?
- Проверьте, равен ли регистр нулю с помощью CMP reg, 0 против OR reg, reg?
- В чем смысл MOV (% r11,% r12,1),% edx?
- Что означает «int 0x80» в коде сборки?
- Как разобрать 16-разрядный код загрузочного сектора x86 в GDB с помощью «x / i $ pc»? Он рассматривается как 32-битный
- Есть ли у блокировки xchg то же поведение, что и mfence?
- Самая быстрая встроенная спин-блокировка
leal или lea полное имя «Загрузить эффективный адрес», и он делает именно это: он вычисляет адрес.
В вашем примере вычисление адресов очень просто, поскольку оно просто добавляет смещение к ebx и сохраняет результат в eax:
eax = ebx + 0x10
lea может сделать намного больше. Он может добавлять регистры, умножать регистры с константами 2, 4 и 8 для адресных вычислений слов, целых чисел и удвоений. Он также может добавить смещение.
Обратите внимание, что lea является особенным в том смысле, что он никогда не будет изменять флаги, даже если вы используете его как простое дополнение, как в приведенном выше примере. Компиляторы иногда используют эту функцию и заменяют добавление с помощью lea, чтобы помочь планировщику. Это не редкость видеть, что инструкции lea выполняют простую арифметику в скомпилированном коде по этой причине.
lea
означает «эффективный адрес загрузки»; это способ использовать сложные методы адресации набора инструкций IA32 для выполнения арифметики. Суффикс l
– это способ различить размер операндов команд в синтаксисе GNU как, что у вас есть на вашем Linux-поле.
Итак, короче говоря, да, это своего рода дополнительная инструкция. Он также может обрабатывать умножения на 2, 4 или 8 одновременно.
См. Также этот связанный вопрос (где они используют синтаксис Intel для обсуждения одной и той же инструкции):
GNU как 2.18 документов
https://sourceware.org/binutils/docs-2.18/as/i386_002dMemory.html
AT & T: -4 (% ebp), Intel: [ebp – 4]
а затем синтаксис Intel сам объясняет.
Что еще более важно, документы также объясняют общий случай:
Ссылка на косвенную память синтаксиса Intel формы
section:[base + index*scale + disp]
преобразуется в синтаксис AT & T
section:disp(base, index, scale)
где base и index являются необязательными 32-разрядными базовыми и индексными регистрами, disp – это необязательное смещение, а масштаб, принимающий значения 1, 2, 4 и 8, умножает индекс для вычисления адреса операнда
В AT & T все происходит немного, когда мы опускаем некоторые части адреса, например, -4(%ebp)
, но с примерами в документах мы можем легко вывести все случаи синтаксиса.
Чтобы действительно понять, что происходит, я рекомендую вам взглянуть на то, как кодируются инструкции. Это хороший учебник: http://www.c-jump.com/CIS77/CPU/x86/lecture.html Когда вы это увидите, станет ясно, почему некоторые части адреса могут быть опущены и что каждая форма будет компилироваться.
Чтобы добавить к ответу Нилса,
Как обновитель, режим addresing в ассемблере IA32 обычно имеет вид:
IO (Rb, Ri, s), где:
IO = немедленное смещение
Rb = базовый регистр
Ri = индексный регистр
s = коэффициент масштабирования {1, 2, 4, 8}
Таким образом, эффективный адрес вычисляется как * IO + [Eb] + [Ei] s
leal похож на другие инструкции, такие как movl, но это немного особенное. Вместо чтения из источника в пункт назначения он копирует эффективный адрес источника в пункт назначения.
Таким образом, его можно использовать для создания указателей для последующих ссылок на память, а также для основных арифметических операций, как указал Нилс.
Например:
пусть register% edx содержит значение x
leal 1 (% edx,% edx, 8),% eax
будет загружать эффективный адрес 1 + x + 8 * x = 1 + 9x для регистрации% eax.
По существу, операция:
исходный источник , destination => destination = адрес источника
Если вы знакомы с C, это эквивалентно:
char * b = & a;
где адрес char a назначается указателю char b
больше примеров:
Пусть зарегистрировано значение% eax hold x и зарегистрировано значение% ecx hold y
leal (% eax,% ecx, 4),% edx назначит значение x + 4y для регистрации% edx
leal 0xB (,% ecx, 5),% edx назначит значение 0xB + 5y = 11 + 5y to% edx
leal (% eax,% eax, 2),% eax назначит значение 3x для регистрации% eax
Надеюсь это поможет