Как ЦП выполняет вычитание?

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

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

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

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

  A = 5B = 2  

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

  A = 2B = 5  

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

Я понимаю, что любая условная логика типа «если-то и т. Д.» Будет реализована аппаратно внутри ALU. вычисление 2-х дополнений и т. д., отбрасывание лишнего бита будет выполняться аппаратно внутри ALU. Как выглядит этот компонент ALU?


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

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


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

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

  99+  22 ===  

Чтобы сделать это, нам нужно будет кое-что «Нести».

   11 99 + 22 === 121  

9 плюс 2 равно 1, переносят единицу, 1 плюс 9 плюс 2 составляют 2, переносят единицу …

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

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

  0101 + 0010 ===== 0111  

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

И если мы хотим сложить 5 и -2

  11 0101 + 1110 ===== 0011  

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

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

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

  v этот бит обычно равен нулю, для вычитания мы устанавливаем этот перенос в бит 11 11 0101 пять + 1101 дополнение до 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 в зависимости от состояния флага переноса в регистре состояния.

Умножение — это совсем другая история. двоичный код делает умножение намного проще, чем при использовании десятичной математики, но вам НЕОБХОДИМО иметь разные инструкции умножения без знака и со знаком. А деление — это отдельный зверь, поэтому в большинстве наборов инструкций деления нет. У многих нет умножителя, потому что он сжигает количество ворот или часов.


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

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

  99 + 22 ===  

Для этого у нас будет происходить «Неси своего».

  11 99 + 22 ===  121  

9 плюс 2 — это 1, переносят один, 1 плюс 9 плюс 2 — это 2, несут один …

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

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

  0101 + 0010 ===== 0111  

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

И если мы хотим сложить 5 и -2

  11 0101 + 1110 ===== 0011  

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

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

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

  v этот бит обычно равен нулю, для вычитания мы устанавливаем этот перенос в бит 11 11 0101 пять + 1101 дополнение до 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 в зависимости от состояния флага переноса в регистре состояния.

Умножение — это совсем другая история. двоичный код делает умножение намного проще, чем при использовании десятичной математики, но вам НЕОБХОДИМО иметь разные инструкции умножения без знака и со знаком. А деление — это отдельный зверь, поэтому в большинстве наборов инструкций деления нет. У многих нет умножителя, потому что он сжигает количество ворот или часов.


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

  B = -2  

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

  1111 1111 1111 1111 1111 1111 1111 1110  

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

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

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


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

  B = -2  

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

  1111 1111 1111 1111 1111 1111 1111 1110  

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

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

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


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

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

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

Архитектура компьютера — Полный сумматор

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

  • Цифровой дизайн и компьютерная архитектура
  • Организация и дизайн компьютера MIPS Edition: The Hardware /Программный интерфейс
  • Организация и проектирование компьютера RISC-V Edition: аппаратный программный интерфейс

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

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

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

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


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

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

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

Архитектура компьютера — Полный сумматор

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

  • Цифровой дизайн и компьютерная архитектура
  • Организация и дизайн компьютера MIPS Edition: The Hardware /Программный интерфейс
  • Организация и проектирование компьютера RISC-V Edition: аппаратный программный интерфейс

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

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

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

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


В нотации с дополнением до 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, …

Или еще две формулы:

  not (-A) = A - 1- (not A) = A +  1  


В нотации с дополнением до 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, …

Или еще две формулы:

  not (-A) = A - 1- (not A) = A +  1  

Оцените статью
techsly.ru
Добавить комментарий