Почему команда x86 INC
(increment) и DEC
(декремент) не влияет на CF
(флаг переноса) в FLAGSREGISTER?
Почему инструкции INC и DEC не влияют на флаг переноса?
Ответ 1
Чтобы понять, почему вам, вероятно, нужно помнить, что текущие процессоры "x86" с 32-разрядными и 64-битными значениями начали работу с гораздо более ограниченными 8-разрядными машинами, вернулись к Intel 8008. (Я закодировал в этом мире еще в 1973 году, Я все еще помню (тьфу) это!).
В этом мире регистры были драгоценными и маленькими. Вам нужны inc/dec для различных целей, наиболее распространенным из которых является управление контуром. Многие циклы включали выполнение "арифметики с несколькими точками" (например, 16 бит или более!) Благодаря тому, что inc/dec установил бит Z, вы могли бы использовать их для управления циклами довольно красиво; настаивая на том, что инструкции управления циклом не изменяют бит переноса, перенос сохраняется по итерациям цикла, и вы можете выполнять операции с множественными значениями без написания тонны кода для запоминания состояния переноса.
Это сработало очень хорошо, как только вы привыкли к уродливому набору команд.
На более современных машинах с большими размерами слов вам это не нужно, поэтому INC и DEC могут быть семантически эквивалентны ADD..., 1 и т.д. Это на самом деле то, что я использую, когда мне нужно переносить set: -}
В основном, я держусь подальше от INC и DEC, потому что они выполняют частичные обновления кода состояния, и это может вызвать смешные киоски в конвейере, и ADD/SUB этого не делают. Поэтому, когда это не имеет значения (большинство мест), я использую ADD/SUB, чтобы избежать киосков. Я использую INC/DEC только при сохранении небольшого значения кода, например, при установке в строку кэша, где размер одной или двух инструкций делает достаточную разницу для материи. Это, вероятно, бессмысленная nano [буквально!] - оптимизация, но я довольно старая школа в своих привычках кодирования.
Мое объяснение говорит нам, почему INC/DEC установил нулевой бит. У меня нет особого убедительное объяснение того, почему INC/DEC задает знак (и биты четности).
EDIT Апрель 2016: Кажется, что проблема с кабиной лучше справляется с современными x86. См. Инструкция INC и ADD 1: имеет ли это значение?
Ответ 2
Вопрос о том, почему знак, когда у вас есть флаг нуля, установленный inc/dec, лучше всего решать с вопросом: скорее бы вы предпочли без опции a?
a) for (n=7;n>=0;n--) // translates to `dec + jns`
b) for (n=8;n>0;n--) // translates to `dec + jnz`
Как Ира Бакстер уже выяснено, флаг Carry используется во множестве алгоритмов - не только арифметики с несколькими точками, но и для обработки растрового изображения в монохромном /cga/EGA эпохи: Это смещает 80 пикселов шириной один пиксель вправо...
mov cx, 10
begin: lodsb
rcr al,1 // this is rotate though carry:
stosb // for the algorithm to work, carry must not be destroyed
LOOP begin //
Но тогда: почему паритет?
Я считаю, что ответ - почему нет. Этот набор инструкций - с конца 70-х, когда транзисторов было мало. Отказ в вычислении флага четности для какой-либо конкретной инструкции не имел бы никакого смысла, а просто добавил к сложности CPU.
Ответ 3
Потому что нет необходимости влиять. Этого достаточно, чтобы проверить флаг Zero. Таким образом, после инструкций inc и dec флаг переноса остается неизменным, и в некоторых случаях это полезно.