请查看以下代码:
/:lang/
-32 = 0010 1111 1111
>> 2之后:0000 1011 1111 = -26
但是正确的答案应该是换班后为-8,这是怎么发生的?
答案 0 :(得分:2)
0010 1111 1111
这似乎是一个12位数字。 MIPS CPU使用32位数字。
因此,无论程序执行哪种操作:0010 1111 1111
位都无法描述寄存器的全部内容!
-32 = 0010 1111 1111
0000 1011 1111 = -26
我尝试了不同的通用方式来存储和写入二进制数字,包括BCD!
我不知道0010 1111 1111
和0000 1011 1111
应该如何代表数字-32和-26!
就像十进制数字一样,二进制数字通常从右到左书写:
最右边的数字的值为2 ^ 0(1),左边的数字为2 ^ 1(2),左边的数字为2 ^ 2(4),依此类推。
这意味着000 ... 000 1011 1111
是128 + 32 + 16 + 8 + 4 + 2 + 1 = 191。
我还看到人们用另一种方式写数字(因此他们将191写为11111101
)。但是,这些人必须记住,单词“ left”和“ right”(sra
= shift right 算术)具有相反的含义!
-32 = ...
有多种方法将负数存储在CPU寄存器中:
几乎所有现代二进制计算机和CPU都使用二进制补码。对于MIPS CPU也是如此。
因为您写的是“ -32 = 0010 1111 1111”,所以我认为您不了解二进制补码的工作原理:
在二进制补码系统中,左位是数字的符号。如果左位为1,则数字为负。如果左位为零,则数字为正或零。
(请注意,对于我上面提到的所有存储负数的方法,这都不是 true 。)
通过反转二进制补码x
的所有位,我们得到数字-(x+1)
。这意味着:
31 = 32-1 = 00...0011111
-32 = -(31+1) = 11...1100000
>> 2之后...
...我们得到111111...111000
的结果:
除去右边的两位,并在左边添加两个“新”位。由于这是一种算术移位,因此可以通过“复制”原始数字的左位来完成:
左边的位是“ 1”,因此在左边增加了两个“ 1”位。
但是正确的答案应该是换班后为-8,这是怎么发生的?
“ 111111 ... 111000”的左位为1。所以这是一个负数。
现在,我们再次应用“反转所有位”规则; x
是寄存器中的值:
x = 111...111000
-(x+1) = 000...000111 = 7
-(x+1) = 7
这意味着:x = (-8)