ассемблер для архитектуры x86-64, полностью использующий русскую лексику
Find a file
2026-06-09 22:43:10 +03:00
доки пересборка 2026-05-02 23:04:46 +03:00
инструменты адресация в bss 2026-05-25 20:36:43 +03:00
тесты добавлена система тестирования 2026-06-09 22:43:10 +03:00
.gitignore обновить todo 2026-05-17 12:52:29 +03:00
AGENTS.md обновить ридми 2026-05-23 16:30:12 +03:00
kvs_build.py добавить сортировщик для таблицы 2026-06-07 16:26:54 +03:00
kvs_builder.py убрать харкод в 4м проходе 2026-05-23 21:14:49 +03:00
kvs_data.py рефакторинг общих данных 2026-05-23 20:30:15 +03:00
kvs_encoder.py однотабличная сборка_ 2026-05-23 08:58:10 +03:00
kvs_encoder_fixsize.py однотабличная сборка 2026-05-23 08:52:52 +03:00
kvs_encoder_mutsize.py однотабличная сборка 2026-05-23 08:52:52 +03:00
kvs_lexer.py кодировщик инструкций фиксированного размера 2026-05-17 12:21:28 +03:00
kvs_parser.py косвенная адресация 2026-05-17 15:18:35 +03:00
kvs_pass1.py починить бнд и учесть длину коментария 2026-06-07 15:55:19 +03:00
kvs_pass2.py упростить рассчет смещений 2026-05-23 18:56:43 +03:00
kvs_pass3.py однотабличная сборка 2026-05-23 08:52:52 +03:00
kvs_pass4.py маркеры секций 2026-05-25 18:19:13 +03:00
kvs_pass5.py починить бнд и учесть длину коментария 2026-06-07 15:55:19 +03:00
kvs_pass6.py добавить сортировщик для таблицы 2026-06-07 16:26:54 +03:00
README.md добавлена система тестирования 2026-06-09 22:43:10 +03:00
todo.txt вывод аргумента 2026-06-07 22:59:34 +03:00

# КВС — Ассемблер с русским синтаксисом для 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.квс:

.текст
.глобал _start

_start:
    ; write(1, msg, 21)
    переместить_имм раикс,1
    переместить_имм рдиай,1
    переместить_имм рсиай, msg
    переместить_имм рдикс,21
    вызов_системы

    ; exit(0)
    переместить_имм раикс,60
    переместить_имм рдиай,0
    вызов_системы

.данные
msg: .строка "Привет мир!\n"

2. Скомпилируйте:

python3 kvs_build.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

Добавление нового теста

  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

📝 Синтаксис

Структура программы

.текст          ; секция кода (обязательна)
    ; ... инструкции ...

.данные         ; секция данных (опциональна)
    ; ... инициализированные данные ...

.бнд            ; секция неинициализированных данных (опциональна)
    ; ... переменные без начального значения ...

Метки

_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

📝 Примеры программ

Работа с памятью (переменные)

.текст
.глобал _start

_start:
    переместить_имм раикс,42
    сохранить [переменная], раикс
    загрузить рбикс,[переменная]
    переместить_имм раикс,60
    загрузить рдиай,[переменная]
    вызов_системы

.данные
переменная: .байт 0

Цикл и условный переход

.текст
.глобал _start

_start:
    переместить_имм рсикс,10

loop:
    переместить_имм раикс,1
    переместить_имм рдиай,1
    переместить_имм рсиай, msg
    переместить_имм рдикс,10
    вызов_системы
    уменьшить рсикс
    сравнить_с рсикс,0
    переход_если_больше loop

    переместить_имм раикс,60
    переместить_имм рдиай,0
    вызов_системы

.данные
msg: .строка "Iteration\n"

Вычисление суммы чисел от 1 до 10

.текст
.глобал _start

_start:
    переместить_имм р8,0
    переместить_имм р9,10

loop:
    прибавить р8, р9
    уменьшить р9
    сравнить_с р9,0
    переход_если_больше loop

    переместить_имм раикс,60
    переместить рдикс, р8
    вызов_системы

Использование BND-секции

.текст
.глобал _start

_start:
    переместить_имм раикс,0
    сохранить [счётчик], раикс
    переместить_имм рсикс,10

loop:
    загрузить раикс,[счётчик]
    увеличить раикс
    сохранить [счётчик], раикс
    уменьшить рсикс
    сравнить_с рсикс,0
    переход_если_больше loop

    загрузить рдиай,[счётчик]
    переместить_имм раикс,60
    вызов_системы

.бнд
счётчик: .байт 0

Косвенная адресация

.текст
.глобал _start

_start:
    переместить_имм рбикс, переменная
    переместить_имм раикс,99
    сохранить [рбикс], раикс
    загрузить раикс,[рбикс]
    переместить_имм рдиай, раикс
    переместить_имм раикс,60
    вызов_системы

.данные
переменная: .байт 0

Вывод аргумента командной строки

.текст
.глобал _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"

🐛 Отладка и проверка

Просмотр сгенерированного кода

# Дизассемблирование
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)
  • Многомодульная компиляция
  • Макросы

📈 План развития

Реализовано (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 Только для образовательных целей. Используйте на свой страх и риск.