# КВС (kvs_9_8.py) — Ассемблер с русским синтаксисом для x86-64 ## 📖 Оглавление - [🎯 Назначение и концепция](#-назначение-и-концепция) - [🚀 Особенности и возможности](#-особенности-и-возможности) - [⚙️ Архитектура и процесс сборки](#️-архитектура-и-процесс-сборки) - [📁 Формат исходных файлов (.квс)](#-формат-исходных-файлов-квс) - [🔧 Система команд (инструкции)](#-система-команд-инструкции) - [💾 Регистры процессора](#-регистры-процессора) - [📋 Директивы ассемблера](#-директивы-ассемблера) - [📦 Система импорта модулей](#-система-импорта-модулей) - [🔄 Процесс трансляции и выходные файлы](#-процесс-трансляции-и-выходные-файлы) - [⚠️ Ограничения и особенности реализации](#️-ограничения-и-особенности-реализации) ## 🎯 Назначение и концепция **КВС** — это ассемблер для архитектуры x86-64, полностью использующий **русскую лексику** для мнемоник инструкций, имён регистров и директив. Проект носит **образовательный и экспериментальный характер** и демонстрирует принципы работы ассемблера, построения ELF-файлов и трансляции высокоуровневых концепций в машинный код. **Ключевые философские принципы проекта:** * **Самодокументируемый код**: Читаемость и ясность важнее краткости. * **Изоляция логики**: Разделение парсера, трансформатора и кодогенератора. * **Минимизация зависимостей**: Используется только `struct` для упаковки данных, `re` не используется. * **Избегание чрезмерного ООП**: В контексте возможной будущей самокомпиляции. ## 🚀 Особенности и возможности * **Полностью русский синтаксис**: Все инструкции (`переместить`, `прибавить`, `вызвать`), регистры (`раикс`, `есипи`, `ал`) и директивы (`.текст`, `.данные`) используют кириллицу. * **Генерация исполняемых ELF-файлов**: На выходе создаются 64-битные ELF-файлы для Linux, готовые к запуску. * **Двухпроходная сборка**: Традиционная для ассемблеров схема с разрешением меток. * **Поддержка секций**: Явное разделение на секции кода (`.текст`) и данных (`.данные`). * **Система импорта модулей**: Директива `.импорт` для включения других файлов `.квс` с автоматическим разрешением имён. * **Подготовка к сложной адресации**: Архитектура заложена для будущей трансформации сложных режимов адресации памяти в последовательности простых инструкций через промежуточное представление. * **Детальное логирование**: Генерация `.log.csv` файла с полным соответствием машинных кодов, виртуальных адресов и исходных команд. ## ⚙️ Архитектура и процесс сборки Процесс трансляции исходного кода `.квс` в исполняемый файл `.elf` проходит через несколько этапов: ``` Исходный файл (.квс) │ ▼ (Этап 1: Разбор и импорт) Промежуточный файл (.квс.промежуточный) │ ▼ (Этап 2: Двухпроходное ассемблирование) Данные секций + Таблица меток │ ▼ (Этап 3: Генерация ELF) Исполняемый файл (.elf) + Лог (.log.csv) ``` **Подробнее об этапах:** 1. **Построение промежуточного представления**: Исходный файл и все импортированные модули объединяются в один текст. Метки и константы переименовываются (получают суффикс имени модуля) для избежания коллизий. 2. **Первый проход ассемблирования**: Анализируется промежуточный файл, вычисляются размеры всех инструкций и данных, строится таблица меток с их смещениями внутри секций. 3. **Второй проход ассемблирования**: Генерируется машинный код. Адреса меток подставляются в инструкции переходов, загрузки адресов и т.д. Формируются бинарные содержимое секций `.text` и `.data`. 4. **Компоновка ELF**: Собранные секции упаковываются в формат исполняемого файла ELF 64-bit с корректными заголовками, таблицами секций и сегментов. ## 📁 Формат исходных файлов (.квс) Исходные файлы имеют расширение `.квс`. Их структура следует традициям ассемблера: ```asm ; Комментарий начинается с точки с запятой .данные ; Начало секции данных приветствие: .строка_нуль "Здравствуй, мир!" число: .байт 0x2A .текст ; Начало секции кода .глобал _start ; Объявление точки входа _start: ; Метка переместить_имм раикс, 60 ; Системный вызов exit (60) в rax переместить_имм рдикс, 42 ; Код возврата (42) в rdi вызов_системы ; Вызов ядра (syscall) ``` ## 🔧 Система команд (инструкции) Ассемблер поддерживает обширный набор инструкций x86-64, сгруппированных по категориям: | Категория | Примеры инструкций | Соответствие NASM | | :--- | :--- | :--- | | **Перемещение данных** | `переместить`, `загрузить`, `сохранить`, `загрузить_адрес` | `mov`, `lea` | | **Арифметика** | `прибавить`, `вычесть`, `умножить`, `разделить`, `увеличить` | `add`, `sub`, `mul`, `div`, `inc` | | **Логические операции** | `и`, `или`, `инвертировать`, `проверить` | `and`, `or`, `not`, `test` | | **Управление потоком** | `переход`, `переход_если_равно`, `вызвать`, `вернуться` | `jmp`, `je`, `call`, `ret` | | **Работа со стеком** | `втолкнуть`, `вытолкнуть` | `push`, `pop` | | **Сдвиги и вращения** | `сдвиг_влево`, `вращать_вправо` | `shl`, `ror` | | **Строковые операции** | `переместить_байт`, `сравнить_байты` | `movsb`, `cmpsb` | | **Системные вызовы** | `вызов_системы`, `прервать` | `syscall`, `int` | **Особенности кодирования:** Проект корректно генерирует префиксы REX, учитывает размеры операндов (8/16/32/64 бита) и поддерживает базовые режимы адресации памяти (например, `[раикс]`). ## 💾 Регистры процессора Поддерживаются регистры x86-64 во всех их размерах: | 64-битные | 32-битные | 16-битные | 8-битные (младшие) | 8-битные (старшие) | | :--- | :--- | :--- | :--- | :--- | | `раикс` | `еаикс` | `аикс` | `ал` | `аш` | | `рбикс` | `ебикс` | `бикс` | `бл` | `бш` | | `рсикс` | `есикс` | `сикс` | `кл` | `чш` | | `рдикс` | `едикс` | `дикс` | `дл` | `дш` | | `рсипи` | `есипи` | `эсп` | `спл` | — | | `рбипи` | `ебипи` | `бипи` | `бпл` | — | | `рсиай` | `есиай` | `эс` | `сил` | — | | `рдиай` | `едиай` | `ди` | `дил` | — | | `р8` ... `р15` | `р8д` ... `р15д` | `р8в` ... `р15в` | `р8б` ... `р15б` | — | ## 📋 Директивы ассемблера Директивы управляют процессом ассемблирования, не превращаясь в машинный код напрямую. | Директива | Описание | Пример | | :--- | :--- | :--- | | `.текст` | Переключает ассемблер на запись в секцию кода. | `.текст` | | `.данные` | Переключает ассемблер на запись в секцию данных. | `.данные` | | `.глобал` | Объявляет метку глобальной (точку входа программы). | `.глобал _start` | | `.строка` / `.строка_нуль` | Резервирует место в секции данных для строки (без нуля / с нулевым завершителем). | `.строка_нуль "Текст"` | | `.байт` | Резервирует один или несколько байт с заданными значениями. | `.байт 1, 0xFE, 255` | | `.константа` | Определяет символьную константу, которую можно использовать как число. | `.константа ВЫХОД = 60` | | `.импорт` | Включает содержимое другого файла `.квс` в текущую сборку. | `.импорт библиотека.квс` | ## 📦 Система импорта модулей Директива `.импорт` позволяет разбивать проект на несколько файлов. **Принцип работы:** 1. **Рекурсивный поиск**: Ассемблер ищет указанный файл в той же директории, что и импортирующий файл. 2. **Переименование**: Чтобы избежать конфликтов имён, все метки и константы импортированного модуля автоматически получают суффикс, основанный на имени файла (например, метка `цикл` из `модуль.квс` станет `цикл_модуль`). 3. **Объединение**: Содержимое всех секций `.данные` из импортированных файлов сливается в общую секцию `.данные` промежуточного файла. Аналогично для `.текст`. Это упрощает создание библиотек и организацию больших проектов. ## 🔄 Процесс трансляции и выходные файлы Запуск ассемблера: ```bash python3 kvs_9_8.py программа.квс ``` **В результате создаются три файла:** 1. **`программа.квс.промежуточный`**: Текстовый файл, содержащий объединённый и переименованный код всех модулей. Используется для отладки процесса импорта. 2. **`программа.elf`**: Исполняемый 64-битный ELF-файл. Для запуска может потребоваться установить флаг исполнения: `chmod +x программа.elf`. 3. **`программа.log.csv`**: Детальный лог в формате CSV, где для каждого байта машинного кода указан его виртуальный адрес, шестнадцатеричное значение, целевой адрес (для инструкций переходов) и исходная команда на русском языке. Неоценим для обучения и отладки. ## ⚠️ Ограничения и особенности реализации * **Экспериментальный статус**: Проект в активной разработке, некоторые углы архитектуры x86-64 могут быть реализованы не полностью. * **Базовая адресация памяти**: На данный момент поддерживаются преимущественно простые формы адресации (например, `[регистр]`). Режимы со сдвигом и несколькими регистрами (`[база + индекс*масштаб + смещение]`) предназначены для реализации через **трансформацию в промежуточном представлении** (задел на будущее). * **Отсутствие макросов и условной компиляции**: В текущей версии эти конструкции не поддерживаются. * **Лексический анализатор (лексер)**: Написан "вручную", без использования регулярных выражений (`re`), в соответствии с философией проекта. * **Генерация ELF**: Реализация фокусируется на создании рабочих исполняемых файлов для Linux. Некоторые необязательные или специфичные поля заголовков ELF могут быть заполнены упрощённо.