| доки | ||
| тесты | ||
| disassembler_skip_zero.py | ||
| elfreader.py | ||
| kvs_build.py | ||
| kvs_builder.py | ||
| kvs_data.py | ||
| kvs_lexer.py | ||
| kvs_parser.py | ||
| kvs_pass1.py | ||
| kvs_pass2.py | ||
| kvs_pass2_encoder.py | ||
| README.html | ||
| README.md | ||
| todo.txt | ||
# КВС Ассемблер с русским синтаксисом для x86-64
**КВС** — это экспериментальный ассемблер для архитектуры x86-64, полностью использующий **русскую лексику** для мнемоник инструкций, имён регистров и директив. Проект носит образовательный характер и демонстрирует принципы работы ассемблера, построения ELF-файлов и трансляции высокоуровневых концепций в машинный код.
## 📋 Оглавление
- [Особенности](#-особенности)
- [Архитектура](#-архитектура)
- [Установка](#-установка)
- [Быстрый старт](#-быстрый-старт)
- [Синтаксис](#-синтаксис)
- [Система команд](#-система-команд)
- [Регистры](#-регистры-процессора)
- [Директивы](#-директивы-ассемблера)
- [Примеры программ](#-примеры-программ)
- [Отладка](#-отладка-и-проверка)
- [Ограничения](#-ограничения)
- [План развития](#-план-развития)
- [Лицензия](#-лицензия)
## ✨ Особенности
- **Полностью русский синтаксис** — все инструкции, регистры и директивы на кириллице
- **Генерация исполняемых ELF-файлов** — 64-битные ELF для Linux, готовые к запуску
- **Двухпроходная сборка** — традиционная схема с разрешением меток
- **Поддержка секций** — разделение на `.текст` (код) и `.данные` (данные)
- **Абсолютная адресация памяти** — чтение и запись по меткам `[переменная]` и абсолютным адресам `[0x402000]` с RIP-relative кодированием
- **CSV-логирование** — детальный файл с соответствием адресов, байтов и исходных команд
- **Более 50 инструкций** — полный набор основных команд x86-64
- **Минимализм зависимостей** — только стандартная библиотека Python
- **Рефакторинг** — кодогенерация вынесена в отдельный модуль `kvs_pass2_encoder.py`
## 🏗 Архитектура
Процесс трансляции исходного кода `.квс` в исполняемый файл `.elf` проходит через несколько этапов:
Исходный файл (.квс) │ ▼ (kvs_lexer.py) Файл токенов (.токены) │ ▼ (kvs_parser.py) AST-представление (.аст) │ ▼ (kvs_pass1.py) Первый проход: размеры, метки (.проход1) │ ▼ (kvs_pass2.py + kvs_pass2_encoder.py) Второй проход: генерация кода (.csv) │ ▼ (kvs_builder.py) ELF-компоновщик (.elf)
Исполняемый файл!
### Модули компилятора
| Файл | Назначение |
|------|------------|
| `kvs_build.py` | Главный сборочный скрипт |
| `kvs_lexer.py` | Лексический анализ, разбор на токены |
| `kvs_parser.py` | Синтаксический анализ, построение AST |
| `kvs_pass1.py` | Первый проход: вычисление размеров и адресов меток |
| `kvs_pass2.py` | Второй проход: обход AST, генерация CSV |
| `kvs_pass2_encoder.py` | Кодировщик инструкций (все encode_* функции) |
| `kvs_builder.py` | Сборка ELF-файла из CSV |
| `kvs_data.py` | Общие данные (регистры, инструкции) |
## 🔧 Установка
```bash
# Клонирование репозитория
git clone https://github.com/username/kvs.git
cd kvs
# Установка прав на выполнение (при необходимости)
chmod +x kvs_build.py
# Проверка работы
python3 kvs_build.py --help
🚀 Быстрый старт
1. Создайте файл hello.квс:
.текст
.глобал _start
_start:
; write(1, msg, 13)
переместить_имм раикс, 1
переместить_имм рдиай, 1
переместить_имм рсиай, msg
переместить_имм рдикс, 13
вызов_системы
; exit(0)
переместить_имм раикс, 60
переместить_имм рдиай, 0
вызов_системы
.данные
msg: .строка_нуль "Hello, World!"
2. Скомпилируйте:
python3 kvs_build.py hello.квс
3. Запустите:
./hello.elf
Вывод:
Hello, World!
📝 Синтаксис
Структура программы
.текст ; секция кода (обязательна)
; ... инструкции ...
.данные ; секция данных (опциональна)
; ... данные ...
Метки
Метка — это имя, за которым следует двоеточие:
_start: ; метка _start
переместить_имм раикс, 1
переход _start ; переход на метку
Комментарии
Однострочные комментарии начинаются с ;:
; Это комментарий
переместить_имм раикс, 42 ; комментарий после инструкции
Работа с памятью (абсолютная адресация)
; Запись значения в память по метке
переместить_имм раикс, 42
сохранить [переменная], раикс
; Чтение значения из памяти
загрузить рбикс, [переменная]
; Запись по абсолютному адресу
сохранить [0x402000], раикс
📖 Система команд
Загрузка констант
| Инструкция | Синтаксис | Описание |
|---|---|---|
переместить_имм |
переместить_имм рег, значение |
Загрузить константу в регистр |
переместить_имм раикс, 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 |
Короткие условные переходы (префикс короткий_):
короткий_переход_если_равно,короткий_переход_если_неравно, и т.д.- Генерируют 2-байтовые инструкции (смещение ±127 байт)
Системные вызовы
| Инструкция | Описание |
|---|---|
вызов_системы |
Вызов ядра Linux (syscall) |
; Пример: завершение программы
переместить_имм раикс, 60 ; syscall 60 = exit
переместить_имм рдиай, 0 ; код возврата 0
вызов_системы
💾 Регистры процессора
КВС поддерживает все основные 64-битные регистры x86-64:
| 64-бит | 32-бит | 16-бит | 8-бит (мл.) | 8-бит (ст.) |
|---|---|---|---|---|
раикс |
еаикс |
аикс |
ал |
аш |
рбикс |
ебикс |
бикс |
бл |
бш |
рсикс |
есикс |
сикс |
кл |
чш |
рдикс |
едикс |
дикс |
дл |
дш |
рсипи |
есипи |
эсп |
спл |
— |
рбипи |
ебипи |
бипи |
бпл |
— |
рсиай |
есиай |
эс |
сил |
— |
рдиай |
едиай |
ди |
дил |
— |
р8…р15 |
р8д…р15д |
р8в…р15в |
р8б…р15б |
— |
🔧 Директивы ассемблера
| Директива | Назначение | Пример |
|---|---|---|
.текст |
Начало секции кода | .текст |
.данные |
Начало секции данных | .данные |
.глобал |
Объявление глобальной метки | .глобал _start |
.строка |
Строка без завершающего нуля | .строка "Hello" |
.строка_нуль |
Строка с завершающим нулём | .строка_нуль "Hello" |
.байт |
Последовательность байтов | .байт 0x48, 0x65, 108 |
.константа |
Определение константы | .константа LEN = 10 |
📝 Примеры программ
Работа с памятью (переменные)
.текст
.глобал _start
_start:
; Запись значения в переменную
переместить_имм раикс, 42
сохранить [переменная], раикс
; Чтение значения из переменной
загрузить рбикс, [переменная]
; Завершение с кодом возврата
переместить_имм раикс, 60
загрузить рдиай, [переменная]
вызов_системы
.данные
переменная: .байт 0
Цикл и условный переход
.текст
.глобал _start
_start:
переместить_имм рсикс, 10 ; счетчик = 10
loop:
переместить_имм раикс, 1
переместить_имм рдиай, 1
переместить_имм рсиай, msg
переместить_имм рдикс, 10
вызов_системы
уменьшить рсикс ; счетчик--
сравнить_с рсикс, 0
переход_если_больше loop ; если > 0, продолжаем
переместить_имм раикс, 60
переместить_имм рдиай, 0
вызов_системы
.данные
msg: .строка "Iteration\n"
Вычисление суммы чисел от 1 до 10
.текст
.глобал _start
_start:
переместить_имм р8, 0 ; сумма
переместить_имм р9, 10 ; счётчик
loop:
прибавить р8, р9
уменьшить р9
сравнить_с р9, 0
переход_если_больше loop
; exit(сумма в r8)
переместить_имм раикс, 60
переместить рдикс, р8
вызов_системы
🐛 Отладка и проверка
Просмотр сгенерированного кода
# Дизассемблирование
objdump -d программа.elf
# Просмотр секций
objdump -h программа.elf
# Просмотр заголовков программы
readelf -l программа.elf
# Извлечение строк из ELF
strings программа.elf
CSV-лог
После компиляции создаётся файл программа.csv со структурой:
| адрес | байт | целевой_адрес | исходная_команда |
|---|---|---|---|
| 0x401000 | 48 | переместить_имм раикс, 1 | |
| 0x401001 | B8 | ||
| 0x401002 | 01 | ||
| ... | ... | ... | ... |
Трассировка системных вызовов
strace ./программа.elf
Отладка с GDB
gdb ./программа.elf
(gdb) break _start ; установить точку останова
(gdb) run ; запустить
(gdb) info registers ; показать регистры
(gdb) x/10i $rip ; показать 10 инструкций
(gdb) stepi ; выполнить одну инструкцию
⚠️ Ограничения
Поддерживается
- ✅ 64-битные, 32-битные, 16-битные и 8-битные регистры
- ✅ Непосредственная загрузка констант (imm) в регистры
- ✅ Сравнение регистров и регистров с константами
- ✅ Условные и безусловные переходы (длинные и короткие)
- ✅ Арифметические операции (ADD, SUB, INC, DEC)
- ✅ Логическая операция TEST
- ✅ Системные вызовы Linux (syscall)
- ✅ Секции
.тексти.данные - ✅ Строковые литералы с escape-последовательностями (
\n,\t,\\,\") - ✅ Директива
.байтдля raw-данных - ✅ Директива
.константадля имён констант - ✅ Абсолютная адресация памяти
[метка]и[число](RIP-relative)
Не поддерживается (в разработке)
- ❌ Косвенная адресация
[reg]— доступ к памяти через регистр - ❌ Адресация со смещением
[reg + disp] - ❌ Сложная адресация с индексом
[reg + reg*scale]и полная SIB-адресация - ❌ Инструкции для работы со стеком (PUSH, POP, CALL, RET) — частично
- ❌ Поддержка плавающей запятой (FPU/SSE)
- ❌ Многомодульная компиляция
- ❌ Директива
.bssдля неинициализированных данных - ❌ Макросы
📈 План развития
Реализовано (v2.0)
- Лексер с токенами
[,],NUMBER - Парсер с поддержкой операндов в квадратных скобках
- Первый проход с корректным расчётом размера инструкций с памятью
- Второй проход с кодированием абсолютной адресации через RIP-relative
- Поддержка меток в операндах памяти
[переменная] - Рефакторинг: выделение кодировщика в отдельный модуль
В планах (v3.0)
- Косвенная адресация
[reg] - Адресация со смещением
[reg + disp] - Сложная адресация с индексом
[reg + reg*scale] - Полная SIB-адресация
[reg + reg*scale + disp] - Директива
.bssдля неинициализированных данных - Поддержка инструкций PUSH/POP/CALL/RET для стековых операций
- Стандартная библиотека (
libkvs.квс): malloc, free, strlen, strcmp, print
📄 Лицензия
Только для образовательных целей. Используйте на свой страх и риск.
КВС Ассемблер | Экспериментальный проект | 2025
Только для образовательных целей. Используйте на свой страх и риск.