Как процессор выполняет вычитание? - PullRequest
7 голосов
/ 26 апреля 2011

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

Скажите, А = 5, В = -2. Предполагая, что A и B - 4 байта, как процессор выполняет сложение A + B?

Я понимаю, что A будет иметь бит знака (MSB) как 0 для обозначения положительного значения и B будет иметь бит знака как 1 для обозначения отрицательного целого числа.

Теперь, когда в программе на C ++ я хочу напечатать A + B, проверяет ли модуль сложения ALU (Арифметическая логическая единица) сначала бит знака, а затем решает выполнить вычитание, а затем выполнить процедуру вычитания. Как вычитание будет моим следующим вопросом.

A = 5
B = 2

Я хочу сделать A - B. Компьютер возьмет 2 дополнения B и добавит A + 2 дополнения B и вернет это (после сброса лишнего бита слева)?

A = 2
B = 5

сделать A - B. Как компьютер работает в этом случае?

Я понимаю, что любая условная логика типа "если-то" и т. Д. Все будет выполняться аппаратно внутри АЛУ. вычисление дополнения 2s и т. д., исключая лишний бит, все будет сделано аппаратно внутри ALU. Как выглядит этот компонент ALU?

Ответы [ 5 ]

14 голосов
/ 26 апреля 2011

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

Итак, чтобы найти A-B, мы можем просто отрицать B и добавить; то есть мы находим A + (-B), и, поскольку мы используем 2-дополнение, мы не беспокоимся о том, положительный или отрицательный (-B), потому что алгоритм сложения работает одинаково в любом случае.

7 голосов
/ 27 апреля 2011

Думайте в терминах двух или трех битов, а затем понимайте, что эти вещи масштабируются до 32 или 64 или сколь угодно много битов.

Сначала давайте начнем с десятичного числа

 99
+22
===

чтобы сделать это, у нас будет продолжаться "Carry the one's".

11
 99
+22
===
121

9 плюс 2 - это 1, но один, 1 плюс 9 плюс 2, это 2, но ... ... 1009*

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

Поскольку вы использовали 5 и 2, давайте выполним 4-битную двоичную математику

 0101
+0010
=====
 0111

Нам не нужно было переносить это, но вы можете видеть, что математика сработала, 5 + 2 = 7.

И если мы хотим добавить 5 и -2

11
 0101
+1110
=====
 0011

И ответ будет 3, как и ожидалось, не удивительно, но у нас получилось.И так как это было добавление с минусом в двойном дополнении, все это работало, тогда не было знака бита тогда, двойное дополнение делает его таким, что нам все равно, просто подайте сумматор двум операндам.

Теперь, если выЕсли вы хотите сделать тонкую разницу, то, что если вы хотите вычесть 2 из 5, вы выбираете инструкцию вычитания, а не добавление.Ну, мы все узнали, что отрицание в дополнение к двум означает инвертировать и добавить один.И мы видели выше, что сумматор с двумя входами действительно нуждается в третьем входе для переноса, чтобы его можно было каскадировать настолько широко, насколько требуется сумматор.Таким образом, вместо двух операций сложения, инвертировать и добавить 1 - это первое добавление реального сложения, все, что нам нужно сделать, - это инвертировать и установить перенос:

Понимать, что логики вычитания нет, добавляется отрицательныйвсего, что вы кормите.

    v this bit is normally zero, for a subtract we set this carry in bit
11 11
 0101 five
+1101 ones complement of 2
=====
 0011

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

Существует два вида переполнения: без знака и со знаком.Без знака просто бит переноса.Переполнение со знаком связано со сравнением бита переноса в столбце msbit с битом переноса для этого столбца.Для приведенной выше математики вы видите, что перенос и вынос этого столбца msbit одинаковы, оба едины.И мы случайно узнали, что в 4-битной системе достаточно места для правильного представления чисел +5, -2 и +3.4-битная система может представлять числа от +7 до -8.Поэтому, если вы добавите 5 и 5 или -6 и -3, вы получите переполнение со знаком.

01 1
 0101
+0101
=====
 1010

Поймите, что ЖЕ добавленная логика используется для математики со знаком и без знака, это зависит от васкод, а не логика для виртуального определения, считались ли эти биты двумя дополнениями со знаком или без знака.

В приведенном выше случае 5 + 5 вы видите, что перенос в столбце msbit равен 1, но перенос выполнен0, что означает флаг V, флаг переполнения со знаком, будет установлен логикой.В то же время вынос этого бита, который является флагом C, флагом переноса, не будет установлен.Когда мы думаем, что беззнаковые 4 бита могут содержать числа от 0 до 15, 5 + 5 = 10 не переполняется.Но если думать о знаке, то 4 бита могут содержать от +7 до -8, а 5 + 5 = 10 - переполнение со знаком, поэтому флаг V установлен.

, если / когда у вас есть инструкция сложения с переносом, они берут ТО ЖЕсхема сумматора и вместо подачи переноса в ноль подается флаг переноса.Аналогично вычитание с заимствованием, вместо подачи переноса в 1, перенос составляет 1 или 0, в зависимости от состояния флага переноса в регистре состояния.

Умножение - это совсем другая история, двоичный код значительно упрощает умножение по сравнению с десятичной математикой, но вы ДОЛЖНЫ иметь разные беззнаковые и подписанные инструкции умножения. А разделение - это отдельный зверь, поэтому в большинстве наборов команд нет разделения. У многих нет умножения из-за количества ворот или часов, которые он сжигает.

7 голосов
/ 26 апреля 2011

Вы немного не правы в части знакового бита.Это не просто знаковый бит - каждое отрицательное число преобразуется в дополнение к 2.Если вы напишите:

B = -2

Компилятор при компиляции в двоичный файл сделает это:

1111 1111 1111 1111 1111 1111 1111 1110

Теперь, когда он хочет добавить 5, ALU получает 2 числа и добавляет их,простое добавление.

Когда ALU получает команду на вычитание, ему присваивается 2 числа - он делает NOT для каждого бита второго числа и делает простое добавление и добавляет еще 1 (потому что дополнение 2 НЕ являетсяк каждому биту +1).

Основная вещь, которую следует помнить, состоит в том, что дополнение 2 было выбрано именно для того, чтобы не делать 2 отдельных процедуры для 2 + 3 и для 2 + (- 3).

1 голос
/ 23 мая 2019

модуль сложения ALU (Арифметическая логическая единица) сначала проверяет бит знака, а затем решает выполнить вычитание, а затем следует процедуре вычитания

Нет, в одном и двух дополнениях нет никакой разницы между сложением / вычитанием положительного или отрицательного числа . АЛУ работает одинаково для любой комбинации положительных и отрицательных значений

Таким образом, ALU в основном делает A + (-B) для A - B, но ему не требуется отдельный шаг отрицания. Дизайнеры используют хитрый трюк, чтобы сумматоры делали и add, и sub на одной и той же длине цикла , добавляя только muxer и вентиль NOT вместе с новым входом Binvert для того, чтобы условно инвертировать второй вход. Вот простой пример ALU, который может делать AND / OR / ADD / SUB

Full-adder

Компьютерная архитектура - полный сумматор

Настоящий сумматор - это просто коробка со знаком плюс внутри ⊞, которая добавляет a с b или ~ b и , несущими , производя суммы и выполнения . Это работает, понимая, что в дополнении до двух -b = ~b + 1, так что a - b = a + ~b + 1. Это означает, что нам просто нужно установить перенос на 1 (или отменить перенос для заимствования) и инвертировать второй ввод (т.е. b ). Этот тип ALU можно найти в различных книгах по компьютерной архитектуре, таких как

RISC-V ALU

В дополнение -b = ~b, поэтому вы не можете установить в поле , когда хотите вычесть, в противном случае дизайн будет таким же. Однако дополнение к двум имеет еще одно преимущество: операции со значениями со знаком и без знака также работают одинаково, поэтому вам даже не нужно различать типы со знаком и без знака. Для дополнения вам нужно добавить бит переноса к младшему значащему биту , если тип подписан

С некоторыми простыми модификациями вышеупомянутого ALU теперь они могут выполнять 6 различных операций: ADD, SUB, SLT, AND, OR, NOR

6-function ALU

CSE 675.02: введение в архитектуру компьютеров

Многобитовые операции выполняются путем объединения нескольких однобитовых ALU, указанных выше. На самом деле ALU способны выполнять гораздо больше операций, но они созданы для экономии места по аналогичному принципу

1 голос
/ 17 марта 2017

В 2-х обозначениях: не B = -B -1 или -B = (не B) + 1. Это можно проверить на компьютере или на бумаге.

То есть A - B = A + (не B) + 1, который можно выполнить с помощью:

1 поразрядно не

1 шаг

1 дополнение

Есть хитрость в том, чтобы неэффективно увеличивать и уменьшать, используя только ноты и отрицания. Например, если вы начинаете с 0 в регистре и выполняете:

not, neg, not, neg, not, neg, ... регистр будет иметь значения:

-1, 1, -2, 2, -3, 3, ...

Или как еще 2 формулы:

не (-A) = A - 1

- (не A) = A + 1

...