Intel x86 Assembly Language & Microarchitecture
Поток управления
Поиск…
Безусловные прыжки
jmp a_label ;Jump to a_label
jmp bx ;Jump to address in BX
jmp WORD [aPointer] ;Jump to address in aPointer
jmp 7c0h:0000h ;Jump to segment 7c0h and offset 0000h
jmp FAR WORD [aFarPointer] ;Jump to segment:offset in aFarPointer
Относительные близкие прыжки
jmp a_label :
- возле
Он указывает только смещение части логического адреса адресата. Сегмент считаетсяCS. - родственник
Семантика команды - это переход с перекрестными байтами вперед 1 из следующего адреса инструкции илиIP = IP + rel.
Инструкция кодируется как EB <rel8> или EB <rel16/32> , сборщик EB <rel16/32> наиболее подходящую форму, обычно предпочитая более короткую.
Возможно jmp SHORT a_label ассемблер, например, с помощью NASM jmp SHORT a_label , jmp WORD a_label и jmp DWORD a_label генерируют три возможные формы.
Абсолютное косвенное приближение
jmp bx и jmp WORD [aPointer] :
- возле
Они указывают только смещенную часть логического адреса адресата. Сегмент считаетсяCS. - абсолютное
Семантика инструкций переходит на адрес в регистре или mem илиIP = reg,IP = mem.
Инструкция кодируется как FF /4 , для косвенной памяти размер операнда определяется как для любого другого доступа к памяти.
Абсолютные далеко прыжки
jmp 7c0h:0000h :
далеко
Он определяет обе части логического адреса: сегмент и смещение.absolute Семантика команды - переход к сегменту адреса : смещение или
CS = segment, IP = offset.
Инструкция кодируется как EA <imm32/48> зависимости от размера кода.
В некоторых ассемблерах можно выбирать между двумя формами, например, с помощью NASM jmp 7c0h: WORD 0000h и jmp 7c0h: DWORD 0000h сгенерировать первую и вторую формы.
Абсолютные косвенные дальние прыжки
jmp FAR WORD [aFarPointer] :
far Он определяет обе части логического адреса: сегмент и смещение.
Абсолютная косвенная семантика команды - переход к сегменту: смещение, сохраненное в mem 2 или
CS = mem[23:16/32], IP = [15/31:0].
Инструкция кодируется как FF /5 , размер операнда может быть контроллером с спецификаторами размера.
В NASM, немного не интуитивно понятные, это jmp FAR WORD [aFarPointer] для операнда 16:16 и jmp FAR DWORD [aFarPointer] для операнда 16:32 .
Отсутствие прыжков
вблизи абсолютного
Можно эмулировать с почти косвенным прыжком.mov bx, target ;BX = absolute address of target jmp bxдалеко относительный
В любом случае, никакого смысла или слишком узкого использования.
1 Два дополнения используются для указания смещенного смещения и, следовательно, перехода назад.
2 Который может быть seg16: off16 или seg16: off32 , размеров 16:16 и 16:32 .
Условия тестирования
Для использования условного перехода необходимо проверить состояние. Тестирование условия здесь относится только к действию проверки флагов, фактический прыжок описывается в разделе « Условные прыжки» .
x86 проверяет условия, полагаясь на регистр EFLAGS, который содержит набор флагов, которые каждая команда может установить.
Арифметические инструкции, такие как sub или add , и логические инструкции, такие как xor или, and , очевидно, «устанавливают флаги». Это означает, что флаги CF , OF , SF , ZF , AF , PF модифицируются этими инструкциями. Любая инструкция может изменять флаги, например, cmpxchg модифицирует ZF .
Всегда проверяйте ссылку на команду, чтобы знать, какие флаги изменены определенной инструкцией.
x86 имеет набор условных переходов , упомянутых ранее, которые скапливаются тогда и только тогда, когда установлены некоторые флаги, или некоторые из них ясны или оба.
Флаги
Арифметические и логические операции очень полезны при установке флагов. Например, после sub eax, ebx , для хранения значений без знака , мы имеем:
| Флаг | Когда установлено | Когда |
|---|---|---|
| ZF | Когда результат равен нулю. EAX - EBX = 0 ⇒ EAX = EBX | Когда результат не равен нулю. EAX - EBX ≠ 0 ⇒ EAX ≠ EBX |
| CF | Когда результат понадобился переносить для MSb. EAX - EBX <0 ⇒ EAX <EBX | Когда результат не нужно переносить для MSb. EAX - EBX ≮ 0 ⇒ EAX ≮ EBX |
| SF | Когда задан результат MSb. | Когда результат MSb не установлен. |
| О | Когда произошло переполнение подписей. | Когда подписанное переполнение не произошло. |
| PF | Когда количество бит, заданное в младшем значении, равно четному результату. | Когда число бит, заданное в младшем значении байта результата, является нечетным. |
| AF | Когда нижняя цифра BCD генерирует перенос. Это бит 4. | Когда нижняя цифра BCD не генерирует перенос. Это бит 4. |
Неразрушающие испытания
sub и and инструкции изменяют свой операнд назначения и требуют двух дополнительных копий (сохранение и восстановление), чтобы сохранить цель немодифицированной.
Для выполнения неразрушающего теста есть инструкции cmp и test . Они идентичны их деструктивным аналогам, за исключением того, что результат операции отбрасывается, и сохраняются только флаги .
| разрушительный | Неразрушающий |
|---|---|
sub | cmp |
and | test |
test eax, eax ;and eax, eax
;ZF = 1 iff EAX is zero
test eax, 03h ;and eax, 03h
;ZF = 1 if both bit[1:0] are clear
;ZF = 0 if at least one of bit[1:0] is set
cmp eax, 241d ;sub eax, 241d
;ZF = 1 iff EAX is 241
;CF = 1 iff EAX < 241
Подписанные и неподписанные тесты
ЦП не дает особого значения для регистрации значений 1 , знак - это программа-программист. Нет никакой разницы при тестировании подписанных и неподписанных значений. Процессор вычисляет достаточно флагов для проверки обычных арифметических отношений (равных, меньше, больше и т. Д.), Как если бы операнды считались подписанными и неподписанными.
1 Хотя в нем есть некоторые инструкции, которые имеют смысл только в определенных форматах, например, в дополнении. Это должно сделать код более эффективным, так как реализация алгоритма в программном обеспечении потребует большого количества кода.
Условные прыжки
На основе состояния флагов ЦП может выполнять или игнорировать скачок. Инструкция, выполняющая прыжок на основе флагов, подпадает под общее название Jcc- Jump on Condition Code 1 .
Синонимы и термины
Чтобы улучшить читаемость кода сборки, Intel определила несколько синонимов для одного и того же кода условий. Например, jae , jnb и jnc - одинаковый код условия CF = 0 .
Хотя имя команды может дать очень сильный намек на то, когда ее использовать или нет, единственным значимым подходом является распознавание флагов, которые необходимо протестировать, а затем правильно выбрать инструкции.
Intel, однако, давала имена инструкций, которые имеют прекрасный смысл при использовании после команды cmp . Для целей этого обсуждения cmp будет считаться установленным флажком перед условным прыжком.
равенство
Операнд равен, если ZF установлен, они отличаются друг от друга. Для проверки равенства нам понадобится ZF = 1 .
je a_label ;Jump if operands are equal
jz a_label ;Jump if zero (Synonym)
jne a_label ;Jump if operands are NOT equal
jnz a_label ;Jump if not zero (Synonym)
| инструкция | Флаги |
|---|---|
je , jz | ZF = 1 |
jne , jnz | ZF = 0 |
Лучше чем
Для неподписанных операндов назначение больше, чем источник, если перенос не нужен, то есть, если CF = 0 . Когда CF = 0, возможно, что операнды были равны, тестирование ZF будет неоднозначно.
jae a_label ;Jump if above or equal (>=)
jnc a_label ;Jump if not carry (Synonym)
jnb a_label ;Jump if not below (Synonym)
ja a_label ;Jump if above (>)
jnbe a_label ;Jump if not below and not equal (Synonym)
| инструкция | Флаги |
|---|---|
jae , jnc , jnb | CF = 0 |
ja , jnbe | CF = 0, ZF = 0 |
Для подписанных операндов нам нужно проверить, что SF = 0 , если не было подписанного переполнения, и в этом случае результирующий SF будет отменен. Поскольку OF = 0, если не было подписанного переполнения и 1 в противном случае, нам нужно проверить, что SF = OF .
ZF может использоваться для реализации строгого / нестандартного теста.
jge a_label ;Jump if greater or equal (>=)
jnl a_label ;Jump if not less (Synonym)
jg a_label ;Jump if greater (>)
jnle a_label ;Jump if not less and not equal (Synonym)
| инструкция | Флаги |
|---|---|
jge , jnl | SF = OF |
jg , jnle | SF = OF, ZF = 0 |
Меньше, чем
Они используют перевернутые условия выше.
jbe a_label ;Jump if below or equal (<=)
jna a_label ;Jump if not above (Synonym)
jb a_label ;Jump if below (<)
jc a_label ;Jump if carry (Synonym)
jnae a_label ;Jump if not above and not equal (Synonym)
;SIGNED
jle a_label ;Jump if less or equal (<=)
jng a_label ;Jump if not greater (Synonym)
jl a_label ;Jump if less (<)
jnge a_label ;Jump if not greater and not equal (Synonym)
| инструкция | Флаги |
|---|---|
jbe , jna | CF = 1 или ZF = 1 |
jb , jc , jnae | CF = 1 |
jle , jng | SF! = OF или ZF = 1 |
jl , jnge | SF! = OF |
Специальные флаги
Каждый флаг может быть протестирован индивидуально с помощью j<flag_name> где flag_name не содержит конечную F (например, CF → C , PF → P ).
Остальные коды, которые не были рассмотрены ранее:
| инструкция | Флаг |
|---|---|
js | SF = 1 |
jns | SF = 0 |
jo | OF = 1 |
jno | OF = 0 |
jp , jpe (e = четный) | PF = 1 |
jnp , jpo (o = нечетный) | PF = 0 |
Еще один условный переход (дополнительный)
Один специальный x86 условный переход не проверяет флаг. Вместо этого он проверяет значение регистра cx или ecx (на основе текущего режима адреса процессора 16 или 32 бит), и скачок выполняется, когда регистр содержит ноль.
Эта инструкция была разработана для проверки регистра счетчика ( cx/ecx ) перед инструкциями, rep описанию, или перед циклами loop .
jcxz a_label ; jump if cx (16b mode) or ecx (32b mode) is zero
jecxz a_label ; synonym of jcxz (recommended in source code for 32b target)
| инструкция | Регистрация (не флаг) |
|---|---|
jcxz , jecxz | cx = 0 (режим 16b) |
jcxz , jecxz | ecx = 0 (режим 32b) |
1 Или что-то в этом роде.
Тестовые арифметические отношения
Неподписанные целые числа
Лучше чем
cmp eax, ebx
ja a_label
Больше или равно
cmp eax, ebx
jae a_label
Меньше, чем
cmp eax, ebx
jb a_label
Меньше или равно
cmp eax, ebx
jbe a_label
равных
cmp eax, ebx
je a_label
Не равный
cmp eax, ebx
jne a_label
Подписанные целые числа
Лучше чем
cmp eax, ebx
jg a_label
Больше или равно
cmp eax, ebx
jge a_label
Меньше, чем
cmp eax, ebx
jl a_label
Меньше или равно
cmp eax, ebx
jle a_label
равных
cmp eax, ebx
je a_label
Не равный
cmp eax, ebx
jne a_label
a_label
В приведенных выше примерах a_label является целевым назначением для CPU, когда проверенное состояние является «истинным». Когда проверенное состояние «ложно», CPU продолжит следующую команду после условного перехода.
Синонимы
Существуют синонимы инструкций, которые могут использоваться для улучшения читаемости кода.
Например, ja и jnbe (Jump не ниже и не равно) являются одной и той же инструкцией.
Подписанные неподписанные сопутствующие коды
| операция | неподписанный | подписанный |
|---|---|---|
| > | ja | jg |
| > = | jae | jge |
| < | jb | jl |
| <= | jbe | jle |
| знак равно | je | je |
| ≠,! =, <> | jne | jne |