Из руководства "Intel Software developer`s manual vol.1" (перевод):
CF - устанавливается, если в результате арифметической операции произошло переполнение разрядной сетки либо заем из старшего бита. Флаг свидетельствует о переполнении для беззнаковых чисел.
Будем рассматривать все на примере 8-битных чисел/регистров.
С переполнением разрядной сетки все достаточно просто. Диапазон беззнаковых чисел, которые могут быть представлены 8 битами - это 0...255. Следовательно переполнение наступит, если результатом выполнения операции будет число больше 255.
clc mov al, 250 mov bl, 10 add al, bl ; должно быть 260, но на деле в al 4
В данном случае число не помещается в 8 бит, и возникает переполнение.
Рассмотрим числа 8 и 6. Что будет если из 6 вычесть 8? В двоичном представлении 6 имеет вид 00000110, 8 - 00001000. При поразрядном вычитании в 4 бите произойдет заем, который породит заем из 5,6,7,8 битов. Т.е. в итоге происходит заем из старшего бита, а это значит что флаг переноса устанавливается.
clc mov al, 6 mov bl, 8 sub al, bl ; теперь в al -2
Для чего в данном случае устанавливается флаг. Дело в том, что результат получается отрицательным, что логично, но это неверно для беззнаковых чисел, которые по определению не могут иметь отрицательного значения. Т.е. результат опять не входит в диапазон 0...255 Из этого можно сделать вывод - если происходит вычитание большего числа из меньшего, то флаг переноса будет установлен, т.к. в этом случае происходит заем из старшего бита.
А при сложении отрицательного и положительного (минус на минус дает плюс) и получая по сути тот же результат, флаг переноса устанавливаться не будет, несмотря на то, что результат является слишком малым и не входит в диапазон 0...255. Дело в том, что отсутствует заем из старшего бита.
mov al, -79 mov bl, 49 add al, bl ; CF = 0Но если взять вместо -79 число -49, то флаг переноса установится, т.к. -49 для беззнаковых чисел равно 207, а 207+49=256, что является переполнением 8 бит.
Флаг переноса полезен при работе с большими числами, не помещающимися в 32-разрядный регистр. Например, если требуется сложить 2 числа, каждое из которых расположено в паре 32-рязрядных регистров.
Рассмотрим флаг переполнения.
Из руководства "Intel Software developer`s manual vol.1" (перевод):
Флаг OF устанавливается, если число - слишком большое положительное, либо слишком маленькое отрицательное. Флаг свидетельствует о переполнении для знаковых чисел.
Диапазон знаковых чисел в 8-битном случае -128...127, т.е., как сказано в руководстве, 2 варианта:
- Число слишком мало для представления в виде 8-битного знакового
- Число слишком велико для представления в виде 8-битного знакового
Первый случай:
mov al, 117 mov bl, 92 add al, bl ;В итоге имеем -47 вместо 209 из-за переноса в знаковый бит, т.е. число 209 выходит за допустимый диапазон сверху.
Второй случай:
mov al, -20 mov bl, -118 add al, bl ;Складываем 2 отрицательных числа и получаем тем не менее положительную сумму (118 вместо -138), т.к. -138 выходит за допустимый диапазон снизу.
Но что такое "знаковые числа"? Как процессор понимает, когда используется знаковое, а когда - беззнаковое число. На самом деле процессор не знает этого. Он сразу предполагает оба случая и в соответствии с этим выставляет флаги.
Комментариев нет :
Отправить комментарий