sra (сдвиг вправо) vs srl (сдвиг вправо) - PullRequest
4 голосов
/ 07 июня 2011

Пожалуйста, посмотрите на эти две части псевдо-ассемблерного кода:

1)

li $t0,53

sll $t1,$t0,2
srl $t2,$t0,2
sra $t3,$t0,2

print $t1  
print $t2  
print $t3  

2)

li $t0,-53


sll $t1,$t0,2
srl $t2,$t0,2
sra $t3,$t0,2

print $t1
print $t2
print $t3

в первом случае вывод:
212
13
13

в последнем есть:
-212
107374 ...
-14
Но не следует: sra (-53) = - (srl 53)?

Ответы [ 2 ]

4 голосов
/ 07 июня 2011
-53 = 1111111111001011

           sra 2

      1111111111110010(11) = -14
       ^^              ^^
      sign           dropped
    extension

Поскольку дополнительные биты просто удаляются как для положительных, так и для отрицательных результатов, результат всегда округляется в меньшую сторону, если вы рассматриваете сдвиг как деление.

 53 sra 2 = floor( 53 / 2^2) = floor( 13.25) =  13
-53 sra 2 = floor(-53 / 2^2) = floor(-13.25) = -14
2 голосов
/ 07 июня 2011

Ответ относится к двоичной записи дополнения.Цель sra - поддержать отрицательные числа, представленные в дополнении к двум.Самый старший бит, равный единице, если значение отрицательное, дублируется при смещении вправо «арифметическим» образом.

На 32-разрядном x86 это означает, что:

 53 = 00000000000000000000000000110101
-53 = 11111111111111111111111111001011

 srl( 53, 2) =  13 = 00000000000000000000000000001101
               -13 = 11111111111111111111111111110011

 sra(-53, 2) = -14 = 11111111111111111111111111110010

Полагаю, нужно понимать, что в дополнении к двум отрицательное число - это не инверсия каждого бита числа - это инверсия каждого бита, а затем добавление 1 к этому числу.Рассмотрим:

 1 = 0000001
-1 = 1111111

Не:

-1 = 1111110

Что привело бы к:

 0 = -1 + 1 = 11111111

Другими словами, в дополнении к двум нет отрицательного нуля,Ноль занимает место в области, иначе считается «положительным знаком», поскольку старший бит равен нулю.

...