是否有无分支的方法来清除32位寄存器取决于状态寄存器状态?它可以使用额外的清除寄存器和CMOVcc来实现,但对我来说,在32位模式下的 x86 上太贵了。遗憾的是CMOVcc没有立即操作数的版本。从记忆中阅读也是不好的变体。
CMOVcc
SETcc
CLEARcc
pxyaymoc1#
这可能会让你失望,但CMOVcc在这方面非常好。将它与值为0的变量ddZERO一起使用并没有那么糟糕,特别是在循环中。
0
ddZERO
CMOVcc rTarget, ddZERO
如果满足cc条件,则将rTarget寄存器复位为零。否则(有一个否则),你可以颠倒的情况和CMOVcc在不匹配的条件。哪种选择更好取决于发生的频率。如果你有一个值为0的寄存器,你应该使用它。但是如果你不能腾出一个寄存器,使用(缓存的)内存位置也不是那么糟糕。该估计基于经验,并且IIRC在L1高速缓存的存储器位置中使用常数在循环中具有实际上可忽略的延迟。
cc
rTarget
rxztt3cl2#
在大多数ISA中,基本上有一个通用方法提供分支设置或清除寄存器:从进位标志生成全零或全一掩码:sbb reg,reg在进位为零时清除掩码,并在进位置位时置位掩码。如果后面跟着and dst, reg,则会清除目标寄存器,或者保持不变。可以通过切换掩码或反转进位标志来反转条件。零测试可以通过从被测寄存器中减去1或从零中减去被测寄存器来实现。第一组进位iff寄存器为零;第二形式集合进位iff寄存器为非零。
sbb reg,reg
and dst, reg
2条答案
按热度按时间pxyaymoc1#
这可能会让你失望,但
CMOVcc
在这方面非常好。将它与值为0
的变量ddZERO
一起使用并没有那么糟糕,特别是在循环中。如果满足
cc
条件,则将rTarget
寄存器复位为零。否则(有一个否则),你可以颠倒的情况和
CMOVcc
在不匹配的条件。哪种选择更好取决于发生的频率。如果你有一个值为
0
的寄存器,你应该使用它。但是如果你不能腾出一个寄存器,使用(缓存的)内存位置也不是那么糟糕。该估计基于经验,并且IIRC在L1高速缓存的存储器位置中使用常数在循环中具有实际上可忽略的延迟。rxztt3cl2#
在大多数ISA中,基本上有一个通用方法提供分支设置或清除寄存器:从进位标志生成全零或全一掩码:
sbb reg,reg
在进位为零时清除掩码,并在进位置位时置位掩码。如果后面跟着and dst, reg
,则会清除目标寄存器,或者保持不变。可以通过切换掩码或反转进位标志来反转条件。零测试可以通过从被测寄存器中减去1或从零中减去被测寄存器来实现。第一组进位iff寄存器为零;第二形式集合进位iff寄存器为非零。