Был бы x86 по-прежнему полностью программируемым, если бы у него не было Sign Flag (SF)?

Флаг знака указывает на то, что результаты операции отрицательны.
Теперь, когда результат операции отрицателен, как я понимаю, установлен флаг знака. Но зачем это нужно. Потому что, если операция возвращает отрицательный результат, мы можем проверить это в целевом регистре, является ли значение отрицательным или положительным. Можно ли удалить этот регистр флага знака из ЦП и выполнить всю работу


person rohit sharma    schedule 30.04.2021    source источник


Ответы (3)


Вам даже не нужны никакие флаги, потому что в x86 MOV уже завершен по Тьюрингу, и существует компилятор, который может скомпилировать код C в исполняемый файл только с MOV (или только с одним из XOR, SUB, ADD, XADD, ADC, SBB, AND/OR, PUSH/POP, 1-битные сдвиги или CMPXCHG/XCHG)

Если у вас есть побитовые операции, то знаковый бит можно легко получить с помощью AND или сдвига вправо

person phuclv    schedule 30.04.2021
comment
Тьюринг завершен, да, но я думаю, что для большинства из них требуется много инструкций для наиболее распространенных операций, больше не сопоставляя большинство операций C с одним небольшим блоком инструкций, верно? Как разбить более широкие целые числа на несколько битов? Так что да, но мы можем сделать намного лучше, см. мой ответ. - person Peter Cordes; 30.04.2021
comment
@PeterCordes да, очевидно, это медленно. Но вопрос ОП в том, выполнимо ли это, а не в производительности. Is it possible to remove this sign flag register from the CPU and get all work done ответ да, а скорость зависит от того, сколько осталось инструкций и регистров - person phuclv; 30.04.2021
comment
Верно, но я подумал, что было бы интересно показать, что потеря научной фантастики не будет слишком больной и не потребует возврата к этим методам. Согласен, также интересно указать, как далеко вы можете зайти в удалении вещей и при этом оставаться полным по Тьюрингу (за исключением конечного хранилища). - person Peter Cordes; 30.04.2021

Да, x86 по-прежнему будет полным по Тьюрингу без SF и даже достаточно эффективно программируемым. Сравнение целых чисел со знаком (кроме ==/!=) будет медленнее, но все же выполнимо. Таким образом, x86-без-SF по-прежнему намного эффективнее, чем хаки с вычислением одной инструкции, такие как использование только MOV (с большим количеством таблиц поиска и режимов адресации). Вы по-прежнему можете выполнять обычные операции сложения/вычитания/умножения с обычными инструкциями и просто эмулировать условия сравнения со знаком, включающие SF.

Например, вы можете эмулировать cmp eax, ecx/jl, используя два временных регистра. jl переходит, если SF != OF. (Возможно, есть более простые способы сделать эту эмуляцию, но это наиболее прямо демонстрирует, что вы можете получить MSB результата во флаг, отличный от SF, и, таким образом, можете эмулировать его в других случаях.)

; inputs: EAX and ECX
; clobbers: EDX and EAX
;;; jumps if EAX < ECX,  like cmp eax,ecx / jl

    mov  edx, eax
    sub  edx, ecx        ; sets OF, and would set SF it it existed
    bt   edx, 31         ; CF = MSB, other flags unmodified.
 ;; jump if CF != OF    , like jl = SF!=OF in normal x86
    pushf
    pop  eax
    and  eax, 0x0801     ; isolate CF and OF
    or   al, ah          ; combine both into the low byte, setting FLAGS
    jpo  eax_lower       ; jump if parity odd: CF != OF means only one bit is set

(битовые позиции EFLAGS)

Обратите внимание, что PF, флаг четности, устанавливается только в соответствии с младшим байтом результата; только после И он может сказать вам только о CF, бит 0 EFLAGS. Это неудачное дизайнерское решение, что OF находится за пределами младшего байта FLAGS, иначе lahf мог бы заменить pushf/pop reg.

Это просто первая идея, которая пришла мне в голову, я уверен, что это можно было бы сделать более эффективно. (Но большая часть кода будет отдавать предпочтение числам без знака, поэтому сравнения могут быть полностью эффективными.)

Если вам нужно было избежать 386 BT для установки только CF, не испортив другие биты, вы, конечно, могли бы просто shr dx, 15, чтобы опустить MSB вниз, или rol dx, 1. (Но это пишет FLAGS, поэтому вы должны сделать это после pushf/pop reg, и, возможно, вы выберете свой сдвиг или количество циклов, чтобы выровнять его с OF.)


Я думаю, что некоторые 8-битные ISA не имели подписанных условий сравнения, и людям все же удавалось что-то с ними сделать. :П

person Peter Cordes    schedule 30.04.2021

Да, именно так работает MIPS. MIPS не имеет ни флагов, ни флага знака, ни флага переполнения, ни флага нуля и т. д. В нем есть инструкции, которые проверяют регистр на наличие нуля/не нуля, ‹= или › 0.

person Erik Eidt    schedule 30.04.2021
comment
Конечно, но x86 не имеет инструкций по сравнению и переходу для подписанных условий, поэтому на самом деле это не относится к чистому x86 с отключенным/удаленным SF. (Во-первых, не ISA, предназначенная для эффективной работы без SF.) Но если ОП не знал об этом, то да, конечно, стоит упомянуть. - person Peter Cordes; 30.04.2021