请看一下这两段伪汇编代码:
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)?
答案 0 :(得分:4)
-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
答案 1 :(得分:2)
答案与两个补码表示法有关。 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
换句话说,两个补码中没有“负零”。零占用领域中的空间,否则被认为是“正号”,因为高位为零。