Написание сборки AT&T для работы с флагом четности и смещениями

У меня есть определенный набор инструкций для x64, которые в конечном итоге либо устанавливают флаг четности, либо сбрасывают его. Я хотел бы написать некоторую сборку, которая пропускает инструкцию установленного флага четности. Из того, что я прочитал в онлайн-руководствах, jpe — это инструкция, которая выполняет переход, если установлен флаг четности, а jpo — это инструкция, которая выполняет переход, если флаг четности не установлен.

Я требую, чтобы выполнение прыгало вперед на 3 байта, если установлен бит четности. Изначально я пробовал следующее, но оно просто прыгает по адресу 0x3, а не по смещению из RIP.

jpe 0x3

Я понял, что если бы я использовал синтаксис Intel, я мог бы сделать следующее.

jpe $+0x3

Однако это не работает для AT&T, и я получаю следующее сообщение об ошибке.

test.c: Assembler messages:
test.c:46: Error: operand type mismatch for `jpe'

Как я могу это исправить?


person Community    schedule 08.10.2015    source источник
comment
Почему бы не использовать ярлык? В любом случае jpe .+3 должно работать.   -  person Jester    schedule 08.10.2015
comment
@Jester: Просто примечание: jpe .+3 производит 7A 01 = jpe short 0x01. Вы должны добавить количество байтов, потребляемых jpe (=2).   -  person rkhb    schedule 08.10.2015
comment
@rkhb Я знаю, что он производит, было неясно, чего хотел ОП. Поскольку $+0x3 тоже производит это (в ассемблере, который использует $, такой как nasm), в любом случае, я надеюсь, что он сможет разобраться с этим сам :)   -  person Jester    schedule 08.10.2015
comment
Имена jp / jnp для одних и тех же инструкций могут сделать ваш код более понятным, если ваше условие четности на самом деле не отражает четность/нечетность чего-либо. (например, если флаг установлен SAHF).   -  person Peter Cordes    schedule 09.10.2015


Ответы (1)


GAS всегда хочет контролировать переходы, см. официальную документацию.

Как упомянул Jester, вы можете использовать .+3 как своего рода метку, где точка обозначает адрес фактической строки (например, «$» в других ассемблере). GAS рассчитает относительное расстояние и соответствующий прыжок. Есть одно предостережение: хотя точка — это адрес фактической строки, относительный переход вычисляется по адресу следующей инструкции. Итак, jpe .+3 производит 7A 01 = jpe short 1.

Другой вариант — использовать ярлык. Я предлагаю локальную метку, которую можно даже переопределить:

mov $0b110, %eax        # Parity = even
test %eax, %eax         # Set PF
jpe 0f                  # Jump forward to the next "0:"
.byte 0,0,0
0:                      # Local label
person rkhb    schedule 08.10.2015