648 lines
27 KiB
Markdown
648 lines
27 KiB
Markdown
```markdown
|
||
# КВС — Ассемблер с русским синтаксисом для x86-64
|
||
|
||
**КВС** — это экспериментальный ассемблер для архитектуры x86-64, полностью использующий **русскую лексику** для мнемоник инструкций, имён регистров и директив. Проект носит образовательный характер и демонстрирует принципы работы ассемблера, построения ELF-файлов и трансляции высокоуровневых концепций в машинный код.
|
||
|
||
## 📋 Оглавление
|
||
|
||
- [Особенности](#-особенности)
|
||
- [Архитектура](#-архитектура)
|
||
- [Установка](#-установка)
|
||
- [Быстрый старт](#-быстрый-старт)
|
||
- [Система тестирования](#-система-тестирования)
|
||
- [Синтаксис](#-синтаксис)
|
||
- [Система команд](#-система-команд)
|
||
- [Регистры](#-регистры-процессора)
|
||
- [Директивы](#-директивы-ассемблера)
|
||
- [Примеры программ](#-примеры-программ)
|
||
- [Отладка и проверка](#-отладка-и-проверка)
|
||
- [Ограничения](#-ограничения)
|
||
- [План развития](#-план-развития)
|
||
- [Лицензия](#-лицензия)
|
||
|
||
## ✨ Особенности
|
||
|
||
- **Полностью русский синтаксис** — все инструкции, регистры и директивы на кириллице
|
||
- **Генерация исполняемых ELF-файлов** — 64-битные ELF для Linux, готовые к запуску
|
||
- **Шестипроходная сборка** — разделение логики на независимые этапы для прозрачности и отладки
|
||
- **Поддержка секций** — разделение на `.текст` (код), `.данные` (данные) и `.бнд` (неинициализированные данные)
|
||
- **Гибкая адресация памяти**:
|
||
- абсолютная адресация по меткам `[переменная]`
|
||
- абсолютная адресация по числовому адресу `[0x402000]`
|
||
- косвенная адресация через регистр `[раикс]`
|
||
- всё с RIP-relative кодированием для 64-битных перемещений
|
||
- **CSV-логирование** — детальный файл с соответствием адресов, байтов, меток и исходных команд
|
||
- **Более 50 инструкций** — полный набор основных команд x86-64
|
||
- **Автоматическая система регрессионного тестирования** — 9+ тестов, проверяющих все аспекты работы ассемблера
|
||
- **Минимализм зависимостей** — только стандартная библиотека Python
|
||
|
||
## 🏗 Архитектура
|
||
|
||
Процесс трансляции исходного кода `.квс` в исполняемый файл `.elf` проходит через **6 этапов**:
|
||
|
||
```
|
||
Исходный файл (.квс)
|
||
│
|
||
▼ (kvs_lexer.py) ← лексический анализ
|
||
Файл токенов (.токены)
|
||
│
|
||
▼ (kvs_parser.py) ← синтаксический анализ
|
||
AST-представление (.аст)
|
||
│
|
||
▼ (kvs_pass1.py) ← ПРОХОД 1: генерация CSV с заглушками (0xCC)
|
||
CSV-файл (.csv) ← содержит все байты программы, метки, виртуальные адреса
|
||
│
|
||
▼ (kvs_pass2.py) ← ПРОХОД 2: разрешение меток
|
||
│
|
||
▼ (kvs_pass3.py) ← ПРОХОД 3: подстановка констант (.константа)
|
||
│
|
||
▼ (kvs_pass4.py) ← ПРОХОД 4: перекодирование инструкций
|
||
│
|
||
▼ (kvs_pass5.py) ← ПРОХОД 5: генерация корректных таблиц секций для совместимости с toolchain
|
||
│
|
||
▼ (kvs_pass6.py) ← ПРОХОД 6: постобработка CSV для визуального анализа
|
||
│
|
||
▼ (kvs_builder.py) ← сборка ELF из CSV
|
||
ELF-файл (.elf)
|
||
│
|
||
▼
|
||
Исполняемый файл!
|
||
```
|
||
|
||
### Почему 6 проходов?
|
||
|
||
1. **Первый проход** — неизвестно, какие адреса будут у меток. Ставим заглушки `0xCC`.
|
||
2. **Второй проход** — после того как все адреса меток известны, заменяем заглушки.
|
||
3. **Третий проход** — константы могут ссылаться друг на друга и на метки.
|
||
4. **Четвёртый проход** — после подстановки чисел перегенерируем машинный код (разная длина инструкций).
|
||
5. **Пятый проход** — генерируем корректные таблицы секций для работы `objdump`, `readelf` и GDB.
|
||
6. **Шестой проход** — сортируем CSV для удобного визуального анализа человеком.
|
||
|
||
Такой подход позволяет **изолировать логику** каждого этапа и делает отладку прозрачной.
|
||
|
||
### Модули компилятора
|
||
|
||
| Файл | Назначение |
|
||
|------|-------------|
|
||
| `kvs_build.py` | Главный сборочный скрипт |
|
||
| `kvs_lexer.py` | Лексический анализ |
|
||
| `kvs_parser.py` | Синтаксический анализ, построение AST |
|
||
| `kvs_data.py` | Общие данные: регистры, таблица инструкций |
|
||
| `kvs_encoder.py` | Фасад кодировщика |
|
||
| `kvs_encoder_fixsize.py` | Кодировщик инструкций фиксированного размера |
|
||
| `kvs_encoder_mutsize.py` | Кодировщик инструкций переменного размера |
|
||
| `kvs_pass1.py` | Генерация CSV с заглушками |
|
||
| `kvs_pass2.py` | Разрешение меток |
|
||
| `kvs_pass3.py` | Подстановка констант |
|
||
| `kvs_pass4.py` | Перекодирование инструкций |
|
||
| `kvs_pass5.py` | Генерация таблиц секций |
|
||
| `kvs_pass6.py` | Сортировка CSV |
|
||
| `kvs_builder.py` | Сборка ELF из CSV |
|
||
|
||
### Структура CSV-файла
|
||
|
||
| Колонка | Назначение |
|
||
|---------|-------------|
|
||
| `сегмент` | Имя секции (`.header`, `.text`, `.data`, `.bss`) |
|
||
| `адрес` | Файловое смещение байта |
|
||
| `виртуальный_адрес` | Виртуальный адрес байта в памяти |
|
||
| `байт` | Исходное значение байта (из pass1) |
|
||
| `приводящая_метка` | Имена меток на этом адресе |
|
||
| `уводящий_адрес` | Строка `ЗАГЛУШКА имя` для неразрешённых меток |
|
||
| `исходная_команда` | Исходная инструкция |
|
||
| `команда_со_значениями` | Инструкция с подставленными адресами/константами |
|
||
| `рассчитанный_уводящий_адрес` | Реальный адрес метки после разрешения |
|
||
| `рассчитанный_байт` | Итоговый байт после перекодирования |
|
||
|
||
## 🔧 Установка
|
||
|
||
```bash
|
||
# Клонирование репозитория
|
||
git clone https://github.com/artradeskz/kvs.git
|
||
cd kvs
|
||
|
||
# Установка прав на выполнение
|
||
chmod +x kvs_build.py
|
||
|
||
# Проверка работы
|
||
python3 kvs_build.py --help
|
||
```
|
||
|
||
## 🚀 Быстрый старт
|
||
|
||
### 1. Создайте файл `hello.квс`:
|
||
|
||
```assembly
|
||
.текст
|
||
.глобал _start
|
||
|
||
_start:
|
||
; write(1, msg, 21)
|
||
переместить_имм раикс,1
|
||
переместить_имм рдиай,1
|
||
переместить_имм рсиай, msg
|
||
переместить_имм рдикс,21
|
||
вызов_системы
|
||
|
||
; exit(0)
|
||
переместить_имм раикс,60
|
||
переместить_имм рдиай,0
|
||
вызов_системы
|
||
|
||
.данные
|
||
msg: .строка "Привет мир!\n"
|
||
```
|
||
|
||
### 2. Скомпилируйте:
|
||
|
||
```bash
|
||
python3 kvs_build.py hello.квс
|
||
```
|
||
|
||
### 3. Запустите:
|
||
|
||
```bash
|
||
./hello.elf
|
||
```
|
||
|
||
**Вывод:**
|
||
|
||
```
|
||
Привет мир!
|
||
```
|
||
|
||
## 🧪 Система тестирования
|
||
|
||
Проект включает автоматическую систему регрессионного тестирования, которая проверяет все аспекты работы ассемблера.
|
||
|
||
### Структура тестов
|
||
|
||
```
|
||
тесты/
|
||
├── kvs_full_test.py # диспетчер тестов
|
||
├── kvs_full_test.csv # таблица активных тестов
|
||
├── cleaner.py # очистка артефактов
|
||
├── привет/ # тест вывода строки
|
||
│ ├── привет.квс
|
||
│ └── привет.py
|
||
├── сложный_тест/ # тест запутанных переходов
|
||
├── длин_тест/ # тест длинных переходов (jmp rel32)
|
||
├── вывод_аргумента/ # тест аргументов командной строки
|
||
├── тест_адресации_р8/ # косвенная адресация через R8
|
||
├── тест_адресации1/ # абсолютная адресация по числовому адресу
|
||
├── тест_адресации2/ # абсолютная адресация по метке
|
||
├── тест_адресации3/ # косвенная адресация через RBX
|
||
└── тест_бнд/ # проверка BSS секции (.bss)
|
||
```
|
||
|
||
### Запуск тестов
|
||
|
||
```bash
|
||
python3 тесты/kvs_full_test.py
|
||
```
|
||
|
||
### Добавление нового теста
|
||
|
||
1. Создать папку `тесты/имя_теста/`
|
||
2. Положить туда `имя_теста.квс` и `имя_теста.py`
|
||
3. Добавить строку в `kvs_full_test.csv`:
|
||
```
|
||
1;имя_теста;Описание теста
|
||
```
|
||
4. Запустить `python3 тесты/kvs_full_test.py`
|
||
|
||
### Что проверяют тесты
|
||
|
||
| Тест | Проверяет |
|
||
|------|-----------|
|
||
| `привет` | Вывод строки на русском, exit(0) |
|
||
| `сложный_тест` | Короткие условные переходы |
|
||
| `длин_тест` | Длинные переходы (jmp rel32) |
|
||
| `вывод_аргумента` | Аргументы командной строки (2 сценария) |
|
||
| `тест_адресации_р8` | Косвенную адресацию через R8 |
|
||
| `тест_адресации1` | Абсолютную адресацию `[0x402000]` |
|
||
| `тест_адресации2` | Абсолютную адресацию по метке |
|
||
| `тест_адресации3` | Косвенную адресацию через RBX |
|
||
| `тест_бнд` | BSS секцию: NOBITS, размер, p_memsz |
|
||
|
||
## 📝 Синтаксис
|
||
|
||
### Структура программы
|
||
|
||
```assembly
|
||
.текст ; секция кода (обязательна)
|
||
; ... инструкции ...
|
||
|
||
.данные ; секция данных (опциональна)
|
||
; ... инициализированные данные ...
|
||
|
||
.бнд ; секция неинициализированных данных (опциональна)
|
||
; ... переменные без начального значения ...
|
||
```
|
||
|
||
### Метки
|
||
|
||
```assembly
|
||
_start: ; метка _start
|
||
переместить_имм раикс,1
|
||
переход _start ; переход на метку
|
||
```
|
||
|
||
### Комментарии
|
||
|
||
```assembly
|
||
; Это комментарий
|
||
переместить_имм раикс,42 ; комментарий после инструкции
|
||
```
|
||
|
||
### Работа с памятью
|
||
|
||
```assembly
|
||
; Запись значения в память по метке
|
||
переместить_имм раикс,42
|
||
сохранить [переменная], раикс
|
||
|
||
; Чтение значения из памяти
|
||
загрузить рбикс,[переменная]
|
||
|
||
; Запись по абсолютному адресу
|
||
сохранить [0x402000], раикс
|
||
|
||
; Косвенная адресация через регистр
|
||
переместить_имм рбикс, переменная
|
||
загрузить раикс, [рбикс]
|
||
|
||
; Работа с BND-секцией
|
||
.бнд
|
||
счётчик: .байт 0
|
||
```
|
||
|
||
## 📖 Система команд
|
||
|
||
### Загрузка констант
|
||
|
||
| Инструкция | Синтаксис | Описание |
|
||
|------------|-----------|----------|
|
||
| `переместить_имм` | `переместить_имм рег, значение` | Загрузить константу в регистр |
|
||
|
||
```assembly
|
||
переместить_имм раикс,42 ; RAX = 42
|
||
переместить_имм еаикс,0x7FFF ; EAX = 32767
|
||
переместить_имм ал,0xFF ; AL = 255
|
||
```
|
||
|
||
### Работа с памятью
|
||
|
||
| Инструкция | Синтаксис | Описание |
|
||
|------------|-----------|----------|
|
||
| `загрузить` | `загрузить рег, [метка/адрес/регистр]` | Загрузить значение из памяти |
|
||
| `сохранить` | `сохранить [метка/адрес/регистр], рег` | Сохранить значение в память |
|
||
|
||
```assembly
|
||
загрузить раикс,[переменная] ; RAX = *переменная
|
||
сохранить [результат], раикс ; *результат = RAX
|
||
загрузить рбикс,[0x402000] ; загрузка по абсолютному адресу
|
||
загрузить раикс,[рбикс] ; косвенная загрузка через регистр
|
||
```
|
||
|
||
### Арифметика и логика
|
||
|
||
| Инструкция | Синтаксис | Описание |
|
||
|------------|-----------|----------|
|
||
| `прибавить` | `прибавить рег1, рег2` | рег1 += рег2 |
|
||
| `вычесть` | `вычесть рег1, рег2` | рег1 -= рег2 |
|
||
| `увеличить` | `увеличить рег` | рег++ |
|
||
| `уменьшить` | `уменьшить рег` | рег-- |
|
||
| `сравнить` | `сравнить рег1, рег2` | Сравнить регистры |
|
||
| `сравнить_с` | `сравнить_с рег, значение` | Сравнить с константой |
|
||
| `проверить` | `проверить рег1, рег2` | TEST (логическое AND) |
|
||
|
||
```assembly
|
||
прибавить раикс, рбикс ; RAX += RBX
|
||
увеличить рсикс ; RCX++
|
||
сравнить раикс,10 ; сравнить RAX с 10
|
||
```
|
||
|
||
### Переходы
|
||
|
||
| Инструкция | Условие |
|
||
|------------|---------|
|
||
| `переход` | Безусловный |
|
||
| `короткий_переход` | Безусловный (смещение ±127) |
|
||
| `переход_если_равно` | ZF = 1 |
|
||
| `переход_если_неравно` | ZF = 0 |
|
||
| `переход_если_меньше` | SF ≠ OF (signed <) |
|
||
| `переход_если_больше` | ZF = 0 и SF = OF (signed >) |
|
||
| `переход_если_меньше_или_равно` | ZF = 1 или SF ≠ OF |
|
||
| `переход_если_больше_или_равно` | SF = OF |
|
||
| `переход_если_перенос` | CF = 1 |
|
||
| `переход_если_нет_переноса` | CF = 0 |
|
||
|
||
### Системные вызовы
|
||
|
||
| Инструкция | Описание |
|
||
|------------|----------|
|
||
| `вызов_системы` | Вызов ядра Linux (syscall) |
|
||
|
||
```assembly
|
||
; Пример: завершение программы
|
||
переместить_имм раикс,60 ; syscall 60 = exit
|
||
переместить_имм рдиай,0 ; код возврата 0
|
||
вызов_системы
|
||
```
|
||
|
||
## 💾 Регистры процессора
|
||
|
||
КВС поддерживает все основные 64-битные регистры x86-64:
|
||
|
||
| 64-бит | 32-бит | 16-бит | 8-бит (мл.) |
|
||
|--------|--------|--------|-------------|
|
||
| `раикс` | `еаикс` | `аикс` | `ал` |
|
||
| `рбикс` | `ебикс` | `бикс` | `бл` |
|
||
| `рсикс` | `есикс` | `сикс` | `кл` |
|
||
| `рдикс` | `едикс` | `дикс` | `дл` |
|
||
| `рсипи` | `есипи` | `эсп` | `спл` |
|
||
| `рбипи` | `ебипи` | `бипи` | `бпл` |
|
||
| `рсиай` | `есиай` | `эс` | `сил` |
|
||
| `рдиай` | `едиай` | `ди` | `дил` |
|
||
|
||
## 🔧 Директивы ассемблера
|
||
|
||
| Директива | Назначение | Пример |
|
||
|-----------|------------|--------|
|
||
| `.текст` | Начало секции кода | `.текст` |
|
||
| `.данные` | Начало секции инициализированных данных | `.данные` |
|
||
| `.бнд` | Начало секции неинициализированных данных | `.бнд` |
|
||
| `.глобал` | Объявление глобальной метки | `.глобал _start` |
|
||
| `.строка` | Строка без завершающего нуля | `.строка "Hello"` |
|
||
| `.строка_нуль` | Строка с завершающим нулём | `.строка_нуль "Hello"` |
|
||
| `.байт` | Последовательность байтов | `.байт 0x48, 0x65, 108` |
|
||
| `.константа` | Определение константы | `.константа LEN = 10` |
|
||
| `.резб` | Резервирование байтов в BND | `.резб 100` |
|
||
| `.резс` | Резервирование слов в BND | `.резс 50` |
|
||
| `.рездс` | Резервирование двойных слов в BND | `.рездс 25` |
|
||
| `.резкс` | Резервирование квадрослов в BND | `.резкс 10` |
|
||
|
||
## 📝 Примеры программ
|
||
|
||
### Работа с памятью (переменные)
|
||
|
||
```assembly
|
||
.текст
|
||
.глобал _start
|
||
|
||
_start:
|
||
переместить_имм раикс,42
|
||
сохранить [переменная], раикс
|
||
загрузить рбикс,[переменная]
|
||
переместить_имм раикс,60
|
||
загрузить рдиай,[переменная]
|
||
вызов_системы
|
||
|
||
.данные
|
||
переменная: .байт 0
|
||
```
|
||
|
||
### Цикл и условный переход
|
||
|
||
```assembly
|
||
.текст
|
||
.глобал _start
|
||
|
||
_start:
|
||
переместить_имм рсикс,10
|
||
|
||
loop:
|
||
переместить_имм раикс,1
|
||
переместить_имм рдиай,1
|
||
переместить_имм рсиай, msg
|
||
переместить_имм рдикс,10
|
||
вызов_системы
|
||
уменьшить рсикс
|
||
сравнить_с рсикс,0
|
||
переход_если_больше loop
|
||
|
||
переместить_имм раикс,60
|
||
переместить_имм рдиай,0
|
||
вызов_системы
|
||
|
||
.данные
|
||
msg: .строка "Iteration\n"
|
||
```
|
||
|
||
### Вычисление суммы чисел от 1 до 10
|
||
|
||
```assembly
|
||
.текст
|
||
.глобал _start
|
||
|
||
_start:
|
||
переместить_имм р8,0
|
||
переместить_имм р9,10
|
||
|
||
loop:
|
||
прибавить р8, р9
|
||
уменьшить р9
|
||
сравнить_с р9,0
|
||
переход_если_больше loop
|
||
|
||
переместить_имм раикс,60
|
||
переместить рдикс, р8
|
||
вызов_системы
|
||
```
|
||
|
||
### Использование BND-секции
|
||
|
||
```assembly
|
||
.текст
|
||
.глобал _start
|
||
|
||
_start:
|
||
переместить_имм раикс,0
|
||
сохранить [счётчик], раикс
|
||
переместить_имм рсикс,10
|
||
|
||
loop:
|
||
загрузить раикс,[счётчик]
|
||
увеличить раикс
|
||
сохранить [счётчик], раикс
|
||
уменьшить рсикс
|
||
сравнить_с рсикс,0
|
||
переход_если_больше loop
|
||
|
||
загрузить рдиай,[счётчик]
|
||
переместить_имм раикс,60
|
||
вызов_системы
|
||
|
||
.бнд
|
||
счётчик: .байт 0
|
||
```
|
||
|
||
### Косвенная адресация
|
||
|
||
```assembly
|
||
.текст
|
||
.глобал _start
|
||
|
||
_start:
|
||
переместить_имм рбикс, переменная
|
||
переместить_имм раикс,99
|
||
сохранить [рбикс], раикс
|
||
загрузить раикс,[рбикс]
|
||
переместить_имм рдиай, раикс
|
||
переместить_имм раикс,60
|
||
вызов_системы
|
||
|
||
.данные
|
||
переменная: .байт 0
|
||
```
|
||
|
||
### Вывод аргумента командной строки
|
||
|
||
```assembly
|
||
.текст
|
||
.глобал _start
|
||
|
||
_start:
|
||
сравнить_с рдиай, 2
|
||
переход_если_не_равно no_arg
|
||
|
||
загрузить р8, [рсиай + 8]
|
||
переместить рдиай, р8
|
||
исключающее_или рдикс, рдикс
|
||
|
||
strlen:
|
||
загрузить ал, [р8]
|
||
сравнить_с ал, 0
|
||
переход_если_равно strlen_done
|
||
увеличить р8
|
||
увеличить рдикс
|
||
переход strlen
|
||
|
||
strlen_done:
|
||
переместить_имм раикс, 1
|
||
переместить рсиай, рдиай
|
||
переместить_имм рдиай, 1
|
||
вызов_системы
|
||
исключающее_или рдиай, рдиай
|
||
переместить_имм раикс, 60
|
||
вызов_системы
|
||
|
||
no_arg:
|
||
переместить_имм раикс, 1
|
||
переместить_имм рдиай, 1
|
||
переместить_имм рсиай, msg_no_arg
|
||
переместить_имм рдикс, 26
|
||
вызов_системы
|
||
переместить_имм рдиай, 1
|
||
переместить_имм раикс, 60
|
||
вызов_системы
|
||
|
||
.данные
|
||
msg_no_arg: .строка "Ошибка не передан аргумент\n"
|
||
```
|
||
|
||
## 🐛 Отладка и проверка
|
||
|
||
### Просмотр сгенерированного кода
|
||
|
||
```bash
|
||
# Дизассемблирование
|
||
objdump -d программа.elf
|
||
|
||
# Просмотр секций
|
||
objdump -h программа.elf
|
||
|
||
# Просмотр заголовков программы
|
||
readelf -l программа.elf
|
||
|
||
# Извлечение строк из ELF
|
||
strings программа.elf
|
||
```
|
||
|
||
### CSV-лог
|
||
|
||
После компиляции создаётся файл `программа.csv` с полной информацией о каждом байте программы.
|
||
|
||
### Трассировка системных вызовов
|
||
|
||
```bash
|
||
strace ./программа.elf
|
||
```
|
||
|
||
### Отладка с GDB
|
||
|
||
```bash
|
||
gdb ./программа.elf
|
||
|
||
(gdb) break _start
|
||
(gdb) run
|
||
(gdb) info registers
|
||
(gdb) x/10i $rip
|
||
(gdb) stepi
|
||
```
|
||
|
||
## ⚠️ Ограничения
|
||
|
||
### Поддерживается
|
||
|
||
- 64-битные, 32-битные, 16-битные и 8-битные регистры (AL, BL, CL, DL)
|
||
- Непосредственная загрузка констант (imm) в регистры
|
||
- Сравнение регистров и регистров с константами
|
||
- Условные и безусловные переходы (длинные и короткие)
|
||
- Арифметические операции (ADD, SUB, INC, DEC)
|
||
- Логическая операция TEST
|
||
- Системные вызовы Linux (syscall)
|
||
- Секции `.текст`, `.данные` и `.бнд`
|
||
- Строковые литералы с escape-последовательностями (`\n`, `\t`, `\\`, `\"`)
|
||
- Директива `.байт` для raw-данных
|
||
- Директива `.константа` для имён констант
|
||
- Директивы резервирования `.резб`, `.резс`, `.рездс`, `.резкс`
|
||
- Абсолютная адресация по меткам и числовым адресам `[метка]` / `[0x402000]`
|
||
- Косвенная адресация через регистр `[раикс]`
|
||
- RIP-relative кодирование для всех видов адресации
|
||
- Полная совместимость с `objdump`, `readelf`, `gdb`
|
||
|
||
### Не поддерживается (в разработке)
|
||
|
||
- Адресация со смещением `[reg + disp]`
|
||
- Сложная адресация с индексом `[reg + reg*scale]`
|
||
- Полная SIB-адресация `[reg + reg*scale + disp]`
|
||
- Поддержка плавающей запятой (FPU/SSE)
|
||
- Многомодульная компиляция
|
||
- Макросы
|
||
|
||
## Инструменты разработчика
|
||
|
||
**Подсветка синтаксиса для VS Code** — доступно расширение [Universal Assembly Syntax Highlighting](https://github.com/artradeskz/Universal-Assembly-Syntax-Highlighting) с поддержкой языка КВС (русские инструкции, регистры, секции и директивы)
|
||
|
||
## 📈 План развития
|
||
|
||
### Реализовано (v2.0)
|
||
|
||
- Лексер с поддержкой `[]`, `+`, `-`, `*`
|
||
- Парсер с поддержкой операндов в квадратных скобках
|
||
- Шестипроходная схема сборки (включая генерацию таблиц секций и сортировку CSV)
|
||
- Поддержка меток в операндах памяти `[переменная]`
|
||
- Поддержка числовых адресов `[0x402000]`
|
||
- Поддержка косвенной адресации `[регистр]`
|
||
- Секция `.бнд` для неинициализированных данных
|
||
- Автоматическая система регрессионного тестирования (9+ тестов)
|
||
- Полная совместимость со стандартным toolchain Linux
|
||
|
||
### В планах (v3.0)
|
||
|
||
- Адресация со смещением `[reg + disp]`
|
||
- Сложная адресация с индексом `[reg + reg*scale]`
|
||
- Полная SIB-адресация `[reg + reg*scale + disp]`
|
||
- Стандартная библиотека (`libkvs.квс`): malloc, free, strlen, strcmp, print
|
||
|
||
## 📄 Лицензия
|
||
|
||
Только для образовательных целей. Используйте на свой страх и риск.
|
||
|
||
---
|
||
*КВС Ассемблер | Экспериментальный проект | 2026*
|
||
*Только для образовательных целей. Используйте на свой страх и риск.*
|
||
```
|