Overflow vs Carry flags, действительно основные термины
Я пытался разобраться с переполнением и переносом (для ARM7, но достаточно базовым, чтобы я имел в виду термины применительно ко всему).
Я думаю, что, наконец, у меня это есть - но я хочу проверить, что мое "настоящее базовое понимание" правильное, вся сложность снята, это тот случай, когда все сводится к следующему:
unsigned => V = 0
V = 1 => bit n is incorrect
C = 1 => bit n+1 'exists'
Спасибо,
1 ответ
Эти биты состояния, связанные с переполнением, имеют отношение к дополнению без знака и по сравнению с двумя.
Само дополнение является независимым от знака, то есть красотой дополнения двух. Один фрагмент логики можно использовать для сложения и вычитания без знака и со знаком. Единственное место, которое имеет значение для беззнакового и знакового сложения или вычитания, - это биты переполнения, переполнение без знака (иначе говоря, бит переноса) и переполнение со знаком (также как переполнение).
бит для переноса, надеюсь, более очевиден, так как мы узнали о переносе в начальной школе
7
+4
=====
Вам нужно "нести один", чтобы сделать это дополнение. Точно то же самое в двоичном формате, за исключением того, что процессоры обычно имеют фиксированное количество мест, где на бумаге ширина операции зависит от того, сколько бумаги у вас есть.
так что для любого сложения, если установлен перенос msbit, то было переполнение без знака, у нас не было достаточно битов для количества столбцов.
Теперь это приводит к некоторой путанице, поскольку о бите переноса говорят и о вычитании, и это становится реализацией, поэтому я не обязательно (и не лично) запоминаю, что рука делает это, x86 делает это и т. Д., Но помнит один способ чтобы выяснить, что такое число дополнения до двух, "инвертировать и добавить один". Например, если вы хотите вычесть 5 из 7, то, что вы будете делать в логике, это не добавить -5, а вместо этого добавить дополнение к 5 и установить (инвертировать) бит переноса
1 <- invert or set the carry in bit
111 <- 7 (0b111)
+ 010 <- ones complement of 5 (0b101)
=====
тогда мы делаем математику
1111
111
+ 010
=====
010
и в результате 2 (2b010) с выносом?
Нет, что выполнение не означает неподписанное переполнение. при вычитании думать о выполнении как об обратном с точки зрения переполнения. Вот где некоторые процессоры меняются. Некоторые из них инвертируют результат флага переноса, когда операция представляет собой вычитание, поэтому приведенная выше операция alu может привести к переносу флага 1 или флага переноса 0 для этого вычитания в зависимости от процессора, что также означает, что при выполнении вычитания с заимствовать, если процессор поддерживает его, перенос будет инвертирован или нет при входе.
Так что насчет подписанного переполнения?
Хорошо, давайте посмотрим на трехбитные структуры
unsigned signed
000 0 0
001 1 1
010 2 2
011 3 3
100 4 -4
101 5 -3
110 6 -2
111 7 -1
Так, например, если мы добавим битовые комбинации 2b011 + 2b010, без знака, который будет 3+2 = 5, со знаком, который будет 3+2 = -3... ммм, это неправильно. Подписанное переполнение скажет вам об этом. Выполнение, переполнение без знака не будет установлено для этой операции, но переполнение со знаком будет. С x86 может быть даже половинное переполнение и полное переполнение? более одного переполнения? у кого-то есть один с вещами AL,AH и AX..
Тем не мение
0100 < - carry in and out
011
+ 010
======
100
Обратите внимание, что перенос в msbit равен 1, а перенос равен 0, поэтому мы обнаруживаем переполнение со знаком.
Да, вы можете думать, что бит n ошибочен, потому что знак неверен. Тем не менее, с математической точки зрения это не так, бит знак неверен, потому что нет достаточно битов для хранения ответа, не отличаясь от беззнакового добавления 7+5 = 12 = 0b1100, если бы у нас был 3-битный сумматор, мы получили бы 7+5 = 4 с выноской, указывающей на то, что места для хранения всех битов результата недостаточно. Неподписанное переполнение.