【发布时间】:2019-05-03 06:04:12
【问题描述】:
我正在考虑如何否定 mips32 中的有符号整数。我的直觉是使用 2 的补码的定义,例如:(假设 $s0 是要否定的数字)
nor $t0, $s0, $s0 ; 1's complement
addiu $t0, $t0, 1 ; 2's = 1's + 1
然后我意识到可以这样做:
sub $t0, $zero, $s0
所以...有什么区别?哪个更快? IIRC sub 将尝试检测溢出,但这会使速度变慢吗?最后,有没有其他方法可以做到这一点?
【问题讨论】:
-
sub变体更清晰;大家都知道0 - X == -X,但不是每个人都知道~X+1 == -X(也不是每个人都熟悉NOR运算)。它也尽可能快,因为它是一条指令。nor/addiu变体存在数据风险,其中addiu取决于nor指令的结果。在实践中,这可能会被处理而不会导致任何管道停顿,但这取决于您正在运行的特定 MIPS 实现。 -
sub 实际上做同样的事情,但在单个 ALU 操作中
-
@Michael:我也觉得
sub更好,而且出现在我读的书中。但我只是好奇/怀疑底层正在做与我的第一个版本相同的事情...... -
@Minn:酷,你马上回答我的第二条评论。
-
这两种变体并不等价。
sub将导致算术溢出异常(即尝试计算-INT_MIN时)。如果你使用subu(或addi而不是addiu),它会是等价的。
标签: assembly mips cpu-architecture micro-optimization mips32