2026-05-11 15:08:03 +03:00
|
|
|
|
```markdown
|
2026-05-02 23:04:46 +03:00
|
|
|
|
===========================
|
2026-05-11 15:08:03 +03:00
|
|
|
|
ПЛАН РЕАЛИЗАЦИИ СЛОЖНОЙ АДРЕСАЦИИ (ПОЛНАЯ ВЕРСИЯ)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
===========================
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
## СТАТУС: ЧАСТИЧНО РЕАЛИЗОВАНО (v2.0)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
### Уже реализовано:
|
|
|
|
|
|
- ✅ Лексер: токены `[`, `]`, `NUMBER`
|
|
|
|
|
|
- ✅ Парсер: распознавание `[метка]` и `[число]`
|
|
|
|
|
|
- ✅ Pass1: корректный расчёт размера (7 байт для MOV с памятью)
|
|
|
|
|
|
- ✅ Pass2: RIP-relative кодирование для абсолютной адресации
|
|
|
|
|
|
- ✅ Поддержка меток в операндах памяти `[переменная]`
|
|
|
|
|
|
- ✅ Рефакторинг: `kvs_pass2_encoder.py` отдельно
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. Общая схема изменений по модулям
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
| Модуль | Что меняется | Сложность | Статус |
|
|
|
|
|
|
|--------|--------------|-----------|--------|
|
|
|
|
|
|
| `kvs_lexer.py` | новые токены: `[`, `]`, `+`, `-`, `*`, `NUMBER` | низкая | ✅ ГОТОВ |
|
|
|
|
|
|
| `kvs_parser.py` | новая логика операндов: `parse_operand()`, `parse_memory_operand()` | высокая | ✅ ГОТОВ (базово) |
|
|
|
|
|
|
| `kvs_data.py` | активация и уточнение форматов инструкций | средняя | ⚠️ ТРЕБУЕТ ДОРАБОТКИ |
|
|
|
|
|
|
| `kvs_pass1.py` | динамический рассчёт размера инструкций с памятью | высокая | ✅ ГОТОВ (для абсолютной) |
|
|
|
|
|
|
| `kvs_pass2_encoder.py` | разбор адресации → ModR/M + SIB + disp, генерация кода | очень высокая | ⚠️ ЧАСТИЧНО (только абсолютная) |
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. Детальный план по шагам (в порядке реализации)
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
### Шаг 1 — Лексер (`kvs_lexer.py`) ✅ РЕАЛИЗОВАН
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
**Что сделано:**
|
|
|
|
|
|
- Добавлены токены: `LBRACKET` (`[`), `RBRACKET` (`]`), `PLUS` (`+`), `MINUS` (`-`), `STAR` (`*`), `NUMBER`
|
|
|
|
|
|
- Числа отделены от слов (поддержка десятичных, шестнадцатеричных, отрицательных)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
**Результат:** новые типы токенов на выходе лексера.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
### Шаг 2 — Парсер (`kvs_parser.py`) ✅ РЕАЛИЗОВАН (базово)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
**Что сделано:**
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
2.1. Реализован `parse_operand()`:
|
|
|
|
|
|
- Если токен `LBRACKET` → вызывает `parse_memory_operand()`
|
|
|
|
|
|
- Иначе → возвращает значение токена (регистр/число/метка/строка)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
2.2. Реализован `parse_memory_operand()`:
|
2026-05-02 23:04:46 +03:00
|
|
|
|
- Разбирает содержимое между `[` и `]`
|
2026-05-11 15:08:03 +03:00
|
|
|
|
- Поддерживает: `регистр`, `число`, `метка`
|
|
|
|
|
|
- Возвращает строку вида `[раикс + рсикс*8 + 16]` (структура сохраняется)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
2.3. **Ограничения текущей реализации:**
|
|
|
|
|
|
- Поддерживается только простая форма `[метка]` и `[число]`
|
|
|
|
|
|
- Сложные выражения `[reg + reg*scale + disp]` парсятся, но не кодируются
|
|
|
|
|
|
|
|
|
|
|
|
**Результат:** AST содержит операнды памяти в каноническом строковом виде.
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
### Шаг 3 — Данные инструкций (`kvs_data.py`) ⚠️ ТРЕБУЕТ ДОРАБОТКИ
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
**Что нужно сделать:**
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
3.1. Активировать (или добавить) записи для:
|
|
|
|
|
|
|
|
|
|
|
|
| Мнемоника | Opcode | Тип (формат) |
|
|
|
|
|
|
|-----------|--------|--------------|
|
|
|
|
|
|
| `загрузить` | `48 8B` | `mov_reg_mem` |
|
|
|
|
|
|
| `сохранить` | `48 89` | `mov_mem_reg` |
|
|
|
|
|
|
| `загрузить_байт_из_памяти` | `8A` | `mov_reg8_mem` |
|
|
|
|
|
|
| `сохранить_байт` | `88` | `mov_mem8_reg8` |
|
|
|
|
|
|
| `загрузить_адрес` | `48 8D` | `lea` |
|
|
|
|
|
|
| `переместить_с_нулями` | `48 0F B6` | `movzx` |
|
|
|
|
|
|
| `переместить_со_знаком` | `48 0F BE` | `movsx` |
|
|
|
|
|
|
| `втолкнуть_из_памяти` | `FF /6` | `push_mem` |
|
|
|
|
|
|
| `вытолкнуть_в_память` | `8F /0` | `pop_mem` |
|
|
|
|
|
|
| `обменять_с_памятью` | `48 87` | `xchg_mem` |
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
3.2. **Статус:** записи присутствуют в `kvs_data.py`, но используются не все.
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
### Шаг 4 — Первый проход (`kvs_pass1.py`) ✅ РЕАЛИЗОВАН (для абсолютной)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
**Что сделано:**
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
4.1. Написана функция `estimate_memory_operand_size(operand_str)`:
|
2026-05-02 23:04:46 +03:00
|
|
|
|
- Парсит строку `[раикс + рсикс*8 + 16]`
|
2026-05-11 15:08:03 +03:00
|
|
|
|
- Определяет наличие SIB, размер смещения
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
4.2. Модифицирована `estimate_size()`:
|
|
|
|
|
|
- Для инструкций `загрузить`, `сохранить`, `загрузить_адрес` возвращает `7` (REX + opcode + ModRM + disp32)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
**Ограничения:**
|
|
|
|
|
|
- Для сложных форм адресации размер не рассчитывается динамически
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
### Шаг 5 — Второй проход (`kvs_pass2_encoder.py`) ⚠️ ЧАСТИЧНО РЕАЛИЗОВАН
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
#### 5.1. Структура данных для режима адресации ⚠️ НЕ РЕАЛИЗОВАНА
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Нужно создать класс/словарь `AddressingMode`:
|
2026-05-02 23:04:46 +03:00
|
|
|
|
- `has_base` (bool)
|
|
|
|
|
|
- `base_reg` (int 0–15 или None)
|
|
|
|
|
|
- `has_index` (bool)
|
|
|
|
|
|
- `index_reg` (int 0–15)
|
|
|
|
|
|
- `scale` (1,2,4,8)
|
|
|
|
|
|
- `has_disp` (bool)
|
|
|
|
|
|
- `disp_value` (int)
|
|
|
|
|
|
- `disp_size` (1 или 4)
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
#### 5.2. Парсер адресации ⚠️ ЧАСТИЧНО РЕАЛИЗОВАН
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Реализована `parse_memory_operand()` в `kvs_pass2_encoder.py`:
|
|
|
|
|
|
- Поддерживает `[число]` и `[метка]`
|
|
|
|
|
|
- **Нет поддержки:** `[reg]`, `[reg+disp]`, `[reg+reg*scale]`
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
#### 5.3. Кодирование ModR/M ⚠️ ЧАСТИЧНО РЕАЛИЗОВАНО
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Функция `encode_modrm_reg_mem_absolute()`:
|
|
|
|
|
|
- Использует `mod=00, r/m=101` для RIP-relative
|
|
|
|
|
|
- **Нет поддержки:** других режимов адресации
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
#### 5.4. Кодирование SIB ❌ НЕ РЕАЛИЗОВАНО
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Функция `encode_sib()` отсутствует.
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
#### 5.5. Кодирование смещения ⚠️ ЧАСТИЧНО РЕАЛИЗОВАНО
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
`encode_displacement()` использует `struct.pack('<i', offset)` для disp32.
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
#### 5.6. Генераторы инструкций ⚠️ ЧАСТИЧНО РЕАЛИЗОВАНЫ
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
| Функция | Статус |
|
|
|
|
|
|
|---------|--------|
|
|
|
|
|
|
| `encode_mov_reg_mem` | ✅ Реализована (только абсолютная адресация) |
|
|
|
|
|
|
| `encode_mov_mem_reg` | ✅ Реализована (только абсолютная адресация) |
|
|
|
|
|
|
| `encode_lea` | ⚠️ Есть старая версия, требует доработки |
|
|
|
|
|
|
| `encode_mov_reg8_mem` | ❌ Не реализована |
|
|
|
|
|
|
| `encode_mov_mem8_reg8` | ❌ Не реализована |
|
|
|
|
|
|
| `encode_movzx` | ❌ Не реализована |
|
|
|
|
|
|
| `encode_movsx` | ❌ Не реализована |
|
|
|
|
|
|
| `encode_push_mem` | ❌ Не реализована |
|
|
|
|
|
|
| `encode_pop_mem` | ❌ Не реализована |
|
|
|
|
|
|
| `encode_xchg_mem` | ❌ Не реализована |
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
#### 5.7. Диспетчер ✅ РЕАЛИЗОВАН
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
`encode_instruction()` содержит ветки для всех инструкций, включая:
|
|
|
|
|
|
- `загрузить`, `сохранить`, `загрузить_адрес` (с памятью)
|
|
|
|
|
|
- `переместить_имм`, `переместить` (без памяти)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
### Шаг 6 — Тестирование
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Тесты для проверки (поэтапно):
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
| Тест | Что проверяет | Статус |
|
|
|
|
|
|
|------|---------------|--------|
|
|
|
|
|
|
| `загрузить раикс, [число]` | Абсолютная адресация | ✅ ПРОЙДЕН |
|
|
|
|
|
|
| `сохранить [число], раикс` | Абсолютная адресация (запись) | ✅ ПРОЙДЕН |
|
|
|
|
|
|
| `загрузить раикс, [метка]` | Адресация по метке | ✅ ПРОЙДЕН |
|
|
|
|
|
|
| `сохранить [метка], раикс` | Адресация по метке (запись) | ✅ ПРОЙДЕН |
|
|
|
|
|
|
| `загрузить раикс, [рбикс]` | Косвенная адресация | ❌ НЕ РЕАЛИЗОВАНО |
|
|
|
|
|
|
| `загрузить раикс, [рбикс + 8]` | Со смещением | ❌ НЕ РЕАЛИЗОВАНО |
|
|
|
|
|
|
| `загрузить раикс, [рбикс + рсикс*8]` | С индексом | ❌ НЕ РЕАЛИЗОВАНО |
|
|
|
|
|
|
| `загрузить раикс, [рбикс + рсикс*8 + 16]` | Полная SIB | ❌ НЕ РЕАЛИЗОВАНО |
|
|
|
|
|
|
| `загрузить_адрес р11, [переменная]` | LEA с меткой | ❌ НЕ РЕАЛИЗОВАНО |
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
### Шаг 7 — Стандартная библиотека (отложено)
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
После полной реализации адресации:
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
| Файл | Содержание |
|
|
|
|
|
|
|------|------------|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
| `libkvs.квс` | `malloc`, `free`, `strlen`, `strcmp`, `memcpy`, `putchar`, `getchar`, `printf` |
|
2026-05-02 23:04:46 +03:00
|
|
|
|
| `libkvs_data.квс` | статические данные для библиотеки |
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. Следующие шаги (приоритеты)
|
|
|
|
|
|
|
|
|
|
|
|
### 🔴 Приоритет 1 (критично):
|
|
|
|
|
|
1. **Косвенная адресация `[reg]`** — основа для всех остальных форм
|
|
|
|
|
|
- Нужно: `mod=00, r/m=reg` (без SIB, без disp)
|
|
|
|
|
|
|
|
|
|
|
|
### 🟡 Приоритет 2 (важно):
|
|
|
|
|
|
2. **Адресация со смещением `[reg + disp]`**
|
|
|
|
|
|
- disp8 для малых смещений (`mod=01`)
|
|
|
|
|
|
- disp32 для больших (`mod=10`)
|
|
|
|
|
|
|
|
|
|
|
|
### 🟢 Приоритет 3 (расширение):
|
|
|
|
|
|
3. **Сложная адресация с индексом `[reg + reg*scale]`**
|
|
|
|
|
|
- Требует SIB байта
|
|
|
|
|
|
4. **Полная SIB-адресация `[reg + reg*scale + disp]`**
|
|
|
|
|
|
5. **LEA для меток** `загрузить_адрес reg, [метка]`
|
|
|
|
|
|
6. **`.bss` секция** для неинициализированных данных
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
## 4. Итог: что получим на выходе
|
|
|
|
|
|
|
|
|
|
|
|
- ✅ **Лексер** выдаёт `LBRACKET`, `RBRACKET`, `PLUS`, `MINUS`, `STAR`, `NUMBER`
|
|
|
|
|
|
- ✅ **Парсер** понимает `[раикс + рсикс*8 - 16]`
|
|
|
|
|
|
- ✅ **Pass1** правильно считает размер инструкций с памятью (для абсолютной)
|
|
|
|
|
|
- ⚠️ **Pass2** генерирует код только для абсолютной адресации
|
|
|
|
|
|
- ⚠️ **ELF** содержит корректные инструкции x86-64 с RIP-relative
|
|
|
|
|
|
- ❌ **Библиотека** требует полной адресации
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. Зависимости между подзадачами
|
2026-05-02 23:04:46 +03:00
|
|
|
|
|
|
|
|
|
|
```
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Лексер (шаг 1) ✅
|
2026-05-02 23:04:46 +03:00
|
|
|
|
↓
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Парсер (шаг 2) ✅
|
2026-05-02 23:04:46 +03:00
|
|
|
|
↓
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Данные инструкций (шаг 3) ⚠️
|
2026-05-02 23:04:46 +03:00
|
|
|
|
↓
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Pass1 (шаг 4) ✅
|
2026-05-02 23:04:46 +03:00
|
|
|
|
↓
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Pass2 (шаг 5):
|
|
|
|
|
|
5.1 → 5.2 → 5.3 → 5.4 → 5.5 ⚠️ ЧАСТИЧНО
|
2026-05-02 23:04:46 +03:00
|
|
|
|
↓
|
2026-05-11 15:08:03 +03:00
|
|
|
|
5.6 (для каждой мнемоники) ⚠️ ЧАСТИЧНО
|
2026-05-02 23:04:46 +03:00
|
|
|
|
↓
|
2026-05-11 15:08:03 +03:00
|
|
|
|
5.7 (диспетчер) ✅
|
2026-05-02 23:04:46 +03:00
|
|
|
|
↓
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Тестирование (шаг 6) ⚠️ ЧАСТИЧНО
|
2026-05-02 23:04:46 +03:00
|
|
|
|
↓
|
2026-05-11 15:08:03 +03:00
|
|
|
|
Библиотека (шаг 7) ❌ ОТЛОЖЕНО
|
2026-05-02 23:04:46 +03:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-11 15:08:03 +03:00
|
|
|
|
**Статус: v2.0 — абсолютная адресация реализована полностью.**
|
|
|
|
|
|
**Следующая цель: v3.0 — косвенная адресация `[reg]`.**
|
2026-05-17 11:22:39 +03:00
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-05-17 12:21:28 +03:00
|
|
|
|
изучить работу с кучей
|