absolute value in MIPS

2019-04-22 00:20发布

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

标签: assembly mips
5条回答
Explosion°爆炸
2楼-- · 2019-04-22 00:44

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

查看更多
来,给爷笑一个
3楼-- · 2019-04-22 00:44

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.

查看更多
Fickle 薄情
4楼-- · 2019-04-22 00:51

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.

查看更多
孤傲高冷的网名
5楼-- · 2019-04-22 00:55

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.

查看更多
何必那么认真
6楼-- · 2019-04-22 00:58

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
查看更多
登录 后发表回答