ассемблер для архитектуры x86-64, полностью использующий русскую лексику
Find a file
2026-05-02 23:04:46 +03:00
доки пересборка 2026-05-02 23:04:46 +03:00
тесты пересборка 2026-05-02 23:04:46 +03:00
disassembler_skip_zero.py пересборка 2026-05-02 23:04:46 +03:00
elfreader.py пересборка 2026-05-02 23:04:46 +03:00
kvs_build.py пересборка 2026-05-02 23:04:46 +03:00
kvs_builder.py пересборка 2026-05-02 23:04:46 +03:00
kvs_data.py пересборка 2026-05-02 23:04:46 +03:00
kvs_lexer.py пересборка 2026-05-02 23:04:46 +03:00
kvs_parser.py пересборка 2026-05-02 23:04:46 +03:00
kvs_pass1.py пересборка 2026-05-02 23:04:46 +03:00
kvs_pass2.py пересборка 2026-05-02 23:04:46 +03:00
README.html пересборка 2026-05-02 23:04:46 +03:00
README.md пересборка 2026-05-02 23:04:46 +03:00
todo.txt пересборка 2026-05-02 23:04:46 +03:00

Документация компилятора КВС

1. Общие сведения

КВС (язык программирования) — это низкоуровневый язык, транслируемый в 64-битный ELF-исполняемый файл для архитектуры x86-64. Компилятор написан на Python и состоит из нескольких модулей, выполняющих лексический анализ, синтаксический разбор, двухпроходную генерацию кода и сборку ELF-файла.

1.1. Состав компилятора

Файл Назначение
kvs_8.py Монолитный ассемблер (оригинальная версия)
kvs_build.py Главный сборочный скрипт, запускающий все этапы
kvs_lexer.py Лексический анализ, разбор на токены
kvs_parser.py Синтаксический анализ, построение AST
kvs_pass1.py Первый проход: вычисление размеров и адресов меток
kvs_pass2.py Второй проход: генерация машинного кода
kvs_builder.py Сборка ELF-файла из CSV-данных
kvs_data.py Общие данные (регистры, инструкции, константы)

1.2. Запуск компилятора

# Монолитная версия
python3 kvs_8.py <файл.квс>

# Декомпозированная версия
python3 kvs_build.py <файл.квс>

Входной файл должен иметь расширение .квс.

1.3. Результаты компиляции

Файл Содержимое
<имя>.elf Исполняемый ELF-файл (64-bit)
<имя>.log.csv Лог с адресами, байтами и соответствием командам
<имя>.токены Промежуточный файл токенов (только для декомп. версии)
<имя>.аст Промежуточный AST-файл (только для декомп. версии)
<имя>.проход1 Данные первого прохода (только для декомп. версии)
<имя>.csv CSV с машинным кодом (только для декомп. версии)

2. Синтаксис языка КВС

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

Программа на КВС состоит из секций:

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

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

2.2. Метки

Метка — это имя, за которым следует двоеточие. Метки могут использоваться как цели переходов.

_start:         ; метка _start
    переместить_имм раикс, 1
    переход _start   ; переход на метку

2.3. Директивы

Директива Назначение Пример
.текст Начало секции кода .текст
.данные Начало секции данных .данные
.глобал Объявление глобальной метки (точки входа) .глобал _start
.строка Строка без завершающего нуля .строка "Hello"
.строкауль Строка с завершающим нулём .строкауль "Hello"
.байт Последовательность байтов .байт 0x48, 0x65, 108
.константа Определение константы .константа LEN = 10

2.4. Комментарии

Однострочные комментарии начинаются с ;:

; Это комментарий
переместить_имм раикс, 42   ; комментарий после инструкции

3. Система команд

3.1. Регистры

КВС поддерживает все основные 64-битные регистры x86-64 в различных размерностях:

Размер 64-бит 32-бит 16-бит 8-бит (мл.) 8-бит (ст.)
RAX раикс еаикс аикс ал аш
RCX рсикс есикс сикс кл чш
RDX рдикс едикс дикс дл дш
RBX рбикс ебикс бикс бл бш
RSP рсипи есипи эсп спл
RBP рбипи ебипи бипи бпл
RSI рсиай есиай эс сил
RDI рдиай едиай ди дил
R8-R15 р8р15 рр15д рр15в р8бр15б

3.2. Инструкции

Загрузка констант

Инструкция Синтаксис Описание
переместить_имм переместить_имм рег, значение Загрузить константу в регистр
переместить_имм раикс, 42        ; RAX = 42
переместить_имм еаикс, 0x7FFF    ; EAX = 32767 (32-бит)
переместить_имм ал, 0xFF         ; AL = 255 (8-бит)

Арифметика и логика

Инструкция Синтаксис Описание
прибавить прибавить рег1, рег2 рег1 += рег2
вычесть вычесть рег1, рег2 рег1 -= рег2
увеличить увеличить рег рег++
уменьшить уменьшить рег рег--
сравнить сравнить рег1, рег2 Сравнить два регистра (установка флагов)
сравнить_с сравнить_с рег, значение Сравнить регистр с константой
проверить проверить рег1, рег2 TEST — логическое AND (установка ZF)
прибавить раикс, рбикс   ; 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
переход_если_ноль переход_если_ноль метка ZF = 1 (синоним JE)
переход_если_неоль переход_если_неоль метка ZF = 0 (синоним JNE)

Короткие условные переходы (префикс короткий_):

  • короткий_переход_если_равно, короткий_переход_если_неравно, и т.д.
  • Генерируют 2-байтовые инструкции (смещение ±127 байт)

Системные вызовы

Инструкция Синтаксис Описание
вызов_системы вызов_системы Вызов ядра Linux (syscall)
; Пример: вывод строки
переместить_имм раикс, 1      ; syscall 1 = write
переместить_имм рдиай, 1      ; stdout
переместить_имм рсиай, msg    ; указатель на строку
переместить_имм рдикс, len    ; длина строки
вызов_системы

; Пример: завершение программы
переместить_имм раикс, 60     ; syscall 60 = exit
переместить_имм рдиай, 0      ; код возврата 0
вызов_системы

Прочие инструкции

Инструкция Синтаксис Описание
нет_операции нет_операции NOP (0x90)

4. Примеры программ

4.1. Hello World

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

_start:
    переместить_имм раикс, 1
    переместить_имм рдиай, 1
    переместить_имм рсиай, msg
    переместить_имм рдикс, len_msg
    вызов_системы

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

.данные
    msg: .строкауль "Hello, World!\n"
    .константа len_msg = 15

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

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

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

loop:
    ; тело цикла
    переместить_имм раикс, 1
    переместить_имм рдиай, 1
    переместить_имм рсиай, msg
    переместить_имм рдикс, len_msg
    вызов_системы

    уменьшить рсикс               ; счетчик--
    сравнить_с рсикс, 0
    переход_если_больше loop      ; если > 0, продолжаем

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

.данные
    msg: .строкауль "Iteration\n"
    .константа len_msg = 10

5. Проверка исполняемого файла стандартными утилитами

5.1. Запуск программы

./<имя>.elf

5.2. Просмотр секций (objdump -h)

objdump -h программа.elf

Вывод показывает размер, виртуальный адрес и атрибуты каждой секции.

Разделы:
Idx Name          Разм      VMA               LMA               Фа  смещ.
  0 .text         00000232  0000000000401000  0000000000401000  00001000
  1 .data         0000011c  0000000000402000  0000000000402000  00002000

5.3. Дизассемблирование (objdump -d)

objdump -d программа.elf

Показывает машинный код в виде ассемблерных инструкций x86-64.

# Ограничить вывод
objdump -d программа.elf | head -50

# Сохранить в файл
objdump -d программа.elf > код.asm

5.4. Просмотр заголовков программы (readelf -l)

readelf -l программа.elf

Показывает сегменты LOAD, их смещения, виртуальные адреса и права доступа.

Заголовки программы:
  Тип            Смещ.    Вирт.адр    Физ.адр    Рзм.фйл   Рзм.пм    Флаги
  LOAD           0x001000 0x401000    0x401000   0x232     0x1000    R E
  LOAD           0x002000 0x402000    0x402000   0x11c     0x1000    RW

5.5. Проверка целостности ELF (readelf -h)

readelf -h программа.elf

Выводит заголовок ELF-файла (магия, тип, архитектура, точка входа).

5.6. Просмотр всех заголовков секций (readelf -S)

readelf -S программа.elf

5.7. Сравнение двух ELF-файлов

# Сравнить дизассемблированный код
diff <(objdump -d файл1.elf) <(objdump -d файл2.elf)

# Сравнить заголовки секций
diff <(objdump -h файл1.elf) <(objdump -h файл2.elf)

5.8. Просмотр строк из секции .data

# Извлечь строки из ELF
strings программа.elf

# Показать шестнадцатеричный дамп секции .data
objdump -s -j .data программа.elf

5.9. Трассировка системных вызовов

strace ./программа.elf

Показывает все системные вызовы, выполняемые программой.

5.10. Отладка с GDB

gdb ./программа.elf

В GDB:

(gdb) break _start      ; установить точку останова
(gdb) run               ; запустить
(gdb) info registers    ; показать регистры
(gdb) x/10i $rip        ; показать 10 инструкций
(gdb) stepi             ; выполнить одну инструкцию

6. Особенности и ограничения

6.1. Поддерживаемые возможности

  • 64-битные, 32-битные, 16-битные и 8-битные регистры
  • Непосредственная загрузка констант (imm) в регистры
  • Сравнение регистров и регистров с константами
  • Условные и безусловные переходы (длинные и короткие)
  • Арифметические операции (ADD, SUB, INC, DEC)
  • Логическая операция TEST
  • Системные вызовы Linux (syscall)
  • Секции .text и .data
  • Строковые литералы с escape-последовательностями (\n, \t, \\, \")
  • Директива .байт для raw-данных
  • Директива .константа для имён констант

6.2. Ограничения

  • Отсутствует поддержка косвенной адресации памяти [reg+disp]
  • Нет инструкций для работы со стеком (PUSH, POP, CALL, RET)
  • Нет поддержки плавающей запятой (FPU/SSE)
  • Нет многомодульной компиляции
  • Нет макросов

6.3. Примечания

  • Все переходы используют абсолютные целевые адреса (метки преобразуются в адреса)
  • Для длинных переходов генерируется 5-байтовая инструкция JMP или 6-байтовая Jcc
  • Секция .data выравнивается на границу страницы (0x1000) после .text
  • Точка входа по умолчанию — _start

7. Сообщения об ошибках

Компилятор выводит подробные сообщения об ошибках с указанием файла и строки:

Ошибка в файле test.квс, строка 42:
    переместить_имм аикс, 100000
Неподдерживаемый размер регистра

Основные ошибки:

Сообщение Причина
Неизвестная инструкция: '...' Неверное имя инструкции
Недопустимый формат числа: '...' Неверный синтаксис числа
Недопустимый регистр Регистр не найден в таблице
Метка не найдена: '...' Использование неопределённой метки
Цель слишком далеко для короткого перехода Смещение > 127 байт для условного перехода
Незакрытая кавычка в строке Ошибка в синтаксисе строки

8. Заключение

Компилятор КВС предоставляет возможность писать низкоуровневые программы на русскоязычном ассемблероподобном языке с последующей компиляцией в нативный 64-битный ELF-исполняемый файл. Декомпозированная архитектура компилятора облегчает понимание этапов трансляции и модификацию отдельных модулей.