Assembly 如果x86没有';没有标志旗(SF)?

Assembly 如果x86没有';没有标志旗(SF)?,assembly,x86,cpu-architecture,masm,turing-complete,Assembly,X86,Cpu Architecture,Masm,Turing Complete,符号标志表示操作结果为负数。 现在,当一个运算结果为负时,据我所知,符号 标志已设置。但为什么它是必需的。因为如果操作返回负数 结果我们可以检查目标寄存器中的值是负值还是正值。是否可以从CPU中删除此符号标志寄存器并完成所有工作您甚至不需要任何标志,因为在x86中,有一个(或只有一个XOR、SUB、ADD、XADD、ADC、SBB和/或、PUSH/POP、1位移位或CMPXCHG/XCHG) 如果您有按位操作,那么可以使用和或右移位轻松获得符号位。是的,事实上,这就是MIPS的工作方式。MIPS

符号标志表示操作结果为负数。
现在,当一个运算结果为负时,据我所知,符号 标志已设置。但为什么它是必需的。因为如果操作返回负数
结果我们可以检查目标寄存器中的值是负值还是正值。是否可以从CPU中删除此符号标志寄存器并完成所有工作

您甚至不需要任何标志,因为在x86中,有一个(或只有一个XOR、SUB、ADD、XADD、ADC、SBB和/或、PUSH/POP、1位移位或CMPXCHG/XCHG)


如果您有按位操作,那么可以使用
或右移位轻松获得符号位。是的,事实上,这就是MIPS的工作方式。MIPS没有标志、无标志标志、无溢出标志、无零标志等。它有测试寄存器零/非零、0的指令。

是,如果没有SF,x86仍然是图灵完整的,甚至可以相当高效地编程。有符号整数比较(除了
==
/
!=
)会更慢,但仍然可行。因此,没有SF的x86仍然比仅使用MOV(具有大量查找表和寻址模式)这样的单指令计算黑客更高效您仍然可以使用普通指令执行普通的加法/减法/乘法,只需模拟涉及SF的有符号比较条件。

例如,您可以使用两个临时寄存器模拟
cmp-eax、ecx/jl
。(可能有更简单的方法来进行模拟,但这最直接地表明,您可以将结果的MSB放入SF以外的标志中,从而可以在其他情况下对其进行模拟。)

;输入:EAX和ECX
; 冲击:EDX和EAX
;;; 如果EAX
()

请注意,PF(奇偶校验标志)仅根据结果的低位字节设置;在和之后,它只能告诉你关于CF,EFLAGS的0位。这是一个不幸的设计决定,OF超出了标志的低字节,否则lahf可能会取代pushf/pop reg

这只是我想到的第一个想法,我相信它可以做得更有效。(但很多代码都倾向于使用无符号数字,因此比较是完全有效的。)

如果您必须避免386 BT,只设置CF而不弄乱其他位,那么您当然可以只
shr dx,15
将MSB降到底部,或者
rol dx,1
。(但这会写入标志,所以您可以在pushf/pop reg之后执行此操作,也许您可以选择shift或rotate count将其与OF对齐。)



我认为一些8位ISA没有签署比较条件,人们仍然设法在其上完成了一些工作P

当然可以,但是x86没有用于签名条件的比较和分支指令,因此这并不能真正解决禁用/删除SF的纯x86。(这不是一个没有SF就可以高效运行的ISA。)但如果OP不知道这一点,那么是的,当然,值得一提。图灵完成,是的,但我认为大多数操作都需要很多指令来执行最常见的操作,不再将大多数C操作映射到一小段指令中,对吗?比如把更宽的整数分解成多个位?所以是的,但我们可以做得更好,看我的答案。@PeterCordes是的,很明显它很慢。但OP的问题是它是否可行,而不是性能
是否有可能从CPU中删除这个符号标志寄存器并完成所有工作
答案是肯定的,速度取决于有多少指令和寄存器保留,但我认为有趣的是,显示丢失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