MIPS 中的整数绝对值?

发布于 2024-08-22 16:14:38 字数 37 浏览 5 评论 0原文

有没有简单的方法可以将 MIPS 中寄存器中的值设为绝对值?

Do you have any simple ways to make a value in a register in MIPS as an absolute value?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我恋#小黄人 2024-08-29 16:14:38

这是一个无分支的变体:

# input and output in $t0
sra $t1,$t0,31   
xor $t0,$t0,$t1   
sub $t0,$t0,$t1    

它是如何工作的?
首先,$t1 填充有$t0 的符号位。因此,如果 $t0 为正,$t1 将设置为 0,如果 $t0 为负 $t1将被设置为 0xFFFFFFFF。

接下来,如果 $t1 为 0xFFFFFFFF,则将 $t0 的每一位取反;如果 $t1 为 0,则保持不变。反转数字的所有位与将其设置为 (-number)-1 (二进制补码)相同。

最后,从中间结果中减去 0xFFFFFFFF(等于 -1)或 0。

因此,如果 $t0 最初为负数,您将得到:
$t0 = ($t0 ^ 0xFFFFFFFF) - 0xFFFFFFFF == (-$t0 - 1) - -1 == (-$t0 - 1) + 1 == -$t0
如果最初是积极的,您将得到:
$t0 = ($t0 ^ 0) - 0 == $t0

Here's a branch-less variant:

# input and output in $t0
sra $t1,$t0,31   
xor $t0,$t0,$t1   
sub $t0,$t0,$t1    

How does this work?
First, $t1 is filled with the sign-bit of $t0. So if $t0 is positive $t1 will be set to 0, and if $t0 is negative $t1 will be set to 0xFFFFFFFF.

Next, each bit of $t0 is inverted if $t1 is 0xFFFFFFFF, or left unchanged if $t1 is 0. It just so happens that inverting all bits of a number is the same as setting it to (-number)-1 (in two's complement).

Finally, either 0xFFFFFFFF (which equals -1) or 0 is subtracted from the intermediate result.

So if $t0 originally was negative you'll get:
$t0 = ($t0 ^ 0xFFFFFFFF) - 0xFFFFFFFF == (-$t0 - 1) - -1 == (-$t0 - 1) + 1 == -$t0.
And if it originally was positive you'll get:
$t0 = ($t0 ^ 0) - 0 == $t0.

肥爪爪 2024-08-29 16:14:38

这是一个非常简单的方法。

#assume you want the absolute value of r1
        ori $2, $zero, $1      #copy r1 into r2
        slt $3, $1, $zero      #is value < 0 ?
        beq $3, $zero, foobar  #if r1 is positive, skip next inst
        sub $2, $zero, $1      #r2 = 0 - r1
foobar:
#r2 now contains the absolute value of r1

Here is a pretty simple way to do it.

#assume you want the absolute value of r1
        ori $2, $zero, $1      #copy r1 into r2
        slt $3, $1, $zero      #is value < 0 ?
        beq $3, $zero, foobar  #if r1 is positive, skip next inst
        sub $2, $zero, $1      #r2 = 0 - r1
foobar:
#r2 now contains the absolute value of r1
守不住的情 2024-08-29 16:14:38

最简单的方法。
有一个伪指令可以执行此操作:

abs $t1, $t1

将获取寄存器 $t1 中的值的绝对值并将其放入 $t1

Simplest way of all.
There is a pseudo instruction that does this:

abs $t1, $t1

will take the absolute value of the value in register $t1 and place it in $t1

烙印 2024-08-29 16:14:38

这是它的尺寸优化版本。由于分支预测问题,它比 sra/xor/subu 答案慢,但它比 sra/xor/subu 答案更小,但它更小:

    bgtz $t0, label
label:
    subu $t0, $zero, $t0

这是由于 MIPS 延迟槽而起作用:如果 $t0 为正,则 subu否定 $t0 指令执行两次。您可能需要在汇编器中启用.set noreorder

Here's a size-optimized version of it. It's slower than the sra/xor/subu answer, due to branch prediction issues, but it's one instruction smaller:

    bgtz $t0, label
label:
    subu $t0, $zero, $t0

This works because of the MIPS delay slot: if $t0 is positive, the subu instruction to negate $t0 executes twice. You may need to enable .set noreorder in your assembler.

咽泪装欢 2024-08-29 16:14:38

最简单的方法就是对这些值进行一些二进制数学运算。

http://en.wikipedia.org/wiki/Signed_number_representations 描述了各种系统如何存储其否定数字。我相信 MIPS 使用二进制补码方案来存储带符号的数字。这使得它比位标志有点困难,可以通过将数字与 0b01111111 进行“与”操作来关闭位标志,但它仍然是可行的。

The easiest way would just to do a bit of binary math on the values.

http://en.wikipedia.org/wiki/Signed_number_representations describes how various systems store their negative numbers. I believe MIPS uses a two's complement scheme to store signed numbers. This makes it a bit harder than a bit flag, which could just be turned off by ANDing the number with 0b01111111, but it is still doable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文