是否有根据状态寄存器状态清除 32 位寄存器的无分支方式?可以使用额外的清除寄存器和 来实现,但在 32 位模式下的x86CMOVcc上对我来说太贵了。可悲的是没有即时操作数的版本。从内存中读取也是不好的变体。CMOVcc
x86上有SETcc(虽然,操作数是 1 个字节)但没有 " CLEARcc" 指令。
是否有根据状态寄存器状态清除 32 位寄存器的无分支方式?可以使用额外的清除寄存器和 来实现,但在 32 位模式下的x86CMOVcc上对我来说太贵了。可悲的是没有即时操作数的版本。从内存中读取也是不好的变体。CMOVcc
x86上有SETcc(虽然,操作数是 1 个字节)但没有 " CLEARcc" 指令。
这可能会让你失望,但CMOVcc在这方面非常好。将它与具有ddZERO值的变量一起使用0并不是那么糟糕,尤其是在循环中。
CMOVcc rTarget, ddZERO
如果满足条件,则将rTarget寄存器重置为零。
否则(有其他情况)您可以反转场景并在不匹配条件下。哪种选择更好取决于发生的频率。ccCMOVcc
如果您有一个带有该值的寄存器,则0应该使用它。但是,如果您不能使用(缓存的)内存位置来节省寄存器,那也不是那么糟糕。此估计基于经验,并且 IIRC 在 L1 缓存内存位置中使用常量在循环中的延迟几乎可以忽略不计。
在大多数 ISA 中基本上有一种通用方法提供分支设置或清除寄存器:从进位标志生成全零或全sbb reg,reg一掩码:当进位为零时清除掩码,并在设置进位时设置掩码。随后 and dst, reg将清除目标寄存器,或保持不变。
可以通过切换掩码或反转进位标志来反转条件。零测试可以通过从被测寄存器中减一或从零中减去被测寄存器来实现。第一组进位当且仅当寄存器为零;第二种形式设置进位 iff 寄存器非零。