Ассемблер

CPI в ассемблере: что делает инструкция

CPI в ассемблере обычно означает Compare Immediate — сравнить аккумулятор с непосредственным значением. Такая инструкция встречается в i8080/Z80-подобном контексте. Она не записывает результат вычитания обратно в аккумулятор, а только выставляет флаги, по которым затем выполняют условный переход

Простая идея

Если очень коротко:

CPI 10h

означает: сравнить значение в аккумуляторе A с числом 10h. Процессор внутренне делает что-то похожее на:

A - 10h

Но A остается прежним. Меняются флаги

Какие флаги важны

После CPI обычно смотрят:

  • Z — zero flag, равны ли значения;
  • C — carry flag, был ли заем при сравнении;
  • S — sign flag, знак результата;
  • P/V или parity/overflow в зависимости от процессора;
  • вспомогательный перенос, если он есть в данной архитектуре.

Для новичка самые важные флаги — Z и C

Если A == число, флаг Z будет установлен. Если A < число в беззнаковом смысле, обычно появляется заем, и это отражается через carry

Пример с переходом

Допустим, в аккумуляторе лежит код клавиши или число:

    CPI 05h
    JZ  equal
    JC  less

Что здесь происходит:

  • CPI 05h сравнивает A с 05h;
  • JZ equal перейдет на equal, если A равно 05h;
  • JC less перейдет на less, если при сравнении был заем, то есть A меньше 05h для беззнакового сравнения.

Сам аккумулятор после CPI не меняется. Это главное отличие от реального вычитания, где результат записывается в регистр

Чем CPI отличается от CMP

В похожих архитектурах CMP часто сравнивает аккумулятор с регистром или памятью, а CPI — с числом, которое прямо записано в инструкции

Условно:

CMP B
CPI 20h

Первое сравнивает A с регистром B, второе — A с числом 20h

Как читать CPI в чужом коде

Когда видите CPI, сразу смотрите следующую инструкцию. Почти всегда после сравнения идет переход:

CPI 00h
JZ done

Это читается так: если аккумулятор равен нулю, перейти на done

Если после CPI идет несколько условных переходов, код проверяет разные варианты результата сравнения: равно, меньше, больше или не равно

Частые ошибки

Думают, что CPI меняет аккумулятор

Нет. CPI сравнивает и меняет флаги, но значение A остается

Игнорируют архитектуру

В x86 нет такой же инструкции CPI в обычном учебном смысле. Там чаще используют cmp

Не смотрят на следующий переход

CPI сам по себе только готовит флаги. Решение принимает следующая условная инструкция

Путают знаковое и беззнаковое сравнение

Для простых байтовых значений обычно думают в беззнаковом смысле, но в конкретном процессоре нужно смотреть описание флагов

Что почитать дальше по ассемблеру

Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:

Как проверить результат на практике

Для ассемблера важно сначала понять, под какую среду написан пример: DOSBox/TASM, Linux x64/NASM, Visual Studio/MASM или микроконтроллер. Один и тот же смысл может записываться разным синтаксисом, поэтому не переносите команды между средами вслепую. Создайте отдельную папку для примера, сохраните файл с расширением .asm, выполните сборку именно тем инструментом, который указан в уроке, и сравните вывод или состояние регистров с ожидаемым результатом

Если пример не собирается, читайте первую ошибку ассемблера: обычно она указывает на строку, неизвестную инструкцию, неверную метку, неправильную секцию или конфликт синтаксиса. Исправляйте одну ошибку за раз. В ассемблере это особенно важно, потому что маленькая опечатка в метке, регистре или размере операнда может полностью изменить поведение программы

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x