Нести флаг
В компьютерных процессорах флаг переноса (обычно обозначаемый как флаг C ) представляет собой один бит системы в регистре состояния / регистре флагов, используемый для указания того, когда арифметический перенос или заимствование были сгенерированы из наиболее значимого бита арифметико-логического устройства (АЛУ). позиция. Флаг переноса позволяет складывать/вычитать числа, превышающие одну ширину ALU, путем переноса (добавления) двоичной цифры из частичного сложения/вычитания в позицию младшего бита более значимого слова. Обычно это программируется пользователем процессора на уровне ассемблера или машинного кода, но в некоторых процессорах это также может происходить внутри, посредством цифровой логики или микрокода , где некоторые процессоры имеют более широкие регистры и арифметические инструкции, чем (комбинаторные или «физические» ) АЛУ. [1] Он также используется для расширения битовых сдвигов и ротации аналогичным образом на многих процессорах (иногда это делается с помощью специального флага). Для вычитающих операций используются два (противоположных) соглашения, поскольку большинство машин устанавливают флаг переноса при заимствовании, тогда как некоторые машины (например, 6502 и PIC ) вместо этого сбрасывают флаг переноса при заимствовании (и наоборот).
Использует [ править ]
На флаг переноса влияет результат большинства арифметических (и обычно нескольких битовых) инструкций, а также он используется в качестве входных данных для многих из них. Некоторые из этих инструкций имеют две формы, которые либо читают, либо игнорируют перенос. В языках ассемблера эти инструкции представлены мнемоникой, например ADD/SUB
, ADC/SBC
( ADD/SUB
включая переноску), SHL/SHR
( битовые сдвиги ), ROL/ROR
(бит вращается), RCR/RCL
(поворот через перенос) и так далее. [2] Использование флага переноса таким образом позволяет выполнять нескольких слов операции сложения, вычитания, сдвига и поворота .
Примером может служить то, что произойдет, если сложить 255 и 255 с помощью 8-битных регистров. Результат должен быть 510, что является 9-битным значением. 111111110
в двоичном формате. Восемь младших битов, всегда хранящихся в регистре, будут 11111110
двоичный (254 десятичных), но поскольку имеется перенос бита 7 (восьмого бита), устанавливается перенос, указывающий, что результат требует 9 бит. Действительный 9-битный результат представляет собой объединение флага переноса с результатом.
Для x86 ALU размером 8 бит, 8-битная интерпретация дополнения до двух, операция сложения 11111111
+ 11111111
приводит к 111111110
, Carry_Flag
набор, Sign_Flag
набор, и Overflow_Flag
прозрачный.
Если 11111111
представляет целое число со знаком, дополненное до двух -1 ( ADD al,-1
), то интерпретация результата равна -2, поскольку Overflow_Flag
ясно, и Carry_Flag
игнорируется. Знак результата отрицательный, так как Sign_Flag
установлен. 11111110
- это форма дополнения до двух целого числа со знаком -2.
Если 11111111
представляет целое двоичное число без знака 255 ( ADD al,255
), то интерпретация результата будет равна 254, что неверно, поскольку наиболее значимая часть результата уходит в Carry_Flag
, что поэтому нельзя игнорировать. Overflow_Flag
и Sign_Flag
игнорируются.
Другим примером может быть 8-битный регистр с битовой комбинацией 01010101
и установлен флаг переноса; если мы выполним поворот влево через инструкцию переноса, результат будет 10101011
с очищенным флагом переноса, поскольку наиболее значимый бит (бит 7) был заменен переносом, а перенос был заменен младшим битом (бит 0).
Ранние микропроцессоры Intel 4004 и Intel 8008 имели специальные инструкции для явной установки и сброса флага переноса. Однако более поздние версии Intel 8080 (и Z80 ) не включали явный код операции переноса сброса, поскольку это можно было сделать одинаково быстро с помощью одной из побитовых инструкций AND, OR или XOR (которые не используют флаг переноса).
Флаг переноса также часто используется после инструкций сравнения, которые обычно реализуются с помощью операций вычитания, чтобы позволить принять решение о том, какое из двух сравниваемых значений меньше (или больше, или равно) другого. Инструкции перехода, которые проверяют флаг переноса, часто представляются мнемоникой , например: BCC
и BCS
на разветвление, если перенос свободен, или на разветвление, если перенос установлен соответственно. При таком использовании флаг переноса обеспечивает механизм сравнения значений как целых чисел без знака. В этом отличие от флага переполнения , который обеспечивает механизм сравнения значений как целочисленных значений со знаком.
Против. флаг заимствования [ править ]
Этот раздел нуждается в дополнительных цитатах для проверки . ( Июль 2015 г. ) |
Хотя флаг переноса четко определен для сложения, существует два общепринятых способа использования флага переноса для операций вычитания.
Первый использует бит как флаг заимствования, устанавливая его, если a < b при вычислении a − b , и необходимо выполнить заимствование. Если a ≥ b , бит очищается. Вычитание с заимствованием ( SBB
) инструкция вычислит a − b − C = a −( b + C ), а вычитание без заимствования ( SUB
) действует так, как если бы бит заимствования был очищен. 8080 , 6800 , Z80 , 8051 , x86 [2] и 68 тысяч семей (среди прочих) используют кредит.
Второй использует тождество, что − x = ( not x )+1 напрямую (т. е. без сохранения инвертированного бита переноса) и вычисляет a − b как a +(not b )+1. Флаг переноса устанавливается в соответствии с этим сложением, и вычитание с переносом вычисляет a +not( b )+ C , тогда как вычитание без переноса действует так, как если бы бит переноса был установлен. В результате бит переноса устанавливается, если a ≥ b , и очищается, если a < b . Система /360 , [3] 6502 , MSP430 , COP8 , ARM и PowerPC Это соглашение используется в процессорах . 6502 является особенно известным примером, поскольку он не имеет операции вычитания без операции переноса, поэтому программисты должны убедиться, что флаг переноса установлен перед каждой операцией вычитания, где заимствование не требуется. [4]
Нести или одолжить немного | Вычесть без носить/одолжить | Вычесть с займом | Вычесть с переноской |
---|---|---|---|
С = 0 | а - б = а + не( б ) + 1 | а - б - 0 = а + не( б ) + 1 | а - б - 1 = а + не( б ) + 0 |
С = 1 | а - б - 1 = а + не( б ) + 0 | а - б - 0 = а + не( б ) + 1 |
Чаще всего первый вариант называется «вычитанием с заимствованием», а второй — «вычитанием с переносом». Однако есть исключения в обоих направлениях; Архитектуры VAX , NS320xx и Atmel AVR используют соглашение о заимствовании битов, но называют свою операцию a − b − C «вычитанием с переносом» ( SBWC
, SUBC
и SBC
). Архитектуры PA-RISC и PICmicro используют соглашение о битах переноса, но называют свою операцию a +not( b )+ C «вычитанием с заимствованием» ( SUBB
и SUBWFB
).
8-битные микроконтроллеры ST6 , пожалуй, самые запутанные из всех. Хотя у них нет какой-либо инструкции «вычитание с переносом», у них есть бит переноса, который устанавливается командой вычитания, и соглашение зависит от модели процессора. Процессор ST60 использует соглашение «переноса», тогда как процессоры ST62 и ST63 используют соглашение «заимствования». [5]
См. также [ править ]
Ссылки [ править ]
- ^ Хорошо известные Z80 и 68000 являются примерами таких процессоров, среди многих других.
- ^ Jump up to: Перейти обратно: а б «Руководство разработчика программного обеспечения для архитектуры Intel, том 2: Справочное руководство по набору команд» (PDF) . Проверено 25 октября 2007 г.
- ^ Принципы работы IBM System/360 (PDF) . п. 28. Форма IBM A22-6821-0.
- ^ Тан, BTG (май 1983 г.). «Инструкции SBC, TSX и TXS для 6800 и 6502» (PDF) . Журнал доктора Добба (79): 67–68.
- ^ «Руководство по программированию семейства ST6» (PDF) . Версия 2.0. СТМикроэлектроника . Октябрь 2004 г., стр. 21–22, 42 . Проверено 28 февраля 2017 г.