640 подписчиков

Ассемблер для чайников (Z80) часть 2

133 прочитали

Для того, чтобы полностью понять что тут написано, прочтите первую часть статьи.

Для того, чтобы полностью понять что тут написано, прочтите первую часть статьи.
Передача данных
LD <аргумент1>, (<аргумент2>)
LD (<аргумент1>), <аргумент2>

Передача данных

LD <аргумент1>, (<аргумент2>)

LD (<аргумент1>), <аргумент2>

LD <аргумент1>, <аргумент2>

LD «load» - это оператор для переноса значения из одного места в другое.

<аргумент1> - это пункт назначения. (Это может быть двойной / одиночный регистр или 8/16 битное значение)

<аргумент2> является источником. (Это может быть двойной / одиночный регистр или 8/16 битное значение).
Скобки указывают, что аргумент является 16-битным указателем памяти, где значение выбирается / помещается (вместо прямого значения или пары регистрации)

LDD

Передает 8-битное значение из источника (HL) в пункт назначения (DE) с уменьшением адресов и счетчика (BC)

LDDR

«LDD with Repeat» Передает блок памяти, выполняя LDD, пока счетчик не достигнет 0

LDI

Передает 8-битное значение из источника (HL) в пункт назначения (DE) с увеличением адресов и уменьшением счетчика (BC)

LDIR

«LDI with Repeat» Передает блок памяти, выполняя LDI, пока счетчик не достигнет 0

Регистрация биржи

EX <operand1>, <operand2>

EX (<operand1>), <operand2>

Обмен значениями двух операндов.

EXX

Обменивает значения DE, HL и BC со вспомогательными регистрами.

Арифметические операции

ADC <operand>

Добавьте Аккумулятор с операндом и битом Carry. (A = A + <операнд> + Carry)

ADD <operand>

Добавktybt аккумулятор с операндом. (A = A + <operand>)

DAA

«Десятичная настройка накопителя» Настраивает каждую четверть накопителя на десятичную дробь.

DEC <operand>

Уменьшить содержимое реестра. (<operand>= <operand>- 1)
Если операнд является двойным регистром, операция не изменяет флаги (регистр F).

DEC (<operand>)

Уменьшить содержимое памяти, указанной регистром.

INC <operand>

Увеличить содержимое регистра. (<operand> = <operand> + 1)
Если операнд является двойным регистром, операция не изменяет флаги (регистр F).

INC (<operand>)

Увеличение содержимого памяти, указанного регистром.

NEG

«Negative». Вычтите ноль из содержимого Аккумулятора, затем поместите результат в Аккумулятор. (А = -А)

SBC

Вычтите Аккумулятор с операндом и битом Carry. (A = A - <operand> - Carry

SUB <operand>

Вычтите Аккумулятор с операндом. (A = A - <operand>)

SUB (<operand>)

Вычтите содержимое памяти, указанное регистром.

Логические операции

AND <operand>

Логическая операция: A = A and <operand>.

AND (<operand>)

Логическая операция: A = A and (<operand>).

CPL

«Complement» инвертирует все биты A (= NOT)

OR <operand>

Логическая операция: A = A or <operand>.

OR (<operand>)

Логическая операция: A = A or (<operand>).

XOR <operand>

Логическая операция: A = A xor<operand>.

XOR (<operand>)

Логическая операция: A = A xor (<operand>).

Обработка бит (ы)

CCF

Изменяет статус бита переноса (в регистре F).

RES <номер бита>, <operand>

RES <номер бита>, (<operand>)

Reset (= make 0) бит операнда.

RL <operand>

«Повернуть влево» Биты переноса и операнда смещены влево при вращении.

RLA

Быстрая версия "RL A". Несущие и аккумуляторные биты смещены влево с вращением.

RR <operand>

«Повернуть вправо» Биты переноса и операнда сдвигаются вправо с вращением.

RRA

Быстрая версия "RR A". Несущие и аккумуляторные биты сдвигаются вправо с вращением.

RLC <operand>

«Повернуть влево с переносом» Биты операнда сдвигаются влево с вращением на себе. Carry получает статус наиболее значимого бита из операнда.

RLCA

Быстрая версия "RLC A". Аккумуляторные биты сдвинуты влево с вращением на себя. Carry получает статус наиболее значимого бита из Аккумулятора.

RRC <operand>

«Повернуть вправо с переносом» Биты операнда сдвигаются вправо с вращением на себя. Carry принимает статус наименее значимого бита из операнда.

RRCA

Быстрая версия "RRC A". Аккумуляторные биты сдвинуты вправо с вращением на себя. Carry принимает статус наименее значимого бита из Аккумулятора.

SCF

«Set Carry Flag» Устанавливает бит переноса (в регистре F).

SET <номер бита>, <operand>

SET <номер бита>, (<operand>)

Устанавливает (= Make 1) бит операнда.

SLA <operand>

Биты операнда сдвинуты влево. Наименее значимый бит сбрасывается. Carry получает статус наиболее значимого бита из операнда.

RLD

4 младших бита Аккумулятора и все (HL) будут смещены на 4 бита влево с вращением. 4 самых значимых бита Аккумулятора останутся как есть.

SRA <operand>

Биты операнда сдвинуты вправо. Наиболее значимым битом остается его статус. Carry принимает статус наименее значимого бита из операнда.

SRL

Биты Carry и Accumulator смещены вправо. Наиболее значимый бит сбрасывается. Carry принимает статус наименее значимого бита из операнда.

RRD

4 младших бита Аккумулятора и все (HL) будут сдвинуты на 4 бита вправо с вращением. 4 самых значимых бита Аккумулятора останутся как есть.

Сравнение данных и проверка битов

BIT <номер бита>, <operand>

BIT <номер бита>, (<operand>)

Проверяет, бит операнда сброшен или нет. Скобки указывают, что это содержимое памяти, указанное адресом указанного регистра.
(Флаг Z устанавливается, если бит сброшен.)

CP <argument>

«Compare» Вычитает аргумент с A, но не сохраняет результат. (Z-флаг устанавливается, если то же самое, C-флаг устанавливается, если аргумент больше, чем A)

CPD

Сравнение байта из памяти с A. Затем регистры B (счетчик) и HL (указатель) уменьшаются.

CPDR

Повторное сравнение байта из памяти с A. Регистр B (счетчик) и HL (указатель) уменьшаются до тех пор, пока A = (HL) или B не станет равным нулю.

CPI

Сравнение байта из памяти с A. Затем регистр B (счетчик) уменьшается, а HL (указатель) увеличивается.

CPIR

Повторное сравнение байта из памяти с A. Регистр B (счетчик) уменьшается, а HL (указатель) увеличивается до тех пор, пока A = (HL) или B не станет равным нулю.

Прыжки, стек, подпрограммы

CALL <address>

Вставляет адрес возврата в стек и переходит на указанный адрес.

CALL <condition> <address>

Выдвигает адрес возврата в стек и переходит к указанному адресу в случае названного условия.

DJNZ <distance>

«Dec b and Jump if Not Zero». Обычно используется для выполнения типа «Loop» (назад) или «case» (вперед).

JP <address>

Перейти на указанный адрес.

JP <condition> <address>

Перейти на адрес в случае названного условия.

JP (<registerpair>)

Перейти по адресу в реестре. (Обратите внимание на логическую ошибку в синтаксисе!)

JR <distance>

Относительный прыжок. Может перейти к адресу от -126 до +129 байт дальше, чем текущий адрес.

JR <condition>, <distance>

Относительный скачок в случае названного состояния.

PUSH <registerpair>

Сохраняет регистровую пару на вершине стека и уменьшает SP на 2

POP <registerpair>

Загружает регистровую пару с вершины стека, увеличивая SP на 2.

RET

Возобновить выполнение после последнего выполненного вызова. (= "POP PC")

RST <address>

«Reset» или «Программное прерывание». Работает как CALL, но меньше и быстрее и работает только с 1 из 8 фиксированных адресов: 0, 8, 10, 18, 20, 28, 30 или 38.

Ввод / вывод данных

Избегайте использования его заявлений на MSX. Только некоторые порты являются стандартными, и вы должны обратить внимание на время. Используйте BIOS, соответствующий аппаратному обеспечению, чтобы как можно больше использовать таблицу переходов.

IN A, (<порт>)

Прочитайте указанный порт.

IND

Чтение указанного порта с помощью C и сохранение значения в памяти. Регистр B (счетчик) и HL (указатель) уменьшаются.

INDR

Повторное чтение указанного порта C с сохранением данных в памяти. Регистр B (счетчик) и HL (указатель) уменьшаются до тех пор, пока B не будет сброшен.

INI

Чтение указанного порта с помощью C и сохранение значения в памяти. Регистр B (счетчик) уменьшается, а HL (указатель) увеличивается.

INIR

Повторное чтение указанного порта C с сохранением данных в памяти. Регистр B (счетчик) уменьшается, а HL (указатель) увеличивается до тех пор, пока B не будет сброшен.

OUT (<порт>), A

Отправьте байт на указанный порт.

OUTD

Отправьте байт из памяти на указанный порт с помощью C. Затем регистр B (счетчик) и HL (указатель) уменьшаются.

OTDR

Отправьте серию байтов на указанный порт с помощью C. Регистр B (счетчик) и HL (указатель) уменьшаются до тех пор, пока не будет сброшен B.

OUTI

Отправьте байт из памяти на указанный порт с помощью C. Затем регистр B (счетчик) уменьшается, а HL (указатель) увеличивается.

OTIR

Отправьте серию байтов на указанный порт с помощью C. Регистр B (счетчик) уменьшается, а HL (указатель) увеличивается до тех пор, пока не будет сброшен B.

Перерывы и время ожидания

Процессор получает сигналы прерывания от других устройств. Приведенные ниже утверждения позволяют вам управлять ими. Например, VDP посылает сигнал в конце каждого экрана (50 или 60 раз в секунду). При каждом прерывании CPU выполняет RST 38.

DI

«Отключить прерывания» (прерывания отключаются сразу после выполнения DI.)

EI

«Включить прерывания» (прерывания восстанавливаются после выполнения следующего оператора.)

HALT

Ожидание до следующего прерывания.

IM0

Режим прерывания 0.

IM1

Режим прерывания 1. Режим, используемый MSX.

IM2

Режим прерывания 2.

RETI

Возобновить выполнение после процедуры прерывания в режиме 2.

RETN

Возобновить выполнение после немаскируемой подпрограммы прерывания. (не используется в MSX)

NOP

Подождите 4 T состояния.

Метки

Метки - это символическое имя (символ) для процедуры или значения. Метка определяет постоянный адрес или значение. Установка метки состоит в том, чтобы поместить имя по вашему выбору в начале строки, за которым следует двоеточие. Двоеточие необязательно во многих ассемблерах.

Значение символа будет адресом позиции метки при сборке, если за ним не следует оператор EQU, в этом случае значение будет тем, которое указано в качестве аргумента EQU.

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

Многие ассемблеры чувствительны к регистру меток.

Ассемблеры для старой машины поддерживают короткие метки только для сохранения памяти. Это относится к GEN80 по умолчанию, но вы можете добавить оператор * S 14 в начале вашей программы для поддержки меток длиной до 14 символов. Конечно, вы можете заменить 14 другим значением, когда это необходимо.

Ошибка возникает с несколькими ассемблерами, когда в операторе EQU используется двоеточие.

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

Формат программы

Программа на ассемблере - это простой текстовый файл, который должен быть собран для получения исполняемого файла.

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

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

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

Значения

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

1010000b =% 1010000 = 120o = o120 = 80 = 50h = $ 50 = 'P' = "P"

Если вы используете обозначение с H для шестнадцатеричного числа, необходимо поставить цифру впереди. Поэтому, если значение начинается с буквы (от A до F), поставьте ноль впереди, иначе оно будет принято за метку.

11111111b =% 11111111 = 377o = o377 = 255 = $ FF = 0FFh

Некоторые ассемблеры поддерживают формат значений, как в языке C.

0b11111111 = 0o377 = 255 = 0xFF

Основные выражения

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

Выражения, которые мы можем использовать: + , - , * , / для сложения, вычитания, умножения и деления. Логические выражения & , | , ^ для операций И, Или и Xor.

Данные

Следующие утверждения могут быть использованы для вставки данных.

defb или db для ввода 8-битных значений или символов.
defw или dw для ввода 16-битных значений.
Defs или DS, чтобы зарезервировать область. Первое значение - это длина, второе - это значение для заполнения области. По умолчанию область будет заполнена нулями или 255.

Примечание. Каждое значение должно быть разделено запятой. Символы должны быть строкой в ​​кавычках или апострофом.

Это все?

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

Теперь главное для вас - найти подходящий ассемблер для ваших нужд. Я советую вам кросс-ассемблер. Это ассемблер, способный собрать машинный код для Z80 с современным ПК. Это упростит задачу.