Почему инструкции INC и DEC *не * влияют на флаг переноса (CF)?

почему инструкция x86 INC (инкремент) и DEC (уменьшение) не влияет на CF (нести флаг) в FLAGSREGISTER?

4 ответов


чтобы понять, почему вам, вероятно, нужно помнить, что текущие процессоры "x86" с 32 и 64 битными значениями начали жизнь как гораздо более ограниченные 8-битные машины, возвращаясь к Intel 8008. (Я кодировал в этом мире еще в 1973 году, я все еще помню (Тьфу) это!).

в том мире регистры были драгоценны и малы. Вам нужно INC/DEC для различных целей, чаще всего контура управления. Многие циклы, связанные с выполнением " многоточной арифметики "(e.g, 16 бит или больше!) По имея INC/DEC установить флаг нуля (Z), вы можете использовать их для управления циклами довольно красиво; настаивая на том, чтобы инструкции по управлению циклом не меняли флаг переноса (CF), перенос сохраняется через итерации цикла, и вы можете реализовать операции multiprecision без написания тонны кода для запоминания состояния переноса.

это сработало довольно хорошо, как только вы привыкли к уродливому набору инструкций.

на более современных машинах с больших размеров, вам не нужно это много, так что INC и DEC может быть семантически эквивалентно ADD ..., 1 etc. Это на самом деле то, что я использую, когда мне нужен набор для переноски :-}

в основном, я держусь подальше от INC и DEC теперь, потому что они делают частичные обновления кода условия, и это может вызвать смешные киоски в конвейере, и ADD/SUB не надо. Поэтому, где это не имеет значения (в большинстве мест), я использую ADD/SUB чтобы избежать палатках. Я использую INC/DEC только когда сохранение кода имеет небольшое значение, например, вписывание в строку кэша, где размер одной или двух инструкций имеет значение. Это, вероятно, бессмысленно nano[буквально!]- оптимизация, но я довольно старая школа в своих привычках кодирования.

мое объяснение говорит нам, почему INC/DEC установить флаг нуля (Z). У меня нет особенно убедительного объяснения, почему INC/DEC установите знак (и флаг четности).

редактировать апрель 2016: кажется что проблема стойла лучше обрабатывается на современных x86s. См.инструкция INC против ADD 1: имеет ли это значение?


вопрос почему знак когда вы ноль флаг, установленный 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`

As Ира Бакстер уже выяснено, флаг переноса используется во многих алгоритмах-не только арифметика многозначности, но и для обработки растровых изображений в монохромной/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.


  1. инструкции inc и dec обычно используются для поддержания количества итераций или циклов. Используя 32 бита, число итераций может достигать 4 294 967 295. Это число достаточно велико для большинства приложений. Что, если нам нужен счет, который больше этого? Мы должны использовать add вместо inc? Это приводит ко второй и главной причине.

  2. условие обнаруженное флагом носит может также быть обнаружен нулевым флагом. Почему? Потому что inc и dec меняют число только на 1. Например, предположим, что регистр ECX достиг своего максимального значения 4,294,967,295 (FFFFFFFFH). Если мы тогда выполняем

                     inc ECX
    

    обычно мы ожидаем, что флаг переноса будет установлен на 1. Однако мы можем обнаружить это условие, отметив, что ECX = 0, который устанавливает нулевой флаг. Таким образом, установка флага переноса действительно избыточна для этих инструкций.


потому что нет необходимости влиять. Вполне достаточно проверить нулевой флаг. Таким образом, после инструкций inc и dec флаг переноса остается тем же, и в некоторых случаях это полезно.