24 KiB
# КВС — Ассемблер с русским синтаксисом для x86-64
**КВС** — это экспериментальный ассемблер для архитектуры x86-64, полностью использующий **русскую лексику** для мнемоник инструкций, имён регистров и директив. Проект носит образовательный характер и демонстрирует принципы работы ассемблера, построения ELF-файлов и трансляции высокоуровневых концепций в машинный код.
---
## 📋 Оглавление
- [Особенности](#-особенности)
- [Архитектура](#-архитектура)
- [Установка](#-установка)
- [Быстрый старт](#-быстрый-старт)
- [Система тестирования](#-система-тестирования)
- [Синтаксис](#-синтаксис)
- [Система команд](#-система-команд)
- [Регистры](#-регистры-процессора)
- [Директивы](#-директивы-ассемблера)
- [Отладка и проверка](#-отладка-и-проверка)
- [Ограничения](#-ограничения)
- [План развития](#-план-развития)
- [Лицензия](#-лицензия)
---
## ✨ Особенности
- **Полностью русский синтаксис** — все инструкции, регистры и директивы на кириллице
- **Генерация исполняемых ELF-файлов** — 64-битные ELF для Linux, готовые к запуску
- **Шестипроходная сборка** — разделение логики на независимые этапы для прозрачности и отладки
- **Поддержка секций** — разделение на `.текст` (код), `.данные` (данные) и `.бнд` (неинициализированные данные)
- **Гибкая адресация памяти**:
- абсолютная адресация по меткам `[переменная]`
- абсолютная адресация по числовому адресу `[0x402000]`
- косвенная адресация через регистр `[раикс]`
- всё с RIP-relative кодированием для 64-битных перемещений
- **CSV-логирование** — детальный файл с соответствием адресов, байтов, меток и исходных команд
- **Более 50 инструкций** — полный набор основных команд x86-64
- **Автоматическая система регрессионного тестирования** — 9+ тестов, проверяющих все аспекты работы ассемблера
- **Минимализм зависимостей** — только стандартная библиотека Python
---
## 🏗 Архитектура
Процесс трансляции исходного кода `.квс` в исполняемый файл `.elf` проходит через **6 этапов**:
Исходный файл (.квс) │ ▼ (квс_лексер.py) ← лексический анализ Файл токенов (.токены) │ ▼ (квс_парсер.py) ← синтаксический анализ AST-представление (.аст) │ ▼ (квс_проход1.py) ← ПРОХОД 1: генерация CSV с заглушками (0xCC) CSV-файл (.csv) ← содержит все байты программы, метки, виртуальные адреса │ ▼ (квс_проход2.py) ← ПРОХОД 2: разрешение меток │ ▼ (квс_проход3.py) ← ПРОХОД 3: подстановка констант (.константа) │ ▼ (квс_проход4.py) ← ПРОХОД 4: перекодирование инструкций │ ▼ (квс_проход5.py) ← ПРОХОД 5: генерация корректных таблиц секций для совместимости с toolchain │ ▼ (квс_проход6.py) ← ПРОХОД 6: постобработка CSV для визуального анализа │ ▼ (квс_финсбор.py) ← сборка ELF из CSV ELF-файл (.elf) │ ▼ Исполняемый файл!
### Почему 6 проходов?
1. **Первый проход** — неизвестно, какие адреса будут у меток. Ставим заглушки `0xCC`.
2. **Второй проход** — после того как все адреса меток известны, заменяем заглушки.
3. **Третий проход** — константы могут ссылаться друг на друга и на метки.
4. **Четвёртый проход** — после подстановки чисел перегенерируем машинный код (разная длина инструкций).
5. **Пятый проход** — генерируем корректные таблицы секций для работы `objdump`, `readelf` и GDB.
6. **Шестой проход** — сортируем CSV для удобного визуального анализа человеком.
Такой подход позволяет **изолировать логику** каждого этапа и делает отладку прозрачной.
### Модули компилятора
| Файл | Назначение |
|------|-------------|
| `квс_сборка.py` | Главный сборочный скрипт |
| `квс_лексер.py` | Лексический анализ |
| `квс_парсер.py` | Синтаксический анализ, построение AST |
| `kvs_data.py` | Общие данные: регистры, таблица инструкций |
| `kvs_encoder.py` | Фасад кодировщика |
| `kvs_encoder_fixsize.py` | Кодировщик инструкций фиксированного размера |
| `kvs_encoder_mutsize.py` | Кодировщик инструкций переменного размера |
| `квс_проход1.py` | Генерация CSV с заглушками |
| `квс_проход2.py` | Разрешение меток |
| `квс_проход3.py` | Подстановка констант |
| `квс_проход4.py` | Перекодирование инструкций |
| `квс_проход5.py` | Генерация таблиц секций |
| `квс_проход6.py` | Сортировка CSV |
| `квс_финсбор.py` | Сборка ELF из CSV |
### Структура CSV-файла
| Колонка | Назначение |
|---------|-------------|
| `сегмент` | Имя секции (`.header`, `.text`, `.data`, `.bss`) |
| `адрес` | Файловое смещение байта |
| `виртуальный_адрес` | Виртуальный адрес байта в памяти |
| `байт` | Исходное значение байта (из pass1) |
| `приводящая_метка` | Имена меток на этом адресе |
| `уводящий_адрес` | Строка `ЗАГЛУШКА имя` для неразрешённых меток |
| `исходная_команда` | Исходная инструкция |
| `команда_со_значениями` | Инструкция с подставленными адресами/константами |
| `рассчитанный_уводящий_адрес` | Реальный адрес метки после разрешения |
| `рассчитанный_байт` | Итоговый байт после перекодирования |
---
## 🔧 Установка
```bash
# Клонирование репозитория
git clone https://github.com/artradeskz/kvs.git
cd kvs
# Установка прав на выполнение
chmod +x квс_сборка.py
# Проверка работы
python3 квс_сборка.py --help
🚀 Быстрый старт
1. Создайте файл hello.квс:
.текст
.глобал _start
_start:
; write(1, msg, 21)
переместить_имм раикс,1
переместить_имм рдиай,1
переместить_имм рсиай, msg
переместить_имм рдикс,21
вызов_системы
; exit(0)
переместить_имм раикс,60
переместить_имм рдиай,0
вызов_системы
.данные
msg: .строка "Привет мир!\n"
2. Скомпилируйте:
python3 квс_сборка.py hello.квс
3. Запустите:
./hello.elf
Вывод:
Привет мир!
🧪 Система тестирования
Проект включает автоматическую систему регрессионного тестирования, которая проверяет все аспекты работы ассемблера.
Структура тестов
тесты/
├── kvs_full_test.py # диспетчер тестов
├── kvs_full_test.csv # таблица активных тестов
├── cleaner.py # очистка артефактов
├── привет/ # тест вывода строки
│ ├── привет.квс
│ └── привет.py
├── сложный_тест/ # тест запутанных переходов
├── длин_тест/ # тест длинных переходов (jmp rel32)
├── вывод_аргумента/ # тест аргументов командной строки
├── тест_адресации_р8/ # косвенная адресация через R8
├── тест_адресации1/ # абсолютная адресация по числовому адресу
├── тест_адресации2/ # абсолютная адресация по метке
├── тест_адресации3/ # косвенная адресация через RBX
├── тест_бнд/ # проверка BSS секции (.bss)
└── ...
Запуск тестов
python3 тесты/kvs_full_test.py
Добавление нового теста
- Создать папку
тесты/имя_теста/ - Положить туда
имя_теста.квсиимя_теста.py - Добавить строку в
kvs_full_test.csv:1;имя_теста;Описание теста - Запустить
python3 тесты/kvs_full_test.py
Что проверяют тесты
| Тест | Проверяет |
|---|---|
привет |
Вывод строки на русском, exit(0) |
сложный_тест |
Короткие условные переходы |
длин_тест |
Длинные переходы (jmp rel32) |
вывод_аргумента |
Аргументы командной строки (2 сценария) |
тест_адресации_р8 |
Косвенную адресацию через R8 |
тест_адресации1 |
Абсолютную адресацию [0x402000] |
тест_адресации2 |
Абсолютную адресацию по метке |
тест_адресации3 |
Косвенную адресацию через RBX |
тест_бнд |
BSS секцию: NOBITS, размер, p_memsz |
📝 Синтаксис
Структура программы
.текст ; секция кода (обязательна)
; ... инструкции ...
.данные ; секция данных (опциональна)
; ... инициализированные данные ...
.бнд ; секция неинициализированных данных (опциональна)
; ... переменные без начального значения ...
Метки
_start: ; метка _start
переместить_имм раикс,1
переход _start ; переход на метку
Комментарии
; Это комментарий
переместить_имм раикс,42 ; комментарий после инструкции
Работа с памятью
; Запись значения в память по метке
переместить_имм раикс,42
сохранить [переменная], раикс
; Чтение значения из памяти
загрузить рбикс,[переменная]
; Запись по абсолютному адресу
сохранить [0x402000], раикс
; Косвенная адресация через регистр
переместить_имм рбикс, переменная
загрузить раикс,[рбикс]
; Работа с BND-секцией
.бнд
счётчик: .байт 0
📖 Система команд
Загрузка констант
| Инструкция | Синтаксис | Описание |
|---|---|---|
переместить_имм |
переместить_имм рег, значение |
Загрузить константу в регистр |
переместить_имм раикс,42 ; RAX = 42
переместить_имм еаикс,0x7FFF ; EAX = 32767
переместить_имм ал,0xFF ; AL = 255
Работа с памятью
| Инструкция | Синтаксис | Описание |
|---|---|---|
загрузить |
загрузить рег, [метка/адрес/регистр] |
Загрузить значение из памяти |
сохранить |
сохранить [метка/адрес/регистр], рег |
Сохранить значение в память |
загрузить раикс,[переменная] ; RAX = *переменная
сохранить [результат], раикс ; *результат = RAX
загрузить рбикс,[0x402000] ; загрузка по абсолютному адресу
загрузить раикс,[рбикс] ; косвенная загрузка через регистр
Арифметика и логика
| Инструкция | Синтаксис | Описание |
|---|---|---|
прибавить |
прибавить рег1, рег2 |
рег1 += рег2 |
вычесть |
вычесть рег1, рег2 |
рег1 -= рег2 |
увеличить |
увеличить рег |
рег++ |
уменьшить |
уменьшить рег |
рег-- |
сравнить |
сравнить рег1, рег2 |
Сравнить регистры |
сравнить_с |
сравнить_с рег, значение |
Сравнить с константой |
проверить |
проверить рег1, рег2 |
TEST (логическое AND) |
прибавить раикс, рбикс ; 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) |
; Пример: завершение программы
переместить_имм раикс,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 |
🐛 Отладка и проверка
Просмотр сгенерированного кода
# Дизассемблирование
objdump -d программа.elf
# Просмотр секций
objdump -h программа.elf
# Просмотр заголовков программы
readelf -l программа.elf
# Извлечение строк из ELF
strings программа.elf
CSV-лог
После компиляции создаётся файл программа.csv с полной информацией о каждом байте программы.
Трассировка системных вызовов
strace ./программа.elf
Отладка с GDB
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 с поддержкой языка КВС (русские инструкции, регистры, секции и директивы)
📈 План развития
Реализовано (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 Только для образовательных целей. Используйте на свой страх и риск.