Одна инструкция для очистки PF (Parity Flag) - получить нечетное количество бит в регистре результатов
В сборке x86 возможно ли сбросить флаг четности в одной и только одной инструкции, работающей в любой начальной конфигурации регистра?
Это эквивалентно созданию регистра результата с нечетным числом битов с любой операцией, которая устанавливает флаги (явно исключая mov
).
Для контраста, установка флага четности может быть выполнена в одной инструкции:
cmp bl, bl
И есть много способов очистить флаг четности с помощью двух инструкций:
and bl, 0
or bl, 1
Тем не менее, метод одной инструкции остается неуловимым.
4 ответа
Невозможно.
Ни одна из команд, изменяющих PF, не может безусловно привести к результату нечетной четности при применении к двум копиям или регистру (как или al, al). Аналогично, ни одна из арифметических команд не выдает результат нечетной четности при применении к регистру и константу, которая полностью определяет результат (как и al, 0 или или al, ffh). Что касается команд, где вторым операндом является любая другая константа, результат будет зависеть от начального значения регистра, и мы не можем это контролировать.
Если бы мы знали некоторые детали среды выполнения, можно было бы использовать содержимое памяти по известному адресу. На ПК, совместимом в реальном режиме, вы можете положиться на структуры данных BIOS. В MS-DOS то же самое для исполняемого заголовка.
Попробуй это:
foo: cmp byte [foo],0x7F
Примечание: это cmp
Первый байт инструкции - 0x80, а 0x80-0x7F = 0x01.
Если мы сможем выйти за пределы самого 8086 и перейти в современную эпоху, более поздние наборы инструкций x86 действительно содержат ряд инструкций, которые безоговорочно очищают флаг четности, хотя не всегда ясно, почему они должны это делать. Но поиск в руководствах Intel для
PF
и поиск таких строк, как «очищено», «установлено на 0» и т. д., приводит к нескольким:
Так
ptest xmm0, xmm0
а также
popcnt eax, eax
пожалуй, самые доступные.
ptest
имеет то преимущество, что он не изменяет никаких регистров, кроме
FLAGS
.
Вfcomi
семья близка, так как они очищают PF, когда результат сравнения является любым из
< > =
, но они устанавливают его, если результат «неупорядоченный», что может произойти, если регистры x87 содержат NaN.
(Это показывает, что очистка флага четности не эквивалентна получению нечетного числа битов в 8-битном регистре, поскольку существуют инструкции, которые очищают его при других условиях.)
Я думаю, что объединяет эти инструкции то, что они устанавливают определенные флаги (CF, ZF) особым образом, отличным от обычного «по результату». У них нет особой необходимости что-либо делать с другими, но указание, что они остаются неизменными, введет входную зависимость от этих флагов для процессоров, которые не переименовывают их отдельно. Это проблема для эффективного внеочередного выполнения.
Некоторые инструкции решают эту проблему, указывая, что другие флаги «не определены», но по какой-то причине разработчики этих инструкций решили вместо этого обнулить их.
Я думаю, что единственный способ сделать это, кроме mov
(Я чувствую запах интервью), чтобы найти (чудесным образом, по общему признанию) регистр или пару регистров, которая удовлетворит TEST src, dst
, Смотрите здесь, Операция.
На данный момент на ум не приходит такая пара регистр / регистр x86, которая могла бы удовлетворить это условие.