Сдвиг правой арифметики - PullRequest
0 голосов
/ 16 мая 2019

Пожалуйста, посмотрите следующий код:

addi $t1,$zero,-32
sra $t0,$t1,2

-32 = 0010 1111 1111

после >> 2: 0000 1011 1111 = -26

Но правильный ответ должен быть -8 после сдвига, как это происходит ??

1 Ответ

2 голосов
/ 17 мая 2019

0010 1111 1111

Кажется, это 12-битное число. Процессоры MIPS используют 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). Однако такие люди должны помнить, что слова «влево» и «вправо» (sra = shift right arithmetic) имеют обратное значение!

-32 = ...

Существуют разные способы хранения отрицательных чисел в регистрах ЦП:

  • Знак и положительное число
    (Обычно используется с плавающей точкой)
  • Дополнение
    (Используется для вычисления контрольной суммы в IPv4, TCP и UDP)
  • целое число со смещением
    (Часто используется в арифметике с фиксированной запятой)
  • (псевдо-) симметричные системы счисления
    (Предпочтительный способ для троичных вычислительных устройств, но обычно не используется на бинарных компьютерах)
  • Два дополнения

Почти все современные двоичные компьютеры и процессоры используют дополняют два . Это также верно для процессоров MIPS.

Поскольку вы написали «-32 = 0010 1111 1111», я предполагаю, что вы не поняли, как работает дополнение к двум:

В системе дополнения двоих левый бит является знаком числа. Если левый бит равен единице, число является отрицательным. Если левый бит равен нулю, число положительное или равно нулю.

(Обратите внимание, что не верно для всех методов хранения отрицательных чисел, которые я упоминал выше.)

Инвертируя все биты числа дополнения до двух x, мы получаем число -(x+1). Это значит:

 31 =   32-1  = 00...0011111
-32 = -(31+1) = 11...1100000

после >> 2 ...

... мы получаем результат 111111...111000:

Правые два бита удалены, и два "новых" бита добавлены на левой стороне. Поскольку это арифметический сдвиг, это делается путем «копирования» левого бита исходного числа:

Левый бит - «1», поэтому с левой стороны добавляются два «1».

Но правильный ответ должен быть -8 после сдвига, как это происходит ??

Левый бит "111111 ... 111000" равен единице. Так что это отрицательное число.

Теперь мы снова применяем правило «инвертировать все биты»; x - значение в регистре:

x      = 111...111000
-(x+1) = 000...000111 = 7

-(x+1) = 7

Это означает: x = (-8)

...