В общем туплю, почему переполнение возникает при сложении двух положительных чисел? Например складываем два 32 битных числа mov eax, 7FFFFFFF; 01111111111111111111111111111111b mov ebx, eax add eax, ebx В итоге флаг O=1 Вот и думаю что я не понимаю это понятие переполнение. Знаю оно возникает при несоответствии знака результата при сложении чисел со знаком и без, не совсем ясно зачем переполнение возникает при сложении чисел без знака, ведь итоговый результат соответствует правильному в тех же 32 битах?
aptyp Сами по себе числа не есть со знаком или без знака. То же 7FFFFFFFh может быть, как знаковым, так и беззнаковым. Знаковую семантику число приобретает в зависимости от того, как Вы его используете: если Вы проверяете OF на переполнение, значит работаете со знаковыми числами, т.к. OF — флаг знакового переполнения. Флаг беззнакового переполнения — это CF. Т.к. в вышеприведенном примере беззнакового переполнения не происходит, флаг CF не выставляется.
add работает как со знаковыми так и без. OF показывает, что произошло знаковое переполнение. СF что произошло беззнаковое. Выбирай сам каким флагом пользоваться.
Спасибо. Вроде понял. Думал что число, знаковое и без знаковое в процессоре адресуется только 8 битами, 16, и 32. Выходит даже если в 32 бита поместить 32 битное без знаковое число со знаком в 31 бите (считать справа на лево), и если прибавить к нему допустим то же или другое число со знаком в том же 31 бите, получится переполнение из за переноса старшего знакового бита в данном 31 битном числе. Верно?
aptyp Произошло знаковое переполнение, положительное число прибавляют к положительному, результат должен быть положительным, а он стал отрицательным.
Это понятно, но зачем происходит переполнение, когда число поместилось и является корректным для тех же 32 бит в которых и происходило без знаковое для 32 бит сложение. Какой смысл? Ну понятно ещё если это было бы знаковое 8,16 битное число помещённое в 32 бит, а в данном случае в такую логику не въезжаю.
aptyp, вам же объяснил товарищ. если смотрите на флаг OF, значит числа считаются знаковыми, следовательно переполнение возникает. От разрядности это не зависит.
Маладца. Так и знал. Тока во многих (всех) учебниках много разной мути, а вот такие простые моменты объяснены плохо.
aptyp, другими словами, команда add ( и не она одна ) выставляет флаг OF если до операции старший бит первого операнда был == 0, а после операции стал равен 1.
Mankubus И наоборот тоже. OF почти для всех модифицирующих его инструкций равен xor'у битов переноса в старший бит и переноса из старшего бита (либо битов заёма в старший и из старшего), включая, например, однобитовые логические сдвиги.
aptyp Флаг OF -- это переполнение для знаковых операций, а флаг CF -- переполнение для беззнаковых. Сами по себе операции сложения-вычитания выполняются абсолютно одинаково для знаковых и беззнаковых, поэтому разных команд для них (для умножения и деления есть, поскольку они работают уже по-разному). Вот в некоторых древних машинах (и их современных потомках), пока не догадались ввести отдельные флажки для переноса и переполнения, встречались отдельные команды для сложения/вычитания знаковых и беззнаковых чисел. Собственно результат у них был один и тот же, но по-разному устанавливался признак результата, по которому можно было выполнять условный переход (для одной команды соответствовал установке флажка CF, а для другой -- OF).
Mankubus l_inc Если память не изменяет (проверять лениво), флаг переноса равен XOR'у между переносом _в_ старший разряд результата и переносом _из_ старшего разряда результата.
Пускай 00b..11b - байт. Гляньте на табличку(пощитал, надеюсь, без ошибок). Символом "_" отмечены числа, где результат легко подправить через ADC|SBB, ссылаясь на значение flags.cf. C появлением последнего вопросов тоже никаких нету. Непонятна фраза Возвращаясь к таблице: напишите пожалуйста, кто знает, значения flags.of для каждого случая. Код (Text): bin +dec -/+dec -------------- -------------- -------------- 00 00 00 00 +0 +0 +0 +0 +0 +0 +0 +0 00 01 10 11 +0 +1 +2 +3 +0 +1 -2 -1 00 01 10 11 +0 +1 +2 +3 +0 +1 -2 -1 01 01 01 01 +1 +1 +1 +1 +1 +1 +1 +1 00 01 10 11 +0 +1 +2 +3 +0 +1 -2 -1 01 10 11 _00 +1 +2 +3 _+0 +1 _-2 -1 +0 10 10 10 10 +2 +2 +2 +2 -2 -2 -2 -2 00 01 10 11 +0 +1 +2 +3 +0 +1 -2 -1 10 11 _00 _01 +2 +3 _+0 _+1 -2 -1 _+0 _+1 11 11 11 11 +3 +3 +3 +3 -1 -1 -1 -1 00 01 10 11 +0 +1 +2 +3 +0 +1 -2 -1 11 _00 _01 _10 +3 _+0 _+1 _+2 -1 +0 _+1 -2
изменяет... Флаги переполнения и переноса Так как микропроцессор не знает о том с какими числами (со знаком или без знака) мы в данный момент работаем — он на всякий случай предполагает, что все числа со знаком. Допустим мы складываем байты. Сложение например чисел 5 и 126 даст в результате то ли 8-битовое беззнаковое число 131, то ли 8-битовое число -125 со знаком. При сложении произошел перенос в знаковый разряд и получится ошибочный с точки зрения микропроцессора результат — микропроцессор выработает признак переполнения OF, свидетельствующий о том, что результат арифметических операций попал в знаковый разряд. Термины перенос и переполнение используются для близких понятий поэтому требуются определенные уточнения. Флаг переноса (CF) взводится только тогда, когда происходит перенос из из разрядной сетки (из 7, 15 или 31 разрядов в 8, 16, 32, несуществующие для регистра указанной размерности. «Переполнение» обозначает, что результат арифметических операций либо слишком велик, либо слишком мал, чтобы его можно было корректно представить в выходном регистре. Если в результате сложения или вычитания целых чисел взвелся флаг переполнения (OF), это означает, что при «сложении по модулю 2» знаковых битов слагаемых (S1 и S2), знакового бита суммы (SR) и флага переноса (CF) получилась единица. S1 xor S2 xor SR xor CF = OF Перенос используют для выполнения операций с увеличенной точностью, а признак переполнения нужен для определения правильности или неправильности выполнения арифметической операции над операндами со знаком. |OF|CF|Комментарий |S1 xor S2 xor SR xor CF = OF mov al,3Fh | | |3Fh+1=40h | add al,1 | 0 | 0 |63+1=64(верно)|0 xor 0 xor 0 xor 0 = 0 mov al,0FDh | | |0FDh+5=[1]02h (перенос)| add al,5 | 0 | 1 |-3+5=2 (верно)|1 xor 0 xor 0 xor 1 = 0 mov al,0FCh | | |0FCh+5=[1]01h(перенос)| add al,5 | 0 | 1 |-4+5=1 (верно)|1 xor 0 xor 0 xor 1 = 0 mov al,40h | | |40h+0C0h=[1]00h(перенос)| add al,0C0h | 0 | 1 |64-64=0 (верно)|0 xor 1 xor 0 xor 1 = 0 mov al,80h | | |80h+80h=[1]00h(перенос)| add al,80h | 1 | 1 |-128-128=0 (неверно)|1 xor 1 xor 0 xor 1 = 1 Совершенно аналогично операциям сложения можно произвести ряд операций вычитания, отслеживая зависимость флага OF от наличия займов, а также знаков уменьшаемого, вычитаемого и разницы То же правило распространяется на операцию NEG если рассматривать ее как операцию вычитания из нуля |OF|CF|Комментарий |S1 xor S2 xor SR xor CF = OF mov al,80h | | |(1)00h-80h=80h (займ)| neg al | 1 | 1 |0-(-128)=-128 (не верно)| 0 xor 1 xor 1 xor 1 = 1 mov al,0 | | |0-0=0 | neg al | 0 | 0 |0-0=0 (верно)|0 xor 0 xor 0 xor 0 = 0 mov al,-5| | |(1)00h-FBh=5(займ)| neg al | 0 | 1 |0-(-5)=5 (верно)|0 xor 1 xor 0 xor 1 = 0 mov al,50h | | |(1)00h-50h=0B0h(займ) neg al | 0 | 1 |0-80 =-80 (верно)|0 xor 0 xor 1 xor 1 = 0