Ассемблер
JP в ассемблере: как работает переход
JP в ассемблере обычно означает jump — перейти по адресу. В Z80-подобном коде JP может быть безусловным или условным. Безусловный переход всегда меняет адрес выполнения, а условный смотрит на флаги процессора: например, равенство, неравенство, перенос или знак
Безусловный JP
Простой пример:
JP start
Это значит: продолжить выполнение с метки start. Процессор меняет счетчик команд, и следующая инструкция берется уже из нового места
Такой переход похож на goto в языках высокого уровня. Он не проверяет условие, не сравнивает значения и не меняет сам по себе флаги. Он просто переносит выполнение
Условный JP
Часто JP используется после сравнения:
CP 10h
JP Z, equal
JP NZ, not_equal
Здесь CP 10h сравнивает аккумулятор с числом 10h и выставляет флаги. Затем:
JP Z, equalпереходит, если установлен zero flag;JP NZ, not_equalпереходит, если zero flag не установлен.
То есть JP не делает сравнение сам. Он только смотрит на состояние флагов, которые выставила предыдущая инструкция
Популярные условия
В Z80-подобной записи часто встречаются:
JP Z, label ; если равно
JP NZ, label ; если не равно
JP C, label ; если carry установлен
JP NC, label ; если carry не установлен
JP M, label ; если знак минус
JP P, label ; если знак плюс
Названия условий зависят от процессора и ассемблера, поэтому в учебном задании всегда сверяйтесь с конкретной архитектурой
Чем JP отличается от JR
В Z80 есть и JP, и JR. Упрощенно:
JPобычно делает переход по полному адресу;JRделает относительный переход на небольшое расстояние вперед или назад.
Для новичка главное различие такое: JP удобен для перехода почти куда угодно, JR часто компактнее, но ограничен диапазоном
Пример цикла через JP
LD B, 05h
loop:
DEC B
JP NZ, loop
Что происходит:
- в
Bкладется 5; DEC Bуменьшает счетчик;- если после уменьшения счетчик не ноль,
JP NZ, loopвозвращает выполнение к меткеloop; - когда
Bстановится нулем, переход не выполняется.
Так строится простой цикл
Как читать JP в чужом коде
Смотрите на две вещи:
- Есть ли условие после
JP. - Какая инструкция перед ним выставила флаги.
Если написано просто JP label, это безусловный переход. Если написано JP Z, label, переход зависит от zero flag. Почти всегда рядом выше будет CP, CPI, DEC, INC или другая инструкция, которая изменила флаги
Частые ошибки
Думают, что JP сравнивает значения
Нет. Сравнение делает другая инструкция. JP только переходит
Забывают, кто выставил флаги
Если между сравнением и JP вставить инструкцию, которая меняет флаги, условие может сработать не так
Путают JP и CALL
JP просто переходит. CALL вызывает подпрограмму и сохраняет адрес возврата
Переносят JP в x86-код
В x86 используются другие мнемоники: jmp, je, jne, jc и так далее
Что почитать дальше по ассемблеру
Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:
- CMP в ассемблере: как работает сравнение
- Как работает CMP в ассемблере
- Как работает DIV в ассемблере
- Как работает MUL в ассемблере