Седов Иван Алексеевич
Рязанский политехнический колледж
ASSEMBLER 8-bit SIMULATOR
Занятие #2: документация и команды
(эмулятора) языка ассемблер

https://e1m7.github.io/work/
В данной версии ассемблера представлен упрощенный синтаксис на основе NASM (процессоры INTEL x86). Эмулятор состоит из 8-битного процессора и 256 байт оперативной памяти. Весь код, данные и стек должны уместиться в 256 байт. Каждая инструкция и/или операнд занимают в памяти 1 байт. Из-за этого, например, команда MOV всегда будет занимать 3 байта.
"Последняя" память с 0xE8 по 0xFF (24 байта) отображается на экране в специальном месте, каждое значение, записанное в этот промежуток, будет отображено (65 как A, 48 как 0, 20 как пробел и проч.)

Синтаксис аналогичен большинству ассемблеров: каждая инструкция пишется на отдельной строке, метки не обязательны и должны начинаться либо с точки либо с прописной буквы
В программе можно использовать разные системы счисления для чисел: 200 (10-тичная), 200d (10-тичная), 0x1A (16-ричная), 0o30 (8-ричная), 101b (двоичная). С помощью инструкции DB можно определить число или строку.
[метка:] инструкция [операнды] [; Комментарий] start: MOV A, 10 ; ok
.start: MOV B, 10 ; ok
_start: MOV C, 10 ; errorОперанды команд могут быть одним из 4 регистров общего назначения (A, B, C, D), регистром SP (указатель стека), адресом памяти или константой. SP может использоваться только в MOV, ADD, SUM, CMP, INC и DEC. Любая метка внутри команды будет заменена адресом.
- Регистры общего назначения (GP): A, B, C, D
- Регистр указателя стека: SP
- Адрес (с использованием GP): [A]
- Адрес (с GP и смещением): [A+3]
- Адрес (с SP и смещением): [SP-3]
- Адрес с константой: [100]
- Адрес с меткой message: message
- Константа: любое число 0-255 (8 бит = 1 байт без знака)*
- Смещение для косвенной адресации: от -16 до +15
*Еще раз: мы работаем с положительными числами! Всегда!
JMP start
start:
MOV [232], 'H'
MOV [233], 'e'
MOV [234], 'l'
MOV [235], 'l'
MOV [236], 'o'
MOV [237], ' '
MOV [238], 'W'
MOV [239], 'o'
MOV [240], 'r'
MOV [241], 'l'
MOV [242], 'd'
MOV [243], '!'
HLTПрограмма Hello World!
ВСЕ КОМАНДЫ*
Команда MOV копирует значение из SRC (источник) в DEST (приемник), единственная инструкция, которая может напрямую изменить память.
MOV reg, reg
MOV red, address
MOV reg, constant
MOV address, reg
MOV address, constant*данного эмулятора, который примерно равен реальному на 99%
MOV A, B равно A=B
Замечание: вместо оператора MOV для присвоения данных можно использовать стек, например MOV A, 10 аналогично двум командам 1) PUSH 10 (положить в стек 10), 2) POP A (достать из стека 10 и положить в А).
Константа DB определяет число, символ или строку.
JMP start
val1: DB 100
val2: DB 'A'
val3: DB "Hello World"
start:
MOV A, val1 ; A=?
MOV B, val2 ; B=?
MOV C, val3 ; C=?
HLTСложение и вычитание складывает два числа и вычитает второе из первого, операции (возможно) изменяют флаг переноса (C) и флаг нуля (Z). Результат приходит в первый операнд (регистр).
- FLAG C = 1, если A=3, B=5, A-B=-2 < 0 (ответ A=0xFD)
- FLAG C = 1, если A=250, B=10, A+B=260 > 255 (ответ A=0x04)
- FLAG Z = 1, если A=10, B=10, A-B=0 (ответ A=0x00)
ADD reg, reg
ADD reg, address
ADD reg, constant
SUB reg, reg
SUB reg, address
SUB reg, constant JMP start
val: DB 3
start:
MOV A, 9
SUB A, val ; A=?
MOV A, 8
MOV B, val
SUB A, [B] ; A=?
MOV A, 12
MOV B, 11
SUB A, B ; A=?
HLTЗадача 1

JMP start
val: DB 3
start:
MOV A, 9
SUB A, val ; A=07
MOV A, 8
MOV B, val
SUB A, [B] ; A=05
MOV A, 12
MOV B, 11
SUB A, B ; A=01
HLTЗадача 1 (решение)
Увеличение и уменьшение +1 или -1 к операнду, операции меняют флаги C|Z, регистр SP может использоваться как операнд.
JMP start
start:
MOV A, 10 ;
MOV B, 10 ;
INC A ;
DEC B ;
MOV A, 2 ;
DEC A ;
DEC A ;
DEC A ;
HLTУмножение и деление делят значение регистра A* на заданное значение (второй операнд), операции меняют флаги C|Z
MUL reg
MUL address
MUL constant
DIV reg
DIV address
DIV constant JMP start
start:
MOV A, 20 ;
MOV B, 2 ;
DIV B ;
MOV A, 20 ;
MOV B, 3 ;
DIV B ;
MOV A, 1 ;
MOV B, 2 ;
DIV B ;
HLT*Нельзя разделить, например, B/C. Первое число всегда в А!
Логические операции AND, OR, XOR, NOT меняют флаги C|F

AND (и): папа счастлив если набухался и подрался
OR (или): папа счастлив, если набухался или подрался
XOR (исключающее или): папа счастлив если набухался или подрался, но только что-то одно из списка
AND reg, reg
AND reg, address
AND reg, constant
OR reg, reg
OR reg, address
OR reg, constant
XOR reg, reg
XOR reg, address
XOR reg, constant
NOT reg JMP start
start:
MOV A, 1b ;
MOV B, 1b ;
AND A, B ;
OR A, B ;
XOR A, B ;
HLTОперации сдвига SHL/SAL (левый) и SHR/SAR (правый) поддерживаются, но так как эмулятор поддерживает только положительные числа SHR|SAR дают одинаковый результат, операции меняют флага C|F
SHL reg, reg
SHL reg, address
SHL reg, constant
SHR reg, reg
SHR reg, address
SHR reg, constant JMP start
start:
MOV A, 00000001b ; A=00000001 (1)
MOV B, 3 ; B=00000011 (3)
; Сдвиг влево
SHL A, B ; A=00001000 (8)
HLT JMP start
start:
MOV A, 01000000b ; A=010000000 (64)
MOV B, 2 ; B=000000010 (2)
; Сдвиг вправо
SHR A, B ; A=000100000 (10)
HLT JMP start
start:
MOV A, 10 ;
MOV B, 1 ;
SHL A, B ; A=?
MOV A, 4 ;
MOV B, 1 ;
SHL A, B ; A=?
MOV A, 100 ;
MOV B, 1 ;
SHL A, B ; A=?
HLT
Задача 2

JMP start
start:
MOV A, 10 ;
MOV B, 1 ;
SHL A, B ; A=20
MOV A, 4 ;
MOV B, 1 ;
SHL A, B ; A=8
MOV A, 100 ;
MOV B, 1 ;
SHL A, B ; A=200
HLT
Замечание: сдвиг влево на 1 это умножение числа на 2, сдвиг вправо на 1 это деление числа на 2. Это, кстати, быстрее и по коду и по времени выполнения.
Команда CMP сравнивает два значения и после нее можно анализировать сравнение (=, >, <, >=, <=, !=). Регистр SP может быть операндом, команда используется перед условным переходом.
CMP reg, reg
CMP reg, address
CMP reg, constantКоманда JMP (безусловный прыжок) делает переход без проверок по заданному адресу
JMP addressJC label ; если было переполнение
JNC label ; если не было переполнения
JZ label ; если был ноль
JNZ label ; если не было нуля
JA label ; если больше
JB label ; если меньше
JE label ; если равно 0
JNE label ; если не равно нулюПолная версия всех команд по ссылке
clck.ru/We7RN
Команда CALL вызов функции, происходит сохранение адреса следующей команды в стек и переход по адресу функции
Команда RET выходит из подпрограммы (функции), возвращает из стека адрес следующей команды, сохраненный ранее командой CALL. Если в функции использовался регистр SP, то его надо восстановить, иначе переход будет поврежден.
Команда PUSH поместит в стек значение, указатель SP уменьшится (будет равен следующей свободной ячейке)
PUSH reg
PUSH address
PUSH constantКоманда POP извлекает значение из стека, регистр SP увеличивается
Команда HLT останавливает работу процессора, рекомендуется нажать "Сброс", чтобы обнулить регистр IP
POP regHLT
assembler8_02
By Ivan Sedov
assembler8_02
- 809