В компьютерных процессорах флаг переноса (обычно обозначается как флаг C ) - это единственный бит в системном регистре состояния / регистре флага, используемом для указания, когда арифметическое перенос или заимствование было сгенерировано из самой значимой битовой позиции арифметико-логического блока (ALU). Флаг переноса позволяет добавлять / вычитать числа, превышающие ширину одного ALU, путем переноса (добавления) двоичной цифры из частичного сложения / вычитания в позицию младшего бита более значимого слова. Он также используется для расширения битовых сдвигов и вращается аналогичным образом на многих процессорах (иногда это делается с помощью специального флага X ). Для операций вычитания используются два (противоположных) соглашения, так как большинство машин устанавливают флаг переноса при заимствовании, в то время как некоторые машины (например, 6502 и PIC ) вместо этого сбрасывают флаг переноса. заимствовать (и наоборот).
На флаг переноса влияет результат большинства арифметических (и обычно нескольких побитовых) инструкций и также используется в качестве входных данных для многих из них. Некоторые из этих инструкций имеют две формы, которые либо читают, либо игнорируют перенос. В языках ассемблера эти инструкции представлены мнемоникой, например ADD / SUB
, ADC / SBC
(ADD / SUB
включая перенос), SHL / SHR
(битовые сдвиги ), ROL / ROR
(биты вращаются), RCR / RCL
( вращать через перенос) и т. д. Использование флага переноса таким образом позволяет выполнять операции сложения, вычитания, сдвига и поворота из нескольких слов слов.
Например, если сложить 255 и 255, используя 8-битные регистры. Результатом должно быть 510, что является 9-битным значением 111111110
в двоичном формате. 8 младших значащих битов, всегда сохраняемых в регистре, будут 11111110
двоичными (254 десятичных), но поскольку есть перенос бита 7 (восемь битов), перенос устанавливается, указывая, что результат требует 9 биты. Допустимый 9-битный результат - это соединение флага переноса с результатом.
Для x86 ALU размером 8 бит, 8-битной интерпретации дополнения до двух, операция сложения 11111111
+ 11111111
приводит к 111111110
, Carry_Flag
установлен, Sign_Flag
установлен, а Overflow_Flag
очищен.
Если 11111111
представляет собой дополненное до двух целое число со знаком -1 (ADD al, -1
), то интерпретация результата будет 11111110
, потому что Overflow_Flag
сброшен, а Carry_Flag
игнорируется. Знак результата отрицательный, потому что установлен Sign_Flag
. 11111110
- это двоичное дополнение целого числа со знаком −2.
Если 11111111
представляет собой целое двоичное число без знака 255 (ADD al, 255
), то интерпретация результата, что Carry_Flag
не может быть игнорируется. Overflow_Flag
и Sign_Flag
игнорируются.
Другим примером может быть 8-битный регистр с битовой комбинацией 01010101
и установленным флагом переноса; если мы выполним команду поворота влево через перенос, результат будет 10101011
с очищенным флагом переноса, потому что самый старший бит (бит 7) был повернут в перенос, а перенос был повернут в младший бит (бит 0).
Ранние микропроцессоры Intel 4004 и Intel 8008 имели особые инструкции для установки, а также явного сброса флага переноса. Однако в более поздних версиях Intel 8080 (и Z80 ) не было явного кода операции переноса сброса, поскольку это можно было сделать так же быстро с помощью одной из команд побитового AND, OR или XOR (которые не используйте флаг переноса).
Флаг переноса также часто используется после инструкций сравнения, которые обычно реализуются с помощью операций вычитания, чтобы можно было принять решение о том, какое из двух сравниваемых значений ниже (или больше или равно) Другие. Инструкции перехода, которые проверяют флаг переноса, часто представлены мнемониками , такими как BCC
и BCS
для перехода, если перенос очищен, или перехода, если перенос установлен соответственно. При использовании таким образом флаг переноса обеспечивает механизм для сравнения значений как целых чисел без знака. Это контрастирует с флагом переполнения , который предоставляет механизм для сравнения значений как целочисленных значений со знаком.
Хотя флаг переноса хорошо определен для сложения, существует два общих способа использования флага переноса для операций вычитания.
Первый использует бит как флаг заимствования, устанавливая его, если инструкция SBB) вычислит a − b − C = a− ( b + C), а вычитание без заимствования (SUB
) действует так, как если бы бит заимствования был очищен. Семейства 8080, Z80, 8051, x86 и 68k (среди прочих) используют бит заимствования.
Второй использует преимущество тождества, что -x = не (x) +1, и вычисляет a-b как a + not (b) +1. Флаг переноса устанавливается в соответствии с этим сложением, и вычитание с переносом вычисляет a + not (b) + C, в то время как вычитание без переноса действует так, как если бы был установлен бит переноса. В результате бит переноса устанавливается, если a≥b, и сбрасывается, если
Перенос или. бит заимствования | Вычитание без. переноса / заимствования | Вычитание. с заимствованием | Вычесть. с переносом |
---|---|---|---|
C = 0 | a - b. = a + not (b) + 1 | a - b - 0. = a + not (b) + 1 | a + not (b) + 0. = a - b - 1 |
C = 1 | a - b - 1. = a + not (b) + 0 | a + not (b) + 1. = a - b - 0 |
Чаще всего первая альтернатива называется «вычитание с заимствованием», а вторая - «вычитание с переносом». Однако есть исключения в обоих направлениях; Архитектуры VAX, NS320xx и Atmel AVR используют соглашение о битах заимствования, но называют свою операцию a-b-C «вычитание с переносом» (SBWC
, SUBC
и SBC
). Архитектуры PA-RISC и PICmicro используют соглашение о битах переноса, но называют свою операцию a + not (b) + C «вычитание с заимствованием» (SUBB
и SUBWFB
).
8-битные микроконтроллеры ST6 / ST7, пожалуй, самые запутанные из всех. Хотя у них нет какой-либо инструкции «вычитание с переносом», у них есть бит переноса, который устанавливается инструкцией вычитания, и соглашение зависит от модели процессора. Процессор ST60 использует соглашение «переноса», в то время как процессоры ST62 и ST63 используют соглашение «заимствования».