右移算术

时间:2019-05-16 20:11:44

标签: assembly mips

请查看以下代码:

/:lang/

-32 = 0010 1111 1111

>> 2之后:0000 1011 1111 = -26

但是正确的答案应该是换班后为-8,这是怎么发生的?

1 个答案:

答案 0 :(得分:2)

  

0010 1111 1111

这似乎是一个12位数字。 MIPS CPU使用32位数字。

因此,无论程序执行哪种操作:0010 1111 1111位都无法描述寄存器的全部内容!

  

-32 = 0010 1111 1111

     

0000 1011 1111 = -26

我尝试了不同的通用方式来存储和写入二进制数字,包括BCD!

我不知道0010 1111 11110000 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寄存器中:

  • 符号和正数
    (通常用于浮点)
  • 一个人的补语
    (用于IPv4,TCP和UDP中的校验和计算)
  • 带偏移量的整数
    (常用于定点运算)
  • (伪)对称数字系统
    (三元计算设备的首选方法,但通常不用于二进制计算机)
  • 补码

几乎所有现代二进制计算机和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)