Сборка x86: сравнения (синтаксис GAS)

Я считаю, что стандартный способ реализации переходов в x86 - это сравнение с чем-то вроде:

cmpl %ebx, %eax

Который сохраняет результат в регистре eflags, а затем следующая команда перехода использует этот регистр eflags:

je some_label

Но что, если я хочу сохранить результат сравнения, чтобы выполнить прыжок позже? Я думал сделать что-то вроде:

    cmpl %eax, %ebx
    je storetrue
storefalse:
    pushl $0
    jmp done
storetrue:
    pushl $1
done:
    ...

Нужно ли мне делать это так или есть более прямой способ, который не требует дополнительных прыжков?


person AlexJ136    schedule 08.08.2013    source источник
comment
Используйте инструкции условного перемещения.   -  person Brett Hale    schedule 08.08.2013
comment
Это полезно, но не объясняет, как именно получить результат сравнения при создании копии (парной части) регистра флагов.   -  person AlexJ136    schedule 08.08.2013
comment
Условный ход - это именно то, что я искал, спасибо.   -  person AlexJ136    schedule 08.08.2013
comment
Также есть SETcc.   -  person Michael    schedule 08.08.2013


Ответы (1)


На ум приходят несколько методов.

  1. Как уже упоминалось в комментариях к вопросу, вы можете использовать инструкцию условного перемещения.
  2. Вы можете использовать инструкцию SETxx, чтобы установить один из 8-битных регистров в 0 или 1.
  3. Вы можете использовать инструкцию PUSHF для сохранения копии регистра EFLAGS в стеке. Его можно восстановить с помощью инструкции POPF.
  4. Вы можете создать свой код так, чтобы он не использовал инструкции, изменяющие регистр EFLAGS, когда вы в следующий раз захотите использовать результаты этого сравнения.
  5. В зависимости от ваших вариантов использования вы можете создать простое арифметическое выражение, результатом которого будет либо 0, либо 1, либо какое-то другое желаемое значение (лично я предпочитаю комбинацию 0 или -1, так как затем становится тривиальным преобразовать это в любое значение). пары X или Y с использованием И, за которым следует ДОБАВИТЬ).

Надеюсь это поможет.

person Sparky    schedule 08.08.2013
comment
Итак, если бы я использовал сравнение, затем pushf, сделал что-то, что меняет cflags, а затем popf, затем jump, я фактически делаю тот же прыжок, который сделал бы, если бы прыгнул сразу после первоначального сравнения? - person AlexJ136; 08.08.2013
comment
@ AlexJ136 AlexJ136 - Пока данные, которые вы извлекаете из стека с помощью POPF, совпадают с теми, которые вы помещали в стек с помощью PUSHF, тогда да. - person Sparky; 08.08.2013