右移算术
Shift right arithmetic
请看下面的代码:
addi $t1,$zero,-32
sra $t0,$t1,2
-32 = 0010 1111 1111
在 >> 2 之后:0000 1011 1111 = -26
但是移位后正确答案应该是-8,这是怎么回事??
0010 1111 1111
这好像是一个12位的数字。 MIPS CPUs 使用 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
=shiftright算术)这两个词是反义的!
-32 = ...
负数存储在CPU寄存器中有不同的方法:
- 符号和正数
(通常用于 floating-point)
- 补码
(用于 IPv4、TCP 和 UDP 中的校验和计算)
- 带偏移量的整数
(常用于fixed-point算术)
- (伪)对称数系
(三进制计算设备的首选方式,但通常不用于二进制计算机)
- 补码
几乎所有现代二进制计算机和 CPU 都使用 补码 。对于 MIPS CPUs.
也是如此
因为你写了“-32 = 0010 1111 1111”,所以我假设你不明白补码的工作原理:
在二进制补码系统中,左边的位是数字的符号。如果左边的位是 1,则数字是负数。如果左位为零,则数字为正数或零。
(请注意,对于我上面提到的所有存储负数的方法,这 不是 正确。)
通过反转二进制补码数 x
的所有位,我们得到数字 -(x+1)
。这意味着:
31 = 32-1 = 00...0011111
-32 = -(31+1) = 11...1100000
after >> 2 ...
...我们得到的结果是 111111...111000
:
删除了右边的两位,在左边添加了两位"new"。因为这是一个算术移位,所以这是通过 "copying" 原数的左边位来完成的:
左边的位是“1”,所以在左边加了两个“1”位。
But the correct answer should be -8 after shifting, how does that happen??
“111111...111000”的左边位是 1。所以这是一个负数。
现在我们再次应用"invert all bits"规则; x
是寄存器中的值:
x = 111...111000
-(x+1) = 000...000111 = 7
-(x+1) = 7
这意味着:x = (-8)
请看下面的代码:
addi $t1,$zero,-32
sra $t0,$t1,2
-32 = 0010 1111 1111
在 >> 2 之后:0000 1011 1111 = -26
但是移位后正确答案应该是-8,这是怎么回事??
0010 1111 1111
这好像是一个12位的数字。 MIPS CPUs 使用 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
=shiftright算术)这两个词是反义的!
-32 = ...
负数存储在CPU寄存器中有不同的方法:
- 符号和正数
(通常用于 floating-point) - 补码
(用于 IPv4、TCP 和 UDP 中的校验和计算) - 带偏移量的整数
(常用于fixed-point算术) - (伪)对称数系
(三进制计算设备的首选方式,但通常不用于二进制计算机) - 补码
几乎所有现代二进制计算机和 CPU 都使用 补码 。对于 MIPS CPUs.
也是如此因为你写了“-32 = 0010 1111 1111”,所以我假设你不明白补码的工作原理:
在二进制补码系统中,左边的位是数字的符号。如果左边的位是 1,则数字是负数。如果左位为零,则数字为正数或零。
(请注意,对于我上面提到的所有存储负数的方法,这 不是 正确。)
通过反转二进制补码数 x
的所有位,我们得到数字 -(x+1)
。这意味着:
31 = 32-1 = 00...0011111
-32 = -(31+1) = 11...1100000
after >> 2 ...
...我们得到的结果是 111111...111000
:
删除了右边的两位,在左边添加了两位"new"。因为这是一个算术移位,所以这是通过 "copying" 原数的左边位来完成的:
左边的位是“1”,所以在左边加了两个“1”位。
But the correct answer should be -8 after shifting, how does that happen??
“111111...111000”的左边位是 1。所以这是一个负数。
现在我们再次应用"invert all bits"规则; x
是寄存器中的值:
x = 111...111000
-(x+1) = 000...000111 = 7
-(x+1) = 7
这意味着:x = (-8)