Справочник по инструкциям процессора

Вернуться на главную страницу

Содержание

Список инструкций процессора

Для ознакомления с данной статьей требуется знание регистров процессора и режимов адресации.

Список неофициальных инструкций смотри на NesDev. Некоторые из них могут быть использованы для небольшой оптимизации своего кода.

Выбери интересующую инструкцию из списка, чтобы посмотреть ее описание и примеры использования.

Раздел еще в разработке, ссылки и примеры будут добавлены постепенно. До тех пор читай, например, этот справочник.

ADC AND ASL BIT BRK CLC
CLD CLI CLV DEC DEX DEY EOR INC INX INY JMP
JSR LSR ORA PHA PHP PLA PLP ROL ROR RTI
RTS SBC SEC SED SEI

ADC (ADd with Carry)

AND (bitwise AND with accumulator)

ASL (Arithmetic Shift Left)

BCC (Branch on Carry Clear)

Условный переход на указанный (относительный) адрес при выполнении условия "C = 0".

Попытка перехода на адрес $8108 при C = 1, а затем при C = 0.

Особенности

Подробнее про относительный адрес читай в описании режима адресации Relative.

BCS (Branch on Carry Set)

Условный переход на указанный (относительный) адрес при выполнении условия "C = 1".

Попытка перехода на адрес $8108 при C = 0, а затем при C = 1.

Особенности

Подробнее про относительный адрес читай в описании режима адресации Relative.

BEQ (Branch on EQual)

Условный переход на указанный (относительный) адрес при выполнении условия "Z = 1".

Попытка перехода на адрес $8108 при Z = 0, а затем при Z = 1.

Особенности

Подробнее про относительный адрес читай в описании режима адресации Relative.

BIT (test BITs)

BMI (Branch on MInus)

Условный переход на указанный (относительный) адрес при выполнении условия "N = 1".

Попытка перехода на адрес $8108 при N = 0, а затем при N = 1.

Особенности

Подробнее про относительный адрес читай в описании режима адресации Relative.

BNE (Branch on Not Equal)

Условный переход на указанный (относительный) адрес при выполнении условия "Z = 0".

Попытка перехода на адрес $8108 при Z = 1, а затем при Z = 0.

Особенности

Подробнее про относительный адрес читай в описании режима адресации Relative.

BPL (Branch on PLus)

Условный переход на указанный (относительный) адрес при выполнении условия "N = 0".

Попытка перехода на адрес $8108 при N = 1, а затем при N = 0.

Особенности

Подробнее про относительный адрес читай в описании режима адресации Relative.

BRK (BReak)

BVC (Branch on oVerflow Clear)

Условный переход на указанный (относительный) адрес при выполнении условия "V = 0".

Попытка перехода на адрес $8108 при V = 1, а затем при V = 0.

Особенности

Подробнее про относительный адрес читай в описании режима адресации Relative.

BVS (Branch on oVerflow Set)

Условный переход на указанный (относительный) адрес при выполнении условия "V = 1".

Попытка перехода на адрес $8108 при V = 0, а затем при V = 1.

Особенности

Подробнее про относительный адрес читай в описании режима адресации Relative.

CLC (CLear Carry)

CLD (CLear Decimal)

CLI (CLear Interrupt)

CLV (CLear oVerflow)

CMP (CoMPare accumulator)

Сравнивает байт из регистра A с фиксированным байтом или с байтом из адреса.

Поочередное сравнение байта #$20 из регистра A с константой #$10, c байтом #$20 из адреса $0150 и c байтом #$30 из адреса $0140.

Особенности

Примеры использования CMP

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

Для проверки результата сравнения не рекомендуется выставлять условие на флаг N, так как по флагу N нельзя достоверно определить какой из двух байтов больше/меньше другого, если рассматривать их как Unsigned (беззнаковые).

Технически не имеет значения в каком порядке сравнивать 2 байта, если ставить правильные условия на результат сравнения. Принято сравнивать байт из адреса с фиксированным байтом, а не наоборот.

Проверка равенства

По флагу Z выясняется равенство двух байтов инструкциями BNE или BEQ. Если сравниваемые байты равны, то есть в результате вычитания получился байт #$00, тогда Z = 1, иначе Z = 0.

LDA $0120 ; загрузка в A из $0120
CMP #$09 ; сравнение A с #$09
BEQ equal ; переход при условии A = #$09
not_equal: ; выполнить нижестоящий код в случае A ≠ #$09

Проверка на равенство #$00

Выполнять инструкцию CMP #$00 для последующей проверки на флаг Z нужно лишь в том случае, если другие инструкции, выполненные до этого, могли повлиять на состояние флага Z.

LDA $0120 ; загрузка в A из $0120 (обновится Z)
LDX $0121 ; загрузка в X из $0121 (обновится Z)
LDY $0122 ; загрузка в Y из $0122 (обновится Z)
CMP #$00 ; сравнение A с #$00 (для обновления Z конкретно из A)
BEQ zero ; переход при условии A = #$00
not_zero: ; выполнить нижестоящий код в случае A ≠ #$00

В остальных случаях можно сразу проверить флаг Z.

LDA $0120 ; загрузка в A из $0120
BEQ zero ; переход при условии A = #$00
not_zero: ; выполнить нижестоящий код в случае A ≠ #$00

Все это касается и флага N. Не обязательно сравнивать регистр A с #$00, если выполнение других инструкций не обновляло состояние флага N.

Проверка на разницу

По флагу C выясняется разница в значении двух байтов инструкциями BCC или BCS. Если байт в регистре A больше или равен сравниваемому байту, тогда C = 1, иначе C = 0.

LDA $0120 ; загрузка в A из $0120
CMP #$09 ; сравнение A с #$09
BCC less ; переход при условии A < #$09
greater_or_equal: ; выполнить нижестоящий код в случае A >= #$09

Проверка на результат "больше"

Поскольку C = 1 получается как в случае "равенства", так и в случае "больше", то для проверки исключительно на результат "больше", а не "больше или равно", нужно предварительно отсеять возможное равенство двух байтов через проверку состояния флага Z.

LDA $0120 ; загрузка в A из $0120
CMP #$09 ; сравнение A с #$09
BEQ equal ; переход при условии A = #$09
BCS greater ; переход при условии A > #$09
less: ; выполнить нижестоящий код в случае A < #$09

CPX (ComPare X register)

Сравнивает байт из регистра X с фиксированным байтом или с байтом из адреса.

Поочередное сравнение байта #$20 из регистра X с константой #$10, c байтом #$20 из адреса $0150 и c байтом #$30 из адреса $0140.

Особенности

CPY (ComPare Y register)

Сравнивает байт из регистра Y с фиксированным байтом или с байтом из адреса.

Поочередное сравнение байта #$20 из регистра Y с константой #$10, c байтом #$20 из адреса $0150 и c байтом #$30 из адреса $0140.

Особенности

DEC (DECrement memory)

DEX (DEcrement X register)

DEY (DEcrement Y register)

EOR (bitwise Exclusive OR)

INC (INCrement memory)

INX (INcrement X register)

INY (INcrement Y register)

JMP (JuMP)

JSR (Jump to SubRoutine)

LDA (LoaD Accumulator)

Загружает (копирует) в регистр A фиксированный байт или байт из адреса.

Загрузка в регистр A константы #$01, байта #$02 из адреса $0050 и байта #$03 из адреса $0140.

Особенности

LDX (LoaD X register)

Загружает (копирует) в регистр X фиксированный байт или байт из адреса.

Загрузка в регистр X константы #$01, байта #$02 из адреса $0050 и байта #$03 из адреса $0140.

Особенности

LDY (LoaD Y register)

Загружает (копирует) в регистр Y фиксированный байт или байт из адреса.

Загрузка в регистр Y константы #$01, байта #$02 из адреса $0050 и байта #$03 из адреса $0140.

Особенности

LSR (Logical Shift Right)

NOP (No OPeration)

Отсутствие какой-либо операции.

Ничего не происходит.

Особенности

Примеры использования NOP

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

Затирание кода

Можно затереть лишнюю инструкцию, избавив себя от необходимости переписывать код.

00:8100: AD 20 01 LDA $0120 ; загрузка в A из $0120
00:8103: 8D 21 01 STA $0121 ; запись A в $0121
00:8106: 8D 22 01 STA $0122 ; запись A в $0122
00:8109: 8D 23 01 STA $0123 ; запись A в $0123

Удаляем в середине инструкцию STA $0122, полностью затерев ее байтами #$EA:

00:8100: AD 20 01 LDA $0120 ; загрузка в A из $0120
00:8103: 8D 21 01 STA $0121 ; запись A в $0121
00:8106: EA NOP ; нет операции
00:8107: EA NOP ; нет операции
00:8108: EA NOP ; нет операции
00:8109: 8D 23 01 STA $0123 ; запись A в $0123

Создание прыжков

Для создания прыжка инструкциями JMP или JSR требуется 3 байта. Однако если нет возможности сделать прыжок на месте инструкции, которая занимает 3 байта, перезаписываются 2 инструкции по 2 байта каждая, а оставшийся лишний байт меняется на #$EA.

00:8100: A9 01 LDA #$01 ; загрузка #$01 в A
00:8102: 85 20 STA $20 ; запись A в $0020
00:8104: 85 21 STA $21 ; запись A в $0021

Вместо инструкций STA $20 и STA $21 создаем прыжок в подпрограмму. Оставшийся байт #$21 меняем на #$EA:

00:8100: A9 01 LDA #$01 ; загрузка #$01 в A
00:8102: 20 50 81 JSR $8150 ; прыжок в подпрограмму $8150
00:8105: EA NOP ; нет операции

Если оставить байт #$21 без изменений, он будет расценен кодом как опкод инструкции AND, которая будет выполнена после того, как код вернется из подпрограммы.

ORA (bitwise OR with Accumulator)

PHA (PusH Accumulator to stack)

PHP (PusH Processor status to stack)

PLA (PuLl Accumulator from stack)

PLP (PuLl Processor status from stack)

ROL (ROtate Left)

ROR (ROtate Right)

RTI (ReTurn from Interrupt)

RTS (ReTurn from Subroutine)

SBC (SuBtract with Carry)

SEC (SEt Carry)

SED (SEt Decimal)

SEI (SEt Interrupt)

STA (STore Accumulator)

Записывает (копирует) байт из регистра A в указанный адрес.

Запись байта #$01 из регистра A в адреса $0051 и $0141.

Особенности

STX (STore X register)

Записывает (копирует) байт из регистра X в указанный адрес.

Запись байта #$01 из регистра X в адреса $0051 и $0141.

Особенности

STY (STore Y register)

Записывает (копирует) байт из регистра Y в указанный адрес.

Запись байта #$01 из регистра Y в адреса $0051 и $0141.

Особенности

TAX (Transfer Accumulator to X register)

Передает (копирует) байт из регистра A в регистр X.

Передача байта #$99 из регистра A в регистр X.

Особенности

TAY (Transfer Accumulator to Y register)

Передает (копирует) байт из регистра A в регистр Y.

Передача байта #$99 из регистра A в регистр Y.

Особенности

TSX (Transfer Stack pointer to X register)

Передает (копирует) младший байт адреса из регистра указателя стека в регистр X.

Передача байта #$76 из регистра указателя стека в регистр X.

Особенности

TXA (Transfer X register to Accumulator)

Передает (копирует) байт из регистра X в регистр A.

Передача байта #$99 из регистра X в регистр A.

Особенности

TXS (Transfer X register to Stack pointer)

Передает (копирует) байт из регистра X в младший байт адреса регистра указателя стека.

Передача байта #$FF из регистра X в регистр указателя стека.

Особенности

TYA (Transfer Y register to Accumulator)

Передает (копирует) байт из регистра Y в регистр A.

Передача байта #$99 из регистра Y в регистр A.

Особенности