diff --git a/README.html b/README.html
index eecfc81..9cd59e5 100644
--- a/README.html
+++ b/README.html
@@ -363,8 +363,8 @@
╚══════════════════════════════════╝
-
Версия 2.0 | Экспериментальный проект | 2025
- ✓ Абсолютная адресация реализована | ⟳ Косвенная адресация в разработке
+ Версия 2.0 | Экспериментальный проект | 2026
+ ✓ Абсолютная адресация реализована | ✓ Косвенная адресация реализована | ✓ Секция .bss реализована
┌──[ ОГЛАВЛЕНИЕ ]────────────────────────────────────────────┐
@@ -401,11 +401,18 @@
ОСОБЕННОСТИ И ВОЗМОЖНОСТИ
- Полностью русский синтаксис — переместить, прибавить, вызвать, регистры раикс, есипи, ал, директивы .текст, .данные
+ Полностью русский синтаксис — переместить, прибавить, вызвать, регистры раикс, есипи, ал, директивы .текст, .данные, .бсс
Генерация исполняемых ELF-файлов — 64-битные ELF для Linux, готовые к запуску
Двухпроходная сборка — традиционная схема с разрешением меток
- Поддержка секций — разделение на .текст (код) и .данные (данные)
- Абсолютная адресация памяти — чтение и запись по меткам [переменная] и абсолютным адресам [0x402000] с RIP-relative кодированием
+ Поддержка секций — разделение на .текст (код), .данные (инициализированные данные) и .бсс (неинициализированные данные)
+ Полная адресация памяти :
+
+ Абсолютная адресация по меткам [переменная]
+ Абсолютная адресация по числовому адресу [0x402000]
+ Косвенная адресация через регистр [раикс]
+ Всё с RIP-relative кодированием для 64-битных перемещений
+
+
CSV-логирование — детальный файл .csv с соответствием адресов, байтов и исходных команд
Более 50 инструкций — полный набор основных команд x86-64
Рефакторинг — кодогенерация вынесена в отдельный модуль kvs_pass2_encoder.py
@@ -448,7 +455,7 @@ ELF-компоновщик (.elf)
УСТАНОВКА И ЗАПУСК
# Клонирование репозитория
-git clone https://github.com/username/kvs.git
+git clone https://github.com/artradeskz/kvs.git
cd kvs
# Установка прав на выполнение (при необходимости)
@@ -463,29 +470,36 @@ python3 kvs_build.py программа.квс
СИНТАКСИС ИСХОДНЫХ ФАЙЛОВ (.квс)
; Комментарий начинается с точки с запятой
-.данные ; Начало секции данных
- переменная: .байт 0 ; Переменная в памяти
+.бсс ; Начало секции неинициализированных данных
+ счётчик: .байт 0 ; Переменная без начального значения
+
+.данные ; Начало секции инициализированных данных
message: .строка_нуль "Привет, мир!"
.текст ; Начало секции кода
.глобал _start ; Точка входа
_start:
- ; Работа с памятью
+ ; Абсолютная адресация через метку
переместить_имм раикс, 42
- сохранить [переменная], раикс ; запись в память
+ сохранить [счётчик], раикс ; запись в BSS-переменную
- загрузить рбикс, [переменная] ; чтение из памяти
+ ; Абсолютная адресация через число
+ сохранить [0x402000], раикс ; запись по абсолютному адресу
+
+ ; Косвенная адресация через регистр
+ переместить_имм рбикс, message
+ загрузить раикс, [рбикс] ; чтение через регистр
; Системный вызов write
переместить_имм раикс, 1
- загрузить_адрес рсиай, message
+ переместить_имм рсиай, message
переместить_имм рдикс, 13
вызов_системы
- ; Выход с кодом из переменной
+ ; Выход с кодом из счётчика
+ загрузить рдиай, [счётчик]
переместить_имм раикс, 60
- загрузить рдиай, [переменная]
вызов_системы
СИСТЕМА КОМАНД
@@ -493,68 +507,81 @@ _start:
Категория Примеры инструкций Соответствие NASM
Перемещение данных переместить, переместить_иммmov, mov reg, imm
Работа с памятью загрузить, сохранить, загрузить_адресmov reg, mem, mov mem, reg, lea
- Арифметика прибавить, вычесть, умножить, разделить, увеличить, уменьшитьadd, sub, mul, div, inc, dec
- Логические и, или, исключающее_или, инвертировать, отрицатьand, or, xor, not, neg
- Сравнение сравнить, сравнить_с, проверитьcmp, test
- Условные переходы переход_если_равно, переход_если_больше, короткий_переход_если_равноje, jg, je short
- Безусловные переходы переход, короткий_переход, вызвать, вернутьсяjmp, jmp short, call, ret
- Системные вызов_системы, остановитьsyscall, hlt
+ Арифметика прибавить, вычесть, увеличить, уменьшитьadd, sub, inc, dec
+ Логические сравнить, сравнить_с, проверитьcmp, test
+ Условные переходы переход_если_равно, переход_если_больше, короткий_переходje, jg, jmp short
+ Безусловные переходы переход, короткий_переходjmp, jmp short
+ Системные вызов_системыsyscall
РАБОТА С ПАМЯТЬЮ
- ✓ РЕАЛИЗОВАНО (v2.0): Абсолютная адресация через метки и числа
+ ✓ РЕАЛИЗОВАНО (v2.0): Абсолютная адресация (метки и числа), косвенная адресация через регистры
Поддерживаемые формы:
Синтаксис Описание Пример
- [метка]Адрес метки (из .данные) загрузить раикс, [переменная]
+ [метка]Адрес метки (из .данные или .бсс) загрузить раикс, [переменная]
[число]Абсолютный адрес сохранить [0x402000], раикс
+ [регистр]Косвенная адресация через регистр загрузить раикс, [рбикс]
Пример использования:
- .данные
-переменная: .байт 0
-результат: .байт 0
+ .бсс
+счётчик: .байт 0
+указатель: .байт 0
+
+.данные
+переменная: .байт 42
+message: .строка_нуль "Hello"
.текст
_start:
- ; Запись значения
- переместить_имм раикс, 42
- сохранить [переменная], раикс
+ ; Абсолютная адресация через метку
+ загрузить раикс, [переменная]
- ; Чтение значения
- загрузить рбикс, [переменная]
+ ; Абсолютная адресация через число
+ сохранить [0x402000], раикс
- ; Завершение с кодом 42
+ ; Косвенная адресация
+ переместить_имм рбикс, переменная
+ загрузить раикс, [рбикс]
+
+ ; Работа с BSS
+ сохранить [счётчик], раикс
+
+ ; Завершение
переместить_имм раикс, 60
- загрузить рдиай, [переменная]
+ загрузить рдиай, [счётчик]
вызов_системы
-
-
⚠️ ВАЖНО: Порядок объявления в секции
.данные имеет значение! Переменные, объявленные перед строковыми константами, могут затереть первые байты строк. Рекомендуется объявлять строки первыми, а изменяемые переменные — после.
+
+ 📌 ВАЖНО: Все тесты из папки тесты/ успешно собираются и запускаются, включая тест, воспроизводящий баг с BSS-секцией. Адресация работает корректно во всех формах.
РЕГИСТРЫ ПРОЦЕССОРА
- 64-битные 32-битные 16-битные 8-битные (мл.) 8-битные (ст.)
- раиксеаиксаиксалаш
- рбиксебиксбиксблбш
- рсиксесикссиксклчш
- рдикседиксдиксдлдш
- рсипиесипиэспспл—
- рбипиебипибипибпл—
- рсиайесиайэссил—
- рдиайедиайдидил—
- р8…р15р8д…р15др8в…р15вр8б…р15б—
+ 64-битные 32-битные 16-битные 8-битные (мл.)
+ раиксеаиксаиксал
+ рбиксебиксбиксбл
+ рсиксесикссикскл
+ рдикседиксдиксдл
+ рсипиесипиэспспл
+ рбипиебипибипибпл
+ рсиайесиайэссил
+ рдиайедиайдидил
+
+ ⚠️ ПРИМЕЧАНИЕ: Старшие 8-битные регистры (AH, BH, CH, DH) и расширенные младшие (SPL, BPL, SIL, DIL) не поддерживаются. Регистры R8–R15 также отсутствуют.
+
ДИРЕКТИВЫ АССЕМБЛЕРА
Директива Назначение Пример
.текстНачало секции кода .текст
- .данныеНачало секции данных .данные
+ .данныеНачало секции инициализированных данных .данные
+ .бссНачало секции неинициализированных данных .бсс
.глобалОбъявление глобальной метки .глобал _start
.строкаСтрока без нулевого терминатора .строка "Hello"
.строка_нульСтрока с нулевым терминатором .строка_нуль "Hello"
@@ -584,40 +611,71 @@ _start:
.данные
msg: .строка_нуль "Hello, World!"
- Пример 2: Работа с переменными в памяти
+ Пример 2: Работа с BSS-секцией
.глобал _start
.текст
_start:
- ; Запись 42 в переменную
- переместить_имм раикс, 42
- сохранить [переменная], раикс
+ ; Инициализация счётчика
+ переместить_имм раикс, 0
+ сохранить [счётчик], раикс
- ; Завершение с кодом 42
+ ; Цикл: увеличить счётчик 10 раз
+ переместить_имм рсикс, 10
+loop:
+ загрузить раикс, [счётчик]
+ увеличить раикс
+ сохранить [счётчик], раикс
+ уменьшить рсикс
+ сравнить_с рсикс, 0
+ переход_если_больше loop
+
+ ; Выход с кодом = значение счётчика
+ загрузить рдиай, [счётчик]
+ переместить_имм раикс, 60
+ вызов_системы
+
+.бсс
+счётчик: .байт 0
+
+ Пример 3: Косвенная адресация
+ .глобал _start
+.текст
+
+_start:
+ ; Загружаем адрес переменной в регистр
+ переместить_имм рбикс, переменная
+
+ ; Косвенная запись
+ переместить_имм раикс, 99
+ сохранить [рбикс], раикс
+
+ ; Косвенное чтение
+ загрузить раикс, [рбикс]
+
+ ; Выход
+ переместить_имм рдиай, раикс
переместить_имм раикс, 60
- загрузить рдиай, [переменная]
вызов_системы
.данные
переменная: .байт 0
- Пример 3: Цикл для вычисления суммы
+ Пример 4: Абсолютный адрес
.глобал _start
.текст
_start:
- переместить_имм р8, 0 ; сумма
- переместить_имм р9, 10 ; счётчик
-
-loop:
- прибавить р8, р9
- уменьшить р9
- сравнить_с р9, 0
- переход_если_больше loop
-
- ; exit(сумма в r8)
+ ; Запись по абсолютному адресу 0x402000
+ переместить_имм раикс, 0x2A
+ сохранить [0x402000], раикс
+
+ ; Чтение по абсолютному адресу
+ загрузить рбикс, [0x402000]
+
+ ; Выход с кодом 42
переместить_имм раикс, 60
- переместить рдикс, р8
+ переместить_имм рдиай, 0x2A
вызов_системы
ПРОЦЕСС ТРАНСЛЯЦИИ И ВЫХОДНЫЕ ФАЙЛЫ
@@ -640,50 +698,44 @@ loop:
Лексер с токенами [, ], NUMBER
Парсер с поддержкой операндов в квадратных скобках
Первый проход с корректным расчётом размера инструкций с памятью
- Второй проход с кодированием абсолютной адресации через RIP-relative
- Поддержка меток в операндах памяти [переменная]
- Рефакторинг: выделение кодировщика в отдельный модуль kvs_pass2_encoder.py
+ Второй проход с кодированием адресации через RIP-relative
+ Абсолютная адресация по меткам [переменная]
+ Абсолютная адресация по числовым адресам [0x402000]
+ Косвенная адресация через регистры [раикс]
+ Секция .бсс для неинициализированных данных
+ Рефакторинг: выделение кодировщика в отдельный модуль
Более 50 инструкций x86-64
CSV-логирование
- ⚠️ Частично реализовано
+ ⚠️ Частично реализовано / ограничено
загрузить_адрес (LEA) — только для чисел, не для меток
- Сложные выражения в операндах памяти парсятся, но не кодируются
-
-
- ❌ В разработке (v3.0)
-
- Косвенная адресация [reg]
- Адресация со смещением [reg + disp]
- Сложная адресация с индексом [reg + reg*scale]
- Полная SIB-адресация [reg + reg*scale + disp]
- Директива .bss для неинициализированных данных
- LEA для меток (загрузить_адрес reg, [метка])
- Стандартная библиотека
+ Старшие 8-битные регистры (AH, BH, CH, DH) не поддерживаются
+ Регистры R8–R15 не поддерживаются
ПЛАН РАЗВИТИЯ
- v2.0 (текущая) — Абсолютная адресация
+ v2.0 (текущая) — Адресация и BSS
✅ Лексер: [, ], NUMBER
- ✅ Парсер: [метка] и [число]
- ✅ Pass1: размер = 7 байт
+ ✅ Парсер: [метка], [число], [регистр]
+ ✅ Pass1: корректный расчёт размера инструкций
✅ Pass2: RIP-relative кодирование
- ✅ Поддержка меток в памяти
+ ✅ Абсолютная адресация (метки и числа)
+ ✅ Косвенная адресация ([reg])
+ ✅ Секция .бсс
✅ Рефакторинг энкодера
- v3.0 (планируется) — Косвенная и относительная адресация
+ v3.0 (планируется) — Расширенная адресация
- ❌ [reg] — косвенная адресация через регистр
- ❌ [reg + disp] — со смещением (disp8/disp32)
+ ❌ [reg + disp] — адресация со смещением
❌ [reg + reg*scale] — с индексным регистром
❌ [reg + reg*scale + disp] — полная SIB-адресация
- ❌ .bss — секция неинициализированных данных
❌ LEA для меток
+ ❌ PUSH/POP/CALL/RET
v4.0 (отложено) — Стандартная библиотека
@@ -691,40 +743,18 @@ loop:
❌ malloc, free
❌ strlen, strcmp, memcpy
❌ putchar, getchar
- ❌ printf (упрощённый вариант)
-
-Зависимости между подзадачами:
-
-Лексер (шаг 1) ✅
- ↓
-Парсер (шаг 2) ✅
- ↓
-Данные инструкций (шаг 3) ⚠️
- ↓
-Pass1 (шаг 4) ✅
- ↓
-Pass2 (шаг 5): ⚠️ ЧАСТИЧНО
- 5.1 → 5.2 → 5.3 → 5.4 → 5.5
- ↓
- 5.6 (генераторы инструкций)
- ↓
- 5.7 (диспетчер) ✅
- ↓
-Тестирование (шаг 6) ⚠️ ЧАСТИЧНО
- ↓
-Библиотека (шаг 7) ❌ ОТЛОЖЕНО
-
-
ОГРАНИЧЕНИЯ
- Косвенная адресация памяти — поддерживается только абсолютная форма [метка]; адресация через регистры [reg] в разработке
- Сложная адресация — формы [reg+disp], [reg+reg*scale], [reg+reg*scale+disp] не реализованы
+ Адресация со смещением — формы [reg+disp], [reg+reg*scale], [reg+reg*scale+disp] не реализованы
LEA для меток — загрузить_адрес reg, [метка] не работает, используйте переместить_имм reg, метка
- Отсутствие .bss — все переменные инициализируются и попадают в .data (занимают место в файле)
- Нет динамической памяти — нет встроенных malloc/free (можно реализовать через syscall brk)
+ Старшие 8-битные регистры — AH, BH, CH, DH не поддерживаются
+ Расширенные регистры — SPL, BPL, SIL, DIL, а также R8–R15 не поддерживаются
+ Нет умножения и деления — инструкции MUL/DIV не реализованы
+ Нет операций со стеком — PUSH/POP/CALL/RET отсутствуют
+ Нет динамической памяти — нет встроенных malloc/free
Нет макросов и условной компиляции
Экспериментальный статус — некоторые инструкции могут быть реализованы не полностью
@@ -732,7 +762,7 @@ Pass2 (шаг 5): ⚠️ ЧАСТИЧНО
───────────────────────────────────────────────────────────────────────
- КВС Ассемблер v2.0 | Экспериментальный проект | 2025
+ КВС Ассемблер v2.0 | Экспериментальный проект | 2026
Только для образовательных целей. Используйте на свой страх и риск.
> Система готова. Введите команду...
diff --git a/README.md b/README.md
index 9ad0c96..ab8efc5 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
```markdown
-# КВС Ассемблер с русским синтаксисом для x86-64
+# КВС — Ассемблер с русским синтаксисом для x86-64
**КВС** — это экспериментальный ассемблер для архитектуры x86-64, полностью использующий **русскую лексику** для мнемоник инструкций, имён регистров и директив. Проект носит образовательный характер и демонстрирует принципы работы ассемблера, построения ELF-файлов и трансляции высокоуровневых концепций в машинный код.
@@ -24,8 +24,12 @@
- **Полностью русский синтаксис** — все инструкции, регистры и директивы на кириллице
- **Генерация исполняемых ELF-файлов** — 64-битные ELF для Linux, готовые к запуску
- **Двухпроходная сборка** — традиционная схема с разрешением меток
-- **Поддержка секций** — разделение на `.текст` (код) и `.данные` (данные)
-- **Абсолютная адресация памяти** — чтение и запись по меткам `[переменная]` и абсолютным адресам `[0x402000]` с RIP-relative кодированием
+- **Поддержка секций** — разделение на `.текст` (код), `.данные` (данные) и `.бсс` (неинициализированные данные)
+- **Гибкая адресация памяти**:
+ - абсолютная адресация по меткам `[переменная]`
+ - абсолютная адресация по числовому адресу `[0x402000]`
+ - косвенная адресация через регистр `[раикс]`
+ - всё с RIP-relative кодированием для 64-битных перемещений
- **CSV-логирование** — детальный файл с соответствием адресов, байтов и исходных команд
- **Более 50 инструкций** — полный набор основных команд x86-64
- **Минимализм зависимостей** — только стандартная библиотека Python
@@ -37,29 +41,30 @@
```
Исходный файл (.квс)
- │
- ▼ (kvs_lexer.py)
+ │
+ ▼ (kvs_lexer.py)
Файл токенов (.токены)
- │
- ▼ (kvs_parser.py)
+ │
+ ▼ (kvs_parser.py)
AST-представление (.аст)
- │
- ▼ (kvs_pass1.py)
+ │
+ ▼ (kvs_pass1.py)
Первый проход: размеры, метки (.проход1)
- │
- ▼ (kvs_pass2.py + kvs_pass2_encoder.py)
+ │
+ ▼ (kvs_pass2.py + kvs_pass2_encoder.py)
Второй проход: генерация кода (.csv)
- │
- ▼ (kvs_builder.py)
+ │
+ ▼ (kvs_builder.py)
ELF-компоновщик (.elf)
-
+ │
+ ▼
Исполняемый файл!
```
### Модули компилятора
| Файл | Назначение |
-|------|------------|
+|------|-------------|
| `kvs_build.py` | Главный сборочный скрипт |
| `kvs_lexer.py` | Лексический анализ, разбор на токены |
| `kvs_parser.py` | Синтаксический анализ, построение AST |
@@ -73,7 +78,7 @@ ELF-компоновщик (.elf)
```bash
# Клонирование репозитория
-git clone https://github.com/username/kvs.git
+git clone https://github.com/artradeskz/kvs.git
cd kvs
# Установка прав на выполнение (при необходимости)
@@ -87,21 +92,21 @@ python3 kvs_build.py --help
### 1. Создайте файл `hello.квс`:
-```asm
+```assembly
.текст
.глобал _start
_start:
; write(1, msg, 13)
- переместить_имм раикс, 1
- переместить_имм рдиай, 1
+ переместить_имм раикс,1
+ переместить_имм рдиай,1
переместить_имм рсиай, msg
- переместить_имм рдикс, 13
+ переместить_имм рдикс,13
вызов_системы
; exit(0)
- переместить_имм раикс, 60
- переместить_имм рдиай, 0
+ переместить_имм раикс,60
+ переместить_имм рдиай,0
вызов_системы
.данные
@@ -121,6 +126,7 @@ python3 kvs_build.py hello.квс
```
**Вывод:**
+
```
Hello, World!
```
@@ -129,21 +135,24 @@ Hello, World!
### Структура программы
-```
+```assembly
.текст ; секция кода (обязательна)
; ... инструкции ...
.данные ; секция данных (опциональна)
- ; ... данные ...
+ ; ... инициализированные данные ...
+
+.бсс ; секция неинициализированных данных (опциональна)
+ ; ... переменные без начального значения ...
```
### Метки
Метка — это имя, за которым следует двоеточие:
-```asm
+```assembly
_start: ; метка _start
- переместить_имм раикс, 1
+ переместить_имм раикс,1
переход _start ; переход на метку
```
@@ -151,23 +160,31 @@ _start: ; метка _start
Однострочные комментарии начинаются с `;`:
-```asm
+```assembly
; Это комментарий
-переместить_имм раикс, 42 ; комментарий после инструкции
+переместить_имм раикс,42 ; комментарий после инструкции
```
-### Работа с памятью (абсолютная адресация)
+### Работа с памятью
-```asm
+```assembly
; Запись значения в память по метке
-переместить_имм раикс, 42
+переместить_имм раикс,42
сохранить [переменная], раикс
; Чтение значения из памяти
-загрузить рбикс, [переменная]
+загрузить рбикс,[переменная]
; Запись по абсолютному адресу
сохранить [0x402000], раикс
+
+; Косвенная адресация через регистр
+переместить_имм рбикс, переменная
+загрузить раикс, [рбикс]
+
+; Работа с BSS-секцией
+.бсс
+счётчик: .байт 0
```
## 📖 Система команд
@@ -178,23 +195,24 @@ _start: ; метка _start
|------------|-----------|----------|
| `переместить_имм` | `переместить_имм рег, значение` | Загрузить константу в регистр |
-```asm
-переместить_имм раикс, 42 ; RAX = 42
-переместить_имм еаикс, 0x7FFF ; EAX = 32767
-переместить_имм ал, 0xFF ; AL = 255
+```assembly
+переместить_имм раикс,42 ; RAX = 42
+переместить_имм еаикс,0x7FFF ; EAX = 32767
+переместить_имм ал,0xFF ; AL = 255
```
### Работа с памятью
| Инструкция | Синтаксис | Описание |
|------------|-----------|----------|
-| `загрузить` | `загрузить рег, [метка/адрес]` | Загрузить значение из памяти |
-| `сохранить` | `сохранить [метка/адрес], рег` | Сохранить значение в память |
+| `загрузить` | `загрузить рег, [метка/адрес/регистр]` | Загрузить значение из памяти |
+| `сохранить` | `сохранить [метка/адрес/регистр], рег` | Сохранить значение в память |
-```asm
-загрузить раикс, [переменная] ; RAX = *переменная
+```assembly
+загрузить раикс,[переменная] ; RAX = *переменная
сохранить [результат], раикс ; *результат = RAX
-загрузить рбикс, [0x402000] ; загрузка по абсолютному адресу
+загрузить рбикс,[0x402000] ; загрузка по абсолютному адресу
+загрузить раикс,[рбикс] ; косвенная загрузка через регистр
```
### Арифметика и логика
@@ -209,10 +227,10 @@ _start: ; метка _start
| `сравнить_с` | `сравнить_с рег, значение` | Сравнить с константой |
| `проверить` | `проверить рег1, рег2` | TEST (логическое AND) |
-```asm
+```assembly
прибавить раикс, рбикс ; RAX += RBX
увеличить рсикс ; RCX++
-сравнить раикс, 10 ; сравнить RAX с 10
+сравнить раикс,10 ; сравнить RAX с 10
```
### Переходы
@@ -240,10 +258,10 @@ _start: ; метка _start
|------------|----------|
| `вызов_системы` | Вызов ядра Linux (syscall) |
-```asm
+```assembly
; Пример: завершение программы
-переместить_имм раикс, 60 ; syscall 60 = exit
-переместить_имм рдиай, 0 ; код возврата 0
+переместить_имм раикс,60 ; syscall 60 = exit
+переместить_имм рдиай,0 ; код возврата 0
вызов_системы
```
@@ -251,24 +269,24 @@ _start: ; метка _start
КВС поддерживает все основные 64-битные регистры x86-64:
-| 64-бит | 32-бит | 16-бит | 8-бит (мл.) | 8-бит (ст.) |
-|--------|--------|--------|-------------|-------------|
-| `раикс` | `еаикс` | `аикс` | `ал` | `аш` |
-| `рбикс` | `ебикс` | `бикс` | `бл` | `бш` |
-| `рсикс` | `есикс` | `сикс` | `кл` | `чш` |
-| `рдикс` | `едикс` | `дикс` | `дл` | `дш` |
-| `рсипи` | `есипи` | `эсп` | `спл` | — |
-| `рбипи` | `ебипи` | `бипи` | `бпл` | — |
-| `рсиай` | `есиай` | `эс` | `сил` | — |
-| `рдиай` | `едиай` | `ди` | `дил` | — |
-| `р8`…`р15` | `р8д`…`р15д` | `р8в`…`р15в` | `р8б`…`р15б` | — |
+| 64-бит | 32-бит | 16-бит | 8-бит (мл.) |
+|--------|--------|--------|-------------|
+| `раикс` | `еаикс` | `аикс` | `ал` |
+| `рбикс` | `ебикс` | `бикс` | `бл` |
+| `рсикс` | `есикс` | `сикс` | `кл` |
+| `рдикс` | `едикс` | `дикс` | `дл` |
+| `рсипи` | `есипи` | `эсп` | `спл` |
+| `рбипи` | `ебипи` | `бипи` | `бпл` |
+| `рсиай` | `есиай` | `эс` | `сил` |
+| `рдиай` | `едиай` | `ди` | `дил` |
## 🔧 Директивы ассемблера
| Директива | Назначение | Пример |
|-----------|------------|--------|
| `.текст` | Начало секции кода | `.текст` |
-| `.данные` | Начало секции данных | `.данные` |
+| `.данные` | Начало секции инициализированных данных | `.данные` |
+| `.бсс` | Начало секции неинициализированных данных | `.бсс` |
| `.глобал` | Объявление глобальной метки | `.глобал _start` |
| `.строка` | Строка без завершающего нуля | `.строка "Hello"` |
| `.строка_нуль` | Строка с завершающим нулём | `.строка_нуль "Hello"` |
@@ -279,21 +297,19 @@ _start: ; метка _start
### Работа с памятью (переменные)
-```asm
+```assembly
.текст
.глобал _start
_start:
; Запись значения в переменную
- переместить_имм раикс, 42
+ переместить_имм раикс,42
сохранить [переменная], раикс
-
; Чтение значения из переменной
- загрузить рбикс, [переменная]
-
+ загрузить рбикс,[переменная]
; Завершение с кодом возврата
- переместить_имм раикс, 60
- загрузить рдиай, [переменная]
+ переместить_имм раикс,60
+ загрузить рдиай,[переменная]
вызов_системы
.данные
@@ -302,26 +318,26 @@ _start:
### Цикл и условный переход
-```asm
+```assembly
.текст
.глобал _start
_start:
- переместить_имм рсикс, 10 ; счетчик = 10
+ переместить_имм рсикс,10 ; счетчик = 10
loop:
- переместить_имм раикс, 1
- переместить_имм рдиай, 1
+ переместить_имм раикс,1
+ переместить_имм рдиай,1
переместить_имм рсиай, msg
- переместить_имм рдикс, 10
+ переместить_имм рдикс,10
вызов_системы
уменьшить рсикс ; счетчик--
- сравнить_с рсикс, 0
+ сравнить_с рсикс,0
переход_если_больше loop ; если > 0, продолжаем
- переместить_имм раикс, 60
- переместить_имм рдиай, 0
+ переместить_имм раикс,60
+ переместить_имм рдиай,0
вызов_системы
.данные
@@ -330,26 +346,82 @@ msg: .строка "Iteration\n"
### Вычисление суммы чисел от 1 до 10
-```asm
+```assembly
.текст
.глобал _start
_start:
- переместить_имм р8, 0 ; сумма
- переместить_имм р9, 10 ; счётчик
+ переместить_имм р8,0 ; сумма
+ переместить_имм р9,10 ; счётчик
loop:
прибавить р8, р9
уменьшить р9
- сравнить_с р9, 0
+ сравнить_с р9,0
переход_если_больше loop
; exit(сумма в r8)
- переместить_имм раикс, 60
+ переместить_имм раикс,60
переместить рдикс, р8
вызов_системы
```
+### Использование BSS-секции
+
+```assembly
+.текст
+.глобал _start
+
+_start:
+ ; инициализация счётчика в BSS
+ переместить_имм раикс,0
+ сохранить [счётчик], раикс
+
+ ; цикл: увеличить счётчик 10 раз
+ переместить_имм рсикс,10
+loop:
+ загрузить раикс,[счётчик]
+ увеличить раикс
+ сохранить [счётчик], раикс
+ уменьшить рсикс
+ сравнить_с рсикс,0
+ переход_если_больше loop
+
+ ; выход с кодом = значение счётчика
+ загрузить рдиай,[счётчик]
+ переместить_имм раикс,60
+ вызов_системы
+
+.бсс
+счётчик: .байт 0
+```
+
+### Косвенная адресация
+
+```assembly
+.текст
+.глобал _start
+
+_start:
+ ; загружаем адрес переменной в регистр
+ переместить_имм рбикс, переменная
+
+ ; косвенная запись
+ переместить_имм раикс,99
+ сохранить [рбикс], раикс
+
+ ; косвенное чтение
+ загрузить раикс,[рбикс]
+
+ ; выход
+ переместить_имм рдиай, раикс
+ переместить_имм раикс,60
+ вызов_системы
+
+.данные
+переменная: .байт 0
+```
+
## 🐛 Отладка и проверка
### Просмотр сгенерированного кода
@@ -389,9 +461,7 @@ strace ./программа.elf
```bash
gdb ./программа.elf
-```
-```gdb
(gdb) break _start ; установить точку останова
(gdb) run ; запустить
(gdb) info registers ; показать регистры
@@ -403,54 +473,59 @@ gdb ./программа.elf
### Поддерживается
-- ✅ 64-битные, 32-битные, 16-битные и 8-битные регистры
+- ✅ 64-битные, 32-битные, 16-битные и 8-битные регистры (AL, BL, CL, DL)
- ✅ Непосредственная загрузка констант (imm) в регистры
- ✅ Сравнение регистров и регистров с константами
- ✅ Условные и безусловные переходы (длинные и короткие)
- ✅ Арифметические операции (ADD, SUB, INC, DEC)
- ✅ Логическая операция TEST
- ✅ Системные вызовы Linux (syscall)
-- ✅ Секции `.текст` и `.данные`
+- ✅ Секции `.текст`, `.данные` и `.бсс`
- ✅ Строковые литералы с escape-последовательностями (`\n`, `\t`, `\\`, `\"`)
- ✅ Директива `.байт` для raw-данных
- ✅ Директива `.константа` для имён констант
-- ✅ **Абсолютная адресация памяти** `[метка]` и `[число]` (RIP-relative)
+- ✅ **Абсолютная адресация** по меткам и числовым адресам `[метка]` / `[0x402000]`
+- ✅ **Косвенная адресация через регистр** `[раикс]`
+- ✅ RIP-relative кодирование для всех видов адресации
### Не поддерживается (в разработке)
-- ❌ Косвенная адресация `[reg]` — доступ к памяти через регистр
- ❌ Адресация со смещением `[reg + disp]`
- ❌ Сложная адресация с индексом `[reg + reg*scale]` и полная SIB-адресация
-- ❌ Инструкции для работы со стеком (PUSH, POP, CALL, RET) — частично
+- ❌ Инструкции для работы со стеком (PUSH, POP, CALL, RET)
+- ❌ Старшие 8-битные регистры (AH, BH, CH, DH) и расширенные младшие (SPL, BPL, SIL, DIL)
+- ❌ Регистры R8–R15 и их байтовые/словные версии
- ❌ Поддержка плавающей запятой (FPU/SSE)
- ❌ Многомодульная компиляция
-- ❌ Директива `.bss` для неинициализированных данных
- ❌ Макросы
## 📈 План развития
### Реализовано (v2.0)
-- [x] Лексер с токенами `[`, `]`, `NUMBER`
-- [x] Парсер с поддержкой операндов в квадратных скобках
-- [x] Первый проход с корректным расчётом размера инструкций с памятью
-- [x] Второй проход с кодированием абсолютной адресации через RIP-relative
-- [x] Поддержка меток в операндах памяти `[переменная]`
-- [x] Рефакторинг: выделение кодировщика в отдельный модуль
+
+- Лексер с токенами `[`, `]`, `NUMBER`
+- Парсер с поддержкой операндов в квадратных скобках
+- Первый проход с корректным расчётом размера инструкций с памятью
+- Второй проход с кодированием абсолютной адресации через RIP-relative
+- Поддержка меток в операндах памяти `[переменная]`
+- Поддержка числовых адресов `[0x402000]`
+- Поддержка косвенной адресации `[регистр]`
+- Секция `.бсс` для неинициализированных данных
+- Рефакторинг: выделение кодировщика в отдельный модуль
### В планах (v3.0)
-- [ ] Косвенная адресация `[reg]`
-- [ ] Адресация со смещением `[reg + disp]`
-- [ ] Сложная адресация с индексом `[reg + reg*scale]`
-- [ ] Полная SIB-адресация `[reg + reg*scale + disp]`
-- [ ] Директива `.bss` для неинициализированных данных
-- [ ] Поддержка инструкций PUSH/POP/CALL/RET для стековых операций
-- [ ] Стандартная библиотека (`libkvs.квс`): malloc, free, strlen, strcmp, print
+
+- Адресация со смещением `[reg + disp]`
+- Сложная адресация с индексом `[reg + reg*scale]`
+- Полная SIB-адресация `[reg + reg*scale + disp]`
+- Поддержка инструкций PUSH/POP/CALL/RET для стековых операций
+- Стандартная библиотека (`libkvs.квс`): malloc, free, strlen, strcmp, print
## 📄 Лицензия
Только для образовательных целей. Используйте на свой страх и риск.
-```
-КВС Ассемблер | Экспериментальный проект | 2026
-Только для образовательных целей. Используйте на свой страх и риск.
-```
+---
+*КВС Ассемблер | Экспериментальный проект | 2026*
+*Только для образовательных целей. Используйте на свой страх и риск.*
+```
\ No newline at end of file
diff --git a/todo.txt b/todo.txt
index 06559bf..e5a69f3 100644
--- a/todo.txt
+++ b/todo.txt
@@ -246,5 +246,5 @@ Pass2 (шаг 5):
```
-
+тестировать все директивы бнд
изучить работу с кучей
\ No newline at end of file