Поиск…


Безусловные прыжки

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 (например, CFC , PFP ).

Остальные коды, которые не были рассмотрены ранее:

инструкция Флаг
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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow