无分支方式有条件地清除寄存器

问题描述 投票:0回答:2

是否有根据状态寄存器状态无分支方式清除32位寄存器?它可以使用额外的清除寄存器和

CMOVcc
来实现,但对于我来说,在 32 位模式下的 x86 上太昂贵了。遗憾的是
CMOVcc
没有带有立即操作数的版本。从记忆中读取也是不好的变体。

x86
上有
SETcc
(尽管操作数是 1 个字节)但没有“CLEARcc”指令。

assembly x86 flags status-register branchless
2个回答
4
投票

这可能会让你失望,但是

CMOVcc
在这方面非常好。将其与变量
ddZERO
和值
0
一起使用并不是那么糟糕,尤其是在循环中。

CMOVcc rTarget, ddZERO
如果满足

rTarget

 条件,
cc
寄存器重置为零。
否则(有一个“否则”),您可以反转场景并在不匹配条件下
CMOVcc
。哪种选择更好取决于发生的频率。

如果您有一个值为

0
的寄存器,您应该使用它。但是,如果您无法使用(缓存的)内存位置来腾出寄存器,也没有那么糟糕。此估计基于经验,并且 IIRC 在 L1 缓存内存位置中使用常量在循环中的延迟几乎可以忽略不计。


3
投票

在大多数提供分支设置或清除寄存器的 ISA 中,本质上有一种通用方法:从进位标志生成全零或全一掩码:

sbb reg,reg
当进位为零时清除掩码,并在设置进位时设置掩码。随后按
and dst, reg
将清除目标寄存器,或保持不变。

可以通过切换掩码或反转进位标志来反转条件。零测试可以通过从被测寄存器减一或从零减去被测寄存器来实现。第一组进位 iff 寄存器为零;第二种形式设置进位 iff 寄存器非零。

© www.soinside.com 2019 - 2024. All rights reserved.