абсолютное значение в MIPS - PullRequest
9 голосов
/ 22 февраля 2010

У вас есть какие-нибудь простые способы сделать значение в регистре в MIPS абсолютным значением?

Ответы [ 5 ]

18 голосов
/ 17 апреля 2013

Вот вариант без ветки:

# 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.

Затем, каждый бит $t0 инвертируется, если $t1 равен 0xFFFFFFFF, или остается неизменным, если $t1 равен 0. Просто так получается, что инвертирование всех битов числа совпадает с установкой его на (-number)-1 (в два дополнения).

Наконец, либо 0xFFFFFFFF (что равно -1), либо 0 вычитается из промежуточного результата.

Так что, если $t0 изначально был отрицательным, вы получите:
$t0 = ($t0 ^ 0xFFFFFFFF) - 0xFFFFFFFF == (-$t0 - 1) - -1 == (-$t0 - 1) + 1 == -$t0.
И если он изначально был положительным, вы получите:
$t0 = ($t0 ^ 0) - 0 == $t0.

13 голосов
/ 22 февраля 2010

Вот довольно простой способ сделать это.

#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
9 голосов
/ 27 октября 2013

Самый простой способ из всех.Существует псевдоинструкция, которая делает это:

abs $t1, $t1

примет абсолютное значение значения в регистре $ t1 и поместит его в $ t1

1 голос
/ 08 августа 2015

Вот оптимизированная по размеру версия. Он медленнее, чем ответ sra / xor / subu, из-за проблем с предсказанием ветвлений, но на одну инструкцию меньше:

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

Это работает из-за интервала задержки MIPS: если $t0 положительно, инструкция subu для отмены $t0 выполняется дважды. Возможно, вам понадобится включить .set noreorder в вашем ассемблере.

1 голос
/ 22 февраля 2010

Самый простой способ - просто сделать небольшую двоичную математическую обработку значений.

http://en.wikipedia.org/wiki/Signed_number_representations описывает, как различные системы хранят свои отрицательные числа.Я считаю, что MIPS использует схему two'splement для хранения подписанных номеров.Это делает его немного сложнее, чем битовый флаг, который можно просто отключить с помощью ANDing числа с 0b01111111, но это все еще выполнимо.

...