обновить ридми
This commit is contained in:
parent
f133b48363
commit
bb80efac8d
22
AGENTS.md
22
AGENTS.md
|
|
@ -23,16 +23,18 @@
|
|||
### Структура проекта
|
||||
|
||||
```
|
||||
kvs_lexer.py — лексер (исходник → токены)
|
||||
kvs_parser.py — парсер (токены → AST)
|
||||
kvs_pass1.py — первый проход (размеры секций, адреса меток)
|
||||
kvs_pass2.py — второй проход (AST + pass1 → CSV с байтами)
|
||||
kvs_builder.py — сборщик ELF (CSV + pass1 → исполняемый файл)
|
||||
kvs_data.py — общие константы и данные
|
||||
kvs_build.py — главный сборочный скрипт (вызывает всё по порядку)
|
||||
kvs_pass2_encoder_fixsize.py — кодировщик инструкций фиксированного размера
|
||||
kvs_pass2_encoder_mutsize.py — кодировщик инструкций переменного размера + диспетчер
|
||||
kvs_pass2_encoder.py — реэкспорт из fixsize + mutsize (совместимость)
|
||||
kvs_lexer.py — лексер (исходник → токены)
|
||||
kvs_parser.py — парсер (токены → AST)
|
||||
kvs_pass1.py — первый проход: генерация CSV с заглушками для неизвестных меток
|
||||
kvs_pass2.py — второй проход: разрешение меток (замена заглушек на реальные адреса)
|
||||
kvs_pass3.py — третий проход: подстановка констант в команды
|
||||
kvs_pass4.py — четвёртый проход: перекодирование инструкций с подставленными значениями
|
||||
kvs_builder.py — сборщик ELF (CSV → исполняемый файл)
|
||||
kvs_data.py — общие константы и данные (регистры, инструкции, функции)
|
||||
kvs_encoder.py — фасад кодировщика (реэкспорт из fixsize + mutsize)
|
||||
kvs_encoder_fixsize.py — кодировщик инструкций фиксированного размера
|
||||
kvs_encoder_mutsize.py — кодировщик инструкций переменного размера + диспетчер
|
||||
kvs_build.py — главный сборочный скрипт (запускает все проходы по порядку)
|
||||
```
|
||||
|
||||
### Стиль
|
||||
|
|
|
|||
785
README.html
785
README.html
|
|
@ -1,785 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="ru">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>КВС - Ассемблер с русским синтаксисом</title>
|
||||
<style>
|
||||
/* Сброс и базовые настройки */
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Courier New', 'Courier', monospace;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
color: #00ff00;
|
||||
background-color: #000000;
|
||||
background-image:
|
||||
linear-gradient(rgba(0, 20, 0, 0.1) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(0, 20, 0, 0.1) 1px, transparent 1px);
|
||||
background-size: 20px 20px;
|
||||
padding: 20px;
|
||||
min-height: 100vh;
|
||||
text-shadow: 0 0 5px rgba(0, 255, 0, 0.3);
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0; }
|
||||
}
|
||||
|
||||
.cursor {
|
||||
display: inline-block;
|
||||
width: 8px;
|
||||
height: 16px;
|
||||
background-color: #00ff00;
|
||||
margin-left: 2px;
|
||||
vertical-align: text-bottom;
|
||||
animation: blink 1s infinite;
|
||||
}
|
||||
|
||||
.terminal {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
border: 2px solid #00aa00;
|
||||
padding: 20px;
|
||||
position: relative;
|
||||
box-shadow: 0 0 20px rgba(0, 255, 0, 0.2), inset 0 0 20px rgba(0, 255, 0, 0.1);
|
||||
}
|
||||
|
||||
.terminal::before {
|
||||
content: "┌───[ КВС v2.0 ]───┐";
|
||||
position: absolute;
|
||||
top: -11px;
|
||||
left: 20px;
|
||||
background: #000;
|
||||
padding: 0 10px;
|
||||
font-size: 12px;
|
||||
color: #00aa00;
|
||||
}
|
||||
|
||||
.terminal::after {
|
||||
content: "└─────────────────────┘";
|
||||
position: absolute;
|
||||
bottom: -11px;
|
||||
right: 20px;
|
||||
background: #000;
|
||||
padding: 0 10px;
|
||||
font-size: 12px;
|
||||
color: #00aa00;
|
||||
}
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
color: #00ff00;
|
||||
margin: 25px 0 15px 0;
|
||||
border-bottom: 1px dashed #00aa00;
|
||||
padding-bottom: 5px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 24px;
|
||||
color: #00ff88;
|
||||
text-align: center;
|
||||
margin-top: 0;
|
||||
padding: 10px;
|
||||
border: 1px solid #00aa00;
|
||||
background: rgba(0, 20, 0, 0.3);
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 18px;
|
||||
color: #00ff66;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 16px;
|
||||
color: #00ff44;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 15px 0;
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
margin: 15px 0 15px 30px;
|
||||
}
|
||||
|
||||
li {
|
||||
margin: 8px 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
li::before {
|
||||
content: "›";
|
||||
color: #00ff00;
|
||||
position: absolute;
|
||||
left: -15px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #00ffff;
|
||||
text-decoration: none;
|
||||
border-bottom: 1px dotted #00aaaa;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #ffff00;
|
||||
border-bottom: 1px solid #ffff00;
|
||||
text-shadow: 0 0 10px rgba(255, 255, 0, 0.5);
|
||||
}
|
||||
|
||||
code, pre {
|
||||
font-family: 'Courier New', monospace;
|
||||
background: rgba(0, 30, 0, 0.5);
|
||||
border: 1px solid #005500;
|
||||
padding: 15px;
|
||||
margin: 15px 0;
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
white-space: pre;
|
||||
color: #88ff88;
|
||||
box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.5);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
pre::before {
|
||||
content: "┌──[ код ]";
|
||||
position: absolute;
|
||||
top: -10px;
|
||||
left: 10px;
|
||||
background: #000;
|
||||
padding: 0 5px;
|
||||
font-size: 11px;
|
||||
color: #00aa00;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 20px 0;
|
||||
border: 1px solid #005500;
|
||||
}
|
||||
|
||||
th {
|
||||
background: rgba(0, 40, 0, 0.5);
|
||||
color: #00ff88;
|
||||
padding: 10px;
|
||||
border: 1px solid #005500;
|
||||
text-align: left;
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
td {
|
||||
padding: 10px;
|
||||
border: 1px solid #005500;
|
||||
color: #88ff88;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background: rgba(0, 25, 0, 0.3);
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background: rgba(0, 50, 0, 0.4);
|
||||
}
|
||||
|
||||
.note {
|
||||
border-left: 3px solid #ffff00;
|
||||
padding: 15px;
|
||||
margin: 20px 0;
|
||||
background: rgba(40, 40, 0, 0.2);
|
||||
color: #ffff88;
|
||||
}
|
||||
|
||||
.warning {
|
||||
border-left: 3px solid #ff4444;
|
||||
padding: 15px;
|
||||
margin: 20px 0;
|
||||
background: rgba(40, 0, 0, 0.2);
|
||||
color: #ff8888;
|
||||
}
|
||||
|
||||
.success {
|
||||
border-left: 3px solid #44ff44;
|
||||
padding: 15px;
|
||||
margin: 20px 0;
|
||||
background: rgba(0, 40, 0, 0.2);
|
||||
color: #88ff88;
|
||||
}
|
||||
|
||||
.process-diagram {
|
||||
text-align: center;
|
||||
margin: 30px 0;
|
||||
font-family: monospace;
|
||||
white-space: pre;
|
||||
color: #00ffaa;
|
||||
background: rgba(0, 20, 0, 0.3);
|
||||
padding: 20px;
|
||||
border: 1px dashed #00aa00;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.status-table td:first-child {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.status-done {
|
||||
color: #00ff00;
|
||||
}
|
||||
|
||||
.status-partial {
|
||||
color: #ffff00;
|
||||
}
|
||||
|
||||
.status-pending {
|
||||
color: #ff4444;
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 40px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #005500;
|
||||
text-align: center;
|
||||
color: #00aa00;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.typewriter {
|
||||
overflow: hidden;
|
||||
border-right: 3px solid #00ff00;
|
||||
white-space: nowrap;
|
||||
margin: 0 auto;
|
||||
animation: typing 3.5s steps(40, end), blink-caret 0.75s step-end infinite;
|
||||
}
|
||||
|
||||
@keyframes typing {
|
||||
from { width: 0; }
|
||||
to { width: 100%; }
|
||||
}
|
||||
|
||||
@keyframes blink-caret {
|
||||
from, to { border-color: transparent; }
|
||||
50% { border-color: #00ff00; }
|
||||
}
|
||||
|
||||
.ascii-art {
|
||||
text-align: center;
|
||||
margin: 30px 0;
|
||||
font-family: monospace;
|
||||
color: #00ff88;
|
||||
line-height: 1.2;
|
||||
white-space: pre;
|
||||
text-shadow: 0 0 10px rgba(0, 255, 136, 0.5);
|
||||
}
|
||||
|
||||
.ascii-art-box {
|
||||
display: inline-block;
|
||||
border: none;
|
||||
background: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 2px 6px;
|
||||
margin-left: 8px;
|
||||
font-size: 10px;
|
||||
border-radius: 2px;
|
||||
background: #005500;
|
||||
color: #00ff00;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
padding: 10px;
|
||||
font-size: 12px;
|
||||
}
|
||||
.terminal {
|
||||
padding: 15px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 18px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
table {
|
||||
font-size: 11px;
|
||||
}
|
||||
pre, code {
|
||||
font-size: 11px;
|
||||
padding: 10px;
|
||||
}
|
||||
.ascii-art {
|
||||
font-size: 10px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track {
|
||||
background: rgba(0, 20, 0, 0.3);
|
||||
border: 1px solid #005500;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #005500;
|
||||
border: 1px solid #00aa00;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #00aa00;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="terminal">
|
||||
<h1 class="typewriter">КВС — Ассемблер с русским синтаксисом для x86-64</h1>
|
||||
|
||||
<div style="text-align: center; margin: 30px 0; color: #00ff88;">
|
||||
<div class="ascii-art">
|
||||
<pre class="ascii-art-box">
|
||||
╔══════════════════════════════════╗
|
||||
║ ██╗ ██╗ ██╗ ██╗ ███████╗ ║
|
||||
║ ██║ ██╔╝ ██╗ ██╗ ██╔════╝ ║
|
||||
║ █████╔╝ ██╗ ██╗ ███████╗ ║
|
||||
║ ██║╚██╗ ╚██╗ ██╔╝ ╚════██║ ║
|
||||
║ ██║ ╚██╗ ╚██╔╝ ███████║ ║
|
||||
║ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ║
|
||||
╚══════════════════════════════════╝
|
||||
</pre>
|
||||
</div>
|
||||
<p>Версия 2.0 | Экспериментальный проект | 2026</p>
|
||||
<p><span style="color: #00ff00;">✓ Абсолютная адресация реализована</span> | <span style="color: #00ff00;">✓ Косвенная адресация реализована</span> | <span style="color: #00ff00;">✓ Секция .bss реализована</span></p>
|
||||
</div>
|
||||
|
||||
<h2>┌──[ ОГЛАВЛЕНИЕ ]────────────────────────────────────────────┐</h2>
|
||||
<ul style="columns: 2; column-gap: 40px;">
|
||||
<li><a href="#назначение">Назначение и концепция</a></li>
|
||||
<li><a href="#особенности">Особенности и возможности</a></li>
|
||||
<li><a href="#архитектура">Архитектура и процесс сборки</a></li>
|
||||
<li><a href="#установка">Установка и запуск</a></li>
|
||||
<li><a href="#синтаксис">Синтаксис исходных файлов (.квс)</a></li>
|
||||
<li><a href="#команды">Система команд</a></li>
|
||||
<li><a href="#память">Работа с памятью</a></li>
|
||||
<li><a href="#регистры">Регистры процессора</a></li>
|
||||
<li><a href="#директивы">Директивы ассемблера</a></li>
|
||||
<li><a href="#примеры">Примеры программ</a></li>
|
||||
<li><a href="#трансляция">Процесс трансляции</a></li>
|
||||
<li><a href="#статус">Статус реализации</a></li>
|
||||
<li><a href="#план">План развития</a></li>
|
||||
<li><a href="#ограничения">Ограничения</a></li>
|
||||
</ul>
|
||||
<h2>└──────────────────────────────────────────────────────────────┘</h2>
|
||||
|
||||
<h2 id="назначение">НАЗНАЧЕНИЕ И КОНЦЕПЦИЯ</h2>
|
||||
<p><strong>КВС</strong> — это ассемблер для архитектуры x86-64, полностью использующий <strong>русскую лексику</strong> для мнемоник инструкций, имён регистров и директив. Проект носит <strong>образовательный и экспериментальный характер</strong> и демонстрирует принципы работы ассемблера, построения ELF-файлов и трансляции высокоуровневых концепций в машинный код.</p>
|
||||
|
||||
<div class="note">
|
||||
<strong>Ключевые принципы проекта:</strong>
|
||||
<ul>
|
||||
<li><strong>Русскоязычный синтаксис</strong> — все инструкции, регистры и директивы на кириллице</li>
|
||||
<li><strong>Модульная архитектура</strong> — лексер, парсер, два прохода, сборщик ELF</li>
|
||||
<li><strong>Минимализм зависимостей</strong> — только стандартная библиотека Python</li>
|
||||
<li><strong>Подготовка к самокомпиляции</strong> — архитектура, допускающая написание компилятора на самом КВС</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2 id="особенности">ОСОБЕННОСТИ И ВОЗМОЖНОСТИ</h2>
|
||||
<ul>
|
||||
<li><strong>Полностью русский синтаксис</strong> — <code>переместить</code>, <code>прибавить</code>, <code>вызвать</code>, регистры <code>раикс</code>, <code>есипи</code>, <code>ал</code>, директивы <code>.текст</code>, <code>.данные</code>, <code>.бсс</code></li>
|
||||
<li><strong>Генерация исполняемых ELF-файлов</strong> — 64-битные ELF для Linux, готовые к запуску</li>
|
||||
<li><strong>Двухпроходная сборка</strong> — традиционная схема с разрешением меток</li>
|
||||
<li><strong>Поддержка секций</strong> — разделение на <code>.текст</code> (код), <code>.данные</code> (инициализированные данные) и <code>.бсс</code> (неинициализированные данные)</li>
|
||||
<li><strong>Полная адресация памяти</strong>:
|
||||
<ul>
|
||||
<li>Абсолютная адресация по меткам <code>[переменная]</code></li>
|
||||
<li>Абсолютная адресация по числовому адресу <code>[0x402000]</code></li>
|
||||
<li>Косвенная адресация через регистр <code>[раикс]</code></li>
|
||||
<li>Всё с RIP-relative кодированием для 64-битных перемещений</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>CSV-логирование</strong> — детальный файл <code>.csv</code> с соответствием адресов, байтов и исходных команд</li>
|
||||
<li><strong>Более 50 инструкций</strong> — полный набор основных команд x86-64</li>
|
||||
<li><strong>Рефакторинг</strong> — кодогенерация вынесена в отдельный модуль <code>kvs_pass2_encoder.py</code></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="архитектура">АРХИТЕКТУРА И ПРОЦЕСС СБОРКИ</h2>
|
||||
<div class="process-diagram">
|
||||
Исходный файл (.квс)
|
||||
│
|
||||
▼ (kvs_lexer.py)
|
||||
Файл токенов (.токены)
|
||||
│
|
||||
▼ (kvs_parser.py)
|
||||
AST-представление (.аст)
|
||||
│
|
||||
▼ (kvs_pass1.py)
|
||||
Первый проход: размеры, метки (.проход1)
|
||||
│
|
||||
▼ (kvs_pass2.py + kvs_pass2_encoder.py)
|
||||
Второй проход: генерация кода (.csv)
|
||||
│
|
||||
▼ (kvs_builder.py)
|
||||
ELF-компоновщик (.elf)
|
||||
|
||||
Исполняемый файл!
|
||||
</div>
|
||||
|
||||
<h3>Модули компилятора</h3>
|
||||
<table>
|
||||
<tr><th>Файл</th><th>Назначение</th></tr>
|
||||
<tr><td><code>kvs_build.py</code></td><td>Главный сборочный скрипт</td></tr>
|
||||
<tr><td><code>kvs_lexer.py</code></td><td>Лексический анализ, разбор на токены</td></tr>
|
||||
<tr><td><code>kvs_parser.py</code></td><td>Синтаксический анализ, построение AST</td></tr>
|
||||
<tr><td><code>kvs_pass1.py</code></td><td>Первый проход: вычисление размеров и адресов меток</td></tr>
|
||||
<tr><td><code>kvs_pass2.py</code></td><td>Второй проход: обход AST, генерация CSV</td></tr>
|
||||
<tr><td><code>kvs_pass2_encoder.py</code></td><td>Кодировщик инструкций (все encode_* функции)</td></tr>
|
||||
<tr><td><code>kvs_builder.py</code></td><td>Сборка ELF-файла из CSV</td></tr>
|
||||
<tr><td><code>kvs_data.py</code></td><td>Общие данные (регистры, инструкции)</td></tr>
|
||||
</table>
|
||||
|
||||
<h2 id="установка">УСТАНОВКА И ЗАПУСК</h2>
|
||||
<pre># Клонирование репозитория
|
||||
git clone https://github.com/artradeskz/kvs.git
|
||||
cd kvs
|
||||
|
||||
# Установка прав на выполнение (при необходимости)
|
||||
chmod +x kvs_build.py
|
||||
|
||||
# Компиляция программы
|
||||
python3 kvs_build.py программа.квс
|
||||
|
||||
# Запуск скомпилированной программы
|
||||
./программа.elf</pre>
|
||||
|
||||
<h2 id="синтаксис">СИНТАКСИС ИСХОДНЫХ ФАЙЛОВ (.квс)</h2>
|
||||
<pre>; Комментарий начинается с точки с запятой
|
||||
|
||||
.бсс ; Начало секции неинициализированных данных
|
||||
счётчик: .байт 0 ; Переменная без начального значения
|
||||
|
||||
.данные ; Начало секции инициализированных данных
|
||||
message: .строка_нуль "Привет, мир!"
|
||||
|
||||
.текст ; Начало секции кода
|
||||
.глобал _start ; Точка входа
|
||||
|
||||
_start:
|
||||
; Абсолютная адресация через метку
|
||||
переместить_имм раикс, 42
|
||||
сохранить [счётчик], раикс ; запись в BSS-переменную
|
||||
|
||||
; Абсолютная адресация через число
|
||||
сохранить [0x402000], раикс ; запись по абсолютному адресу
|
||||
|
||||
; Косвенная адресация через регистр
|
||||
переместить_имм рбикс, message
|
||||
загрузить раикс, [рбикс] ; чтение через регистр
|
||||
|
||||
; Системный вызов write
|
||||
переместить_имм раикс, 1
|
||||
переместить_имм рсиай, message
|
||||
переместить_имм рдикс, 13
|
||||
вызов_системы
|
||||
|
||||
; Выход с кодом из счётчика
|
||||
загрузить рдиай, [счётчик]
|
||||
переместить_имм раикс, 60
|
||||
вызов_системы</pre>
|
||||
|
||||
<h2 id="команды">СИСТЕМА КОМАНД</h2>
|
||||
<table>
|
||||
<tr><th>Категория</th><th>Примеры инструкций</th><th>Соответствие NASM</th></tr>
|
||||
<tr><td>Перемещение данных</td><td><code>переместить</code>, <code>переместить_имм</code></td><td><code>mov</code>, <code>mov reg, imm</code></td></tr>
|
||||
<tr><td>Работа с памятью</td><td><code>загрузить</code>, <code>сохранить</code>, <code>загрузить_адрес</code></td><td><code>mov reg, mem</code>, <code>mov mem, reg</code>, <code>lea</code></td></tr>
|
||||
<tr><td>Арифметика</td><td><code>прибавить</code>, <code>вычесть</code>, <code>увеличить</code>, <code>уменьшить</code></td><td><code>add</code>, <code>sub</code>, <code>inc</code>, <code>dec</code></td></tr>
|
||||
<tr><td>Логические</td><td><code>сравнить</code>, <code>сравнить_с</code>, <code>проверить</code></td><td><code>cmp</code>, <code>test</code></td></tr>
|
||||
<tr><td>Условные переходы</td><td><code>переход_если_равно</code>, <code>переход_если_больше</code>, <code>короткий_переход</code></td><td><code>je</code>, <code>jg</code>, <code>jmp short</code></td></tr>
|
||||
<tr><td>Безусловные переходы</td><td><code>переход</code>, <code>короткий_переход</code></td><td><code>jmp</code>, <code>jmp short</code></td></tr>
|
||||
<tr><td>Системные</td><td><code>вызов_системы</code></td><td><code>syscall</code></td></tr>
|
||||
</table>
|
||||
|
||||
<h2 id="память">РАБОТА С ПАМЯТЬЮ</h2>
|
||||
<div class="success">
|
||||
<strong>✓ РЕАЛИЗОВАНО (v2.0):</strong> Абсолютная адресация (метки и числа), косвенная адресация через регистры
|
||||
</div>
|
||||
|
||||
<h3>Поддерживаемые формы:</h3>
|
||||
<table>
|
||||
<tr><th>Синтаксис</th><th>Описание</th><th>Пример</th></tr>
|
||||
<tr><td><code>[метка]</code></td><td>Адрес метки (из .данные или .бсс)</td><td><code>загрузить раикс, [переменная]</code></td></tr>
|
||||
<tr><td><code>[число]</code></td><td>Абсолютный адрес</td><td><code>сохранить [0x402000], раикс</code></td></tr>
|
||||
<tr><td><code>[регистр]</code></td><td>Косвенная адресация через регистр</td><td><code>загрузить раикс, [рбикс]</code></td></tr>
|
||||
</table>
|
||||
|
||||
<h3>Пример использования:</h3>
|
||||
<pre>.бсс
|
||||
счётчик: .байт 0
|
||||
указатель: .байт 0
|
||||
|
||||
.данные
|
||||
переменная: .байт 42
|
||||
message: .строка_нуль "Hello"
|
||||
|
||||
.текст
|
||||
_start:
|
||||
; Абсолютная адресация через метку
|
||||
загрузить раикс, [переменная]
|
||||
|
||||
; Абсолютная адресация через число
|
||||
сохранить [0x402000], раикс
|
||||
|
||||
; Косвенная адресация
|
||||
переместить_имм рбикс, переменная
|
||||
загрузить раикс, [рбикс]
|
||||
|
||||
; Работа с BSS
|
||||
сохранить [счётчик], раикс
|
||||
|
||||
; Завершение
|
||||
переместить_имм раикс, 60
|
||||
загрузить рдиай, [счётчик]
|
||||
вызов_системы</pre>
|
||||
|
||||
<div class="note">
|
||||
<strong>📌 ВАЖНО:</strong> Все тесты из папки <code>тесты/</code> успешно собираются и запускаются, включая тест, воспроизводящий баг с BSS-секцией. Адресация работает корректно во всех формах.
|
||||
</div>
|
||||
|
||||
<h2 id="регистры">РЕГИСТРЫ ПРОЦЕССОРА</h2>
|
||||
<table>
|
||||
<tr><th>64-битные</th><th>32-битные</th><th>16-битные</th><th>8-битные (мл.)</th></tr>
|
||||
<tr><td><code>раикс</code></td><td><code>еаикс</code></td><td><code>аикс</code></td><td><code>ал</code></td></tr>
|
||||
<tr><td><code>рбикс</code></td><td><code>ебикс</code></td><td><code>бикс</code></td><td><code>бл</code></td></tr>
|
||||
<tr><td><code>рсикс</code></td><td><code>есикс</code></td><td><code>сикс</code></td><td><code>кл</code></td></tr>
|
||||
<tr><td><code>рдикс</code></td><td><code>едикс</code></td><td><code>дикс</code></td><td><code>дл</code></td></tr>
|
||||
<tr><td><code>рсипи</code></td><td><code>есипи</code></td><td><code>эсп</code></td><td><code>спл</code></td></tr>
|
||||
<tr><td><code>рбипи</code></td><td><code>ебипи</code></td><td><code>бипи</code></td><td><code>бпл</code></td></tr>
|
||||
<tr><td><code>рсиай</code></td><td><code>есиай</code></td><td><code>эс</code></td><td><code>сил</code></td></tr>
|
||||
<tr><td><code>рдиай</code></td><td><code>едиай</code></td><td><code>ди</code></td><td><code>дил</code></td></tr>
|
||||
</table>
|
||||
<div class="warning">
|
||||
<strong>⚠️ ПРИМЕЧАНИЕ:</strong> Старшие 8-битные регистры (AH, BH, CH, DH) и расширенные младшие (SPL, BPL, SIL, DIL) не поддерживаются. Регистры R8–R15 также отсутствуют.
|
||||
</div>
|
||||
|
||||
<h2 id="директивы">ДИРЕКТИВЫ АССЕМБЛЕРА</h2>
|
||||
<table>
|
||||
<tr><th>Директива</th><th>Назначение</th><th>Пример</th></tr>
|
||||
<tr><td><code>.текст</code></td><td>Начало секции кода</td><td><code>.текст</code></td></tr>
|
||||
<tr><td><code>.данные</code></td><td>Начало секции инициализированных данных</td><td><code>.данные</code></td></tr>
|
||||
<tr><td><code>.бсс</code></td><td>Начало секции неинициализированных данных</td><td><code>.бсс</code></td></tr>
|
||||
<tr><td><code>.глобал</code></td><td>Объявление глобальной метки</td><td><code>.глобал _start</code></td></tr>
|
||||
<tr><td><code>.строка</code></td><td>Строка без нулевого терминатора</td><td><code>.строка "Hello"</code></td></tr>
|
||||
<tr><td><code>.строка_нуль</code></td><td>Строка с нулевым терминатором</td><td><code>.строка_нуль "Hello"</code></td></tr>
|
||||
<tr><td><code>.байт</code></td><td>Резервирование байтов</td><td><code>.байт 0x0A, 255, 0b0001</code></td></tr>
|
||||
<tr><td><code>.константа</code></td><td>Определение константы</td><td><code>.константа SIZE = 100</code></td></tr>
|
||||
</table>
|
||||
|
||||
<h2 id="примеры">ПРИМЕРЫ ПРОГРАММ</h2>
|
||||
|
||||
<h3>Пример 1: "Привет, мир!"</h3>
|
||||
<pre>.глобал _start
|
||||
.текст
|
||||
|
||||
_start:
|
||||
; write(1, msg, 13)
|
||||
переместить_имм раикс, 1
|
||||
переместить_имм рдиай, 1
|
||||
переместить_имм рсиай, msg
|
||||
переместить_имм рдикс, 13
|
||||
вызов_системы
|
||||
|
||||
; exit(0)
|
||||
переместить_имм раикс, 60
|
||||
переместить_имм рдиай, 0
|
||||
вызов_системы
|
||||
|
||||
.данные
|
||||
msg: .строка_нуль "Hello, World!"</pre>
|
||||
|
||||
<h3>Пример 2: Работа с BSS-секцией</h3>
|
||||
<pre>.глобал _start
|
||||
.текст
|
||||
|
||||
_start:
|
||||
; Инициализация счётчика
|
||||
переместить_имм раикс, 0
|
||||
сохранить [счётчик], раикс
|
||||
|
||||
; Цикл: увеличить счётчик 10 раз
|
||||
переместить_имм рсикс, 10
|
||||
loop:
|
||||
загрузить раикс, [счётчик]
|
||||
увеличить раикс
|
||||
сохранить [счётчик], раикс
|
||||
уменьшить рсикс
|
||||
сравнить_с рсикс, 0
|
||||
переход_если_больше loop
|
||||
|
||||
; Выход с кодом = значение счётчика
|
||||
загрузить рдиай, [счётчик]
|
||||
переместить_имм раикс, 60
|
||||
вызов_системы
|
||||
|
||||
.бсс
|
||||
счётчик: .байт 0</pre>
|
||||
|
||||
<h3>Пример 3: Косвенная адресация</h3>
|
||||
<pre>.глобал _start
|
||||
.текст
|
||||
|
||||
_start:
|
||||
; Загружаем адрес переменной в регистр
|
||||
переместить_имм рбикс, переменная
|
||||
|
||||
; Косвенная запись
|
||||
переместить_имм раикс, 99
|
||||
сохранить [рбикс], раикс
|
||||
|
||||
; Косвенное чтение
|
||||
загрузить раикс, [рбикс]
|
||||
|
||||
; Выход
|
||||
переместить_имм рдиай, раикс
|
||||
переместить_имм раикс, 60
|
||||
вызов_системы
|
||||
|
||||
.данные
|
||||
переменная: .байт 0</pre>
|
||||
|
||||
<h3>Пример 4: Абсолютный адрес</h3>
|
||||
<pre>.глобал _start
|
||||
.текст
|
||||
|
||||
_start:
|
||||
; Запись по абсолютному адресу 0x402000
|
||||
переместить_имм раикс, 0x2A
|
||||
сохранить [0x402000], раикс
|
||||
|
||||
; Чтение по абсолютному адресу
|
||||
загрузить рбикс, [0x402000]
|
||||
|
||||
; Выход с кодом 42
|
||||
переместить_имм раикс, 60
|
||||
переместить_имм рдиай, 0x2A
|
||||
вызов_системы</pre>
|
||||
|
||||
<h2 id="трансляция">ПРОЦЕСС ТРАНСЛЯЦИИ И ВЫХОДНЫЕ ФАЙЛЫ</h2>
|
||||
<p>Запуск ассемблера:</p>
|
||||
<pre>python3 kvs_build.py программа.квс</pre>
|
||||
|
||||
<p><strong>В результате создаются файлы:</strong></p>
|
||||
<ul>
|
||||
<li><strong><code>программа.токены</code></strong> — результат лексического анализа</li>
|
||||
<li><strong><code>программа.аст</code></strong> — AST-представление</li>
|
||||
<li><strong><code>программа.проход1</code></strong> — результаты первого прохода (размеры, метки)</li>
|
||||
<li><strong><code>программа.csv</code></strong> — детальный лог с адресами, байтами и командами</li>
|
||||
<li><strong><code>программа.elf</code></strong> — исполняемый ELF-файл</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="статус">СТАТУС РЕАЛИЗАЦИИ</h2>
|
||||
|
||||
<h3>✅ Полностью реализовано (v2.0)</h3>
|
||||
<ul>
|
||||
<li>Лексер с токенами <code>[</code>, <code>]</code>, <code>NUMBER</code></li>
|
||||
<li>Парсер с поддержкой операндов в квадратных скобках</li>
|
||||
<li>Первый проход с корректным расчётом размера инструкций с памятью</li>
|
||||
<li>Второй проход с кодированием адресации через RIP-relative</li>
|
||||
<li>Абсолютная адресация по меткам <code>[переменная]</code></li>
|
||||
<li>Абсолютная адресация по числовым адресам <code>[0x402000]</code></li>
|
||||
<li>Косвенная адресация через регистры <code>[раикс]</code></li>
|
||||
<li>Секция <code>.бсс</code> для неинициализированных данных</li>
|
||||
<li>Рефакторинг: выделение кодировщика в отдельный модуль</li>
|
||||
<li>Более 50 инструкций x86-64</li>
|
||||
<li>CSV-логирование</li>
|
||||
</ul>
|
||||
|
||||
<h3>⚠️ Частично реализовано / ограничено</h3>
|
||||
<ul>
|
||||
<li><code>загрузить_адрес</code> (LEA) — только для чисел, не для меток</li>
|
||||
<li>Старшие 8-битные регистры (AH, BH, CH, DH) не поддерживаются</li>
|
||||
<li>Регистры R8–R15 не поддерживаются</li>
|
||||
</ul>
|
||||
|
||||
<h2 id="план">ПЛАН РАЗВИТИЯ</h2>
|
||||
|
||||
<h3>v2.0 (текущая) — Адресация и BSS</h3>
|
||||
<ul>
|
||||
<li>✅ Лексер: <code>[</code>, <code>]</code>, <code>NUMBER</code></li>
|
||||
<li>✅ Парсер: <code>[метка]</code>, <code>[число]</code>, <code>[регистр]</code></li>
|
||||
<li>✅ Pass1: корректный расчёт размера инструкций</li>
|
||||
<li>✅ Pass2: RIP-relative кодирование</li>
|
||||
<li>✅ Абсолютная адресация (метки и числа)</li>
|
||||
<li>✅ Косвенная адресация (<code>[reg]</code>)</li>
|
||||
<li>✅ Секция <code>.бсс</code></li>
|
||||
<li>✅ Рефакторинг энкодера</li>
|
||||
</ul>
|
||||
|
||||
<h3>v3.0 (планируется) — Расширенная адресация</h3>
|
||||
<ul>
|
||||
<li>❌ <code>[reg + disp]</code> — адресация со смещением</li>
|
||||
<li>❌ <code>[reg + reg*scale]</code> — с индексным регистром</li>
|
||||
<li>❌ <code>[reg + reg*scale + disp]</code> — полная SIB-адресация</li>
|
||||
<li>❌ LEA для меток</li>
|
||||
<li>❌ PUSH/POP/CALL/RET</li>
|
||||
</ul>
|
||||
|
||||
<h3>v4.0 (отложено) — Стандартная библиотека</h3>
|
||||
<ul>
|
||||
<li>❌ <code>malloc</code>, <code>free</code></li>
|
||||
<li>❌ <code>strlen</code>, <code>strcmp</code>, <code>memcpy</code></li>
|
||||
<li>❌ <code>putchar</code>, <code>getchar</code></li>
|
||||
</ul>
|
||||
|
||||
<h2 id="ограничения">ОГРАНИЧЕНИЯ</h2>
|
||||
<div class="warning">
|
||||
<ul>
|
||||
<li><strong>Адресация со смещением</strong> — формы <code>[reg+disp]</code>, <code>[reg+reg*scale]</code>, <code>[reg+reg*scale+disp]</code> не реализованы</li>
|
||||
<li><strong>LEA для меток</strong> — <code>загрузить_адрес reg, [метка]</code> не работает, используйте <code>переместить_имм reg, метка</code></li>
|
||||
<li><strong>Старшие 8-битные регистры</strong> — AH, BH, CH, DH не поддерживаются</li>
|
||||
<li><strong>Расширенные регистры</strong> — SPL, BPL, SIL, DIL, а также R8–R15 не поддерживаются</li>
|
||||
<li><strong>Нет умножения и деления</strong> — инструкции MUL/DIV не реализованы</li>
|
||||
<li><strong>Нет операций со стеком</strong> — PUSH/POP/CALL/RET отсутствуют</li>
|
||||
<li><strong>Нет динамической памяти</strong> — нет встроенных malloc/free</li>
|
||||
<li><strong>Нет макросов и условной компиляции</strong></li>
|
||||
<li><strong>Экспериментальный статус</strong> — некоторые инструкции могут быть реализованы не полностью</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p>───────────────────────────────────────────────────────────────────────</p>
|
||||
<p>КВС Ассемблер v2.0 | Экспериментальный проект | 2026</p>
|
||||
<p>Только для образовательных целей. Используйте на свой страх и риск.</p>
|
||||
<p style="margin-top: 10px; font-size: 10px; color: #005500;">
|
||||
> Система готова. Введите команду...
|
||||
<span class="cursor"></span>
|
||||
</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const elements = document.querySelectorAll('h1, h2, h3, p, li, td, th, pre, code');
|
||||
elements.forEach((el, index) => {
|
||||
el.style.opacity = '0';
|
||||
el.style.transition = 'opacity 0.5s ease';
|
||||
setTimeout(() => { el.style.opacity = '1'; }, 100 + index * 10);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
138
README.md
138
README.md
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
- **Полностью русский синтаксис** — все инструкции, регистры и директивы на кириллице
|
||||
- **Генерация исполняемых ELF-файлов** — 64-битные ELF для Linux, готовые к запуску
|
||||
- **Двухпроходная сборка** — традиционная схема с разрешением меток
|
||||
- **Поддержка секций** — разделение на `.текст` (код), `.данные` (данные) и `.бсс` (неинициализированные данные)
|
||||
- **Четырёхпроходная сборка** — традиционная схема с разрешением меток, констант и перекодированием
|
||||
- **Поддержка секций** — разделение на `.текст` (код), `.данные` (данные) и `.бнд` (неинициализированные данные)
|
||||
- **Гибкая адресация памяти**:
|
||||
- абсолютная адресация по меткам `[переменная]`
|
||||
- абсолютная адресация по числовому адресу `[0x402000]`
|
||||
|
|
@ -33,29 +33,31 @@
|
|||
- **CSV-логирование** — детальный файл с соответствием адресов, байтов и исходных команд
|
||||
- **Более 50 инструкций** — полный набор основных команд x86-64
|
||||
- **Минимализм зависимостей** — только стандартная библиотека Python
|
||||
- **Рефакторинг** — кодогенерация вынесена в отдельный модуль `kvs_pass2_encoder.py`
|
||||
|
||||
## 🏗 Архитектура
|
||||
|
||||
Процесс трансляции исходного кода `.квс` в исполняемый файл `.elf` проходит через несколько этапов:
|
||||
Процесс трансляции исходного кода `.квс` в исполняемый файл `.elf` проходит через **6 этапов** (4 прохода + сборка):
|
||||
|
||||
```
|
||||
Исходный файл (.квс)
|
||||
│
|
||||
▼ (kvs_lexer.py)
|
||||
▼ (kvs_lexer.py) ← лексический анализ
|
||||
Файл токенов (.токены)
|
||||
│
|
||||
▼ (kvs_parser.py)
|
||||
▼ (kvs_parser.py) ← синтаксический анализ
|
||||
AST-представление (.аст)
|
||||
│
|
||||
▼ (kvs_pass1.py)
|
||||
Первый проход: размеры, метки (.проход1)
|
||||
▼ (kvs_pass1.py) ← ПРОХОД 1: генерация CSV с заглушками (0xCC)
|
||||
CSV-файл (.csv) ← содержит все байты программы, метки, заглушки
|
||||
│
|
||||
▼ (kvs_pass2.py + kvs_pass2_encoder.py)
|
||||
Второй проход: генерация кода (.csv)
|
||||
▼ (kvs_pass2.py) ← ПРОХОД 2: разрешение меток (замена заглушек)
|
||||
│
|
||||
▼ (kvs_builder.py)
|
||||
ELF-компоновщик (.elf)
|
||||
▼ (kvs_pass3.py) ← ПРОХОД 3: подстановка констант (.константа)
|
||||
│
|
||||
▼ (kvs_pass4.py) ← ПРОХОД 4: перекодирование инструкций
|
||||
│
|
||||
▼ (kvs_builder.py) ← сборка ELF из CSV
|
||||
ELF-файл (.elf)
|
||||
│
|
||||
▼
|
||||
Исполняемый файл!
|
||||
|
|
@ -65,14 +67,39 @@ ELF-компоновщик (.elf)
|
|||
|
||||
| Файл | Назначение |
|
||||
|------|-------------|
|
||||
| `kvs_build.py` | Главный сборочный скрипт |
|
||||
| `kvs_lexer.py` | Лексический анализ, разбор на токены |
|
||||
| `kvs_parser.py` | Синтаксический анализ, построение AST |
|
||||
| `kvs_pass1.py` | Первый проход: вычисление размеров и адресов меток |
|
||||
| `kvs_pass2.py` | Второй проход: обход AST, генерация CSV |
|
||||
| `kvs_pass2_encoder.py` | Кодировщик инструкций (все encode_* функции) |
|
||||
| `kvs_builder.py` | Сборка ELF-файла из CSV |
|
||||
| `kvs_data.py` | Общие данные (регистры, инструкции) |
|
||||
| `kvs_build.py` | Главный сборочный скрипт (запускает все этапы по порядку) |
|
||||
| `kvs_lexer.py` | Лексический анализ, разбор на токены (с поддержкой `[]`, `+`, `-`, `*`) |
|
||||
| `kvs_parser.py` | Синтаксический анализ, построение AST (директивы, метки, инструкции) |
|
||||
| `kvs_data.py` | Общие данные: регистры, таблица инструкций, вспомогательные функции |
|
||||
| `kvs_encoder.py` | Фасад кодировщика (реэкспорт из fixsize + mutsize) |
|
||||
| `kvs_encoder_fixsize.py` | Кодировщик инструкций фиксированного размера |
|
||||
| `kvs_encoder_mutsize.py` | Кодировщик инструкций переменного размера + диспетчер |
|
||||
| `kvs_pass1.py` | Первый проход — вычисление размеров секций, адресов меток, генерация CSV с заглушками |
|
||||
| `kvs_pass2.py` | Второй проход — разрешение меток |
|
||||
| `kvs_pass3.py` | Третий проход — подстановка констант |
|
||||
| `kvs_pass4.py` | Четвёртый проход — перекодирование инструкций |
|
||||
| `kvs_builder.py` | Сборка ELF: чтение CSV, заполнение байтов по адресам, установка прав на исполнение |
|
||||
|
||||
### Почему 4 прохода?
|
||||
|
||||
1. **Первый проход** — неизвестно, какие адреса будут у меток (метка может использоваться до определения). Вместо остановки ставим заглушки `0xCC` и продолжаем.
|
||||
2. **Второй проход** — после того как все адреса меток известны, можно заменить заглушки на реальные значения.
|
||||
3. **Третий проход** — константы могут ссылаться друг на друга и на метки, поэтому их подстановка делается отдельно.
|
||||
4. **Четвёртый проход** — после подстановки чисел адреса/констант нужно перегенерировать машинный код (разные операнды могут менять длину инструкции).
|
||||
|
||||
### Структура CSV-файла
|
||||
|
||||
| Колонка | Назначение |
|
||||
|---------|-------------|
|
||||
| `сегмент` | Имя секции (`.header`, `.text`, `.data`, `.bss`) |
|
||||
| `адрес` | Файловое смещение байта |
|
||||
| `байт` | Исходное значение байта (из pass1) |
|
||||
| `приводящая_метка` | Имена меток, находящихся на этом адресе (через запятую) |
|
||||
| `уводящий_адрес` | Строка `ЗАГЛУШКА имя` для неразрешённых меток |
|
||||
| `исходная_команда` | Исходная инструкция (например, `переход метка`) |
|
||||
| `команда_со_значениями` | Инструкция с подставленными адресами/константами (pass2/pass3) |
|
||||
| `рассчитанный_уводящий_адрес` | Реальный адрес метки (файловое смещение) после разрешения |
|
||||
| `рассчитанный_байт` | Итоговый байт после перекодирования (pass4) |
|
||||
|
||||
## 🔧 Установка
|
||||
|
||||
|
|
@ -142,7 +169,7 @@ Hello, World!
|
|||
.данные ; секция данных (опциональна)
|
||||
; ... инициализированные данные ...
|
||||
|
||||
.бсс ; секция неинициализированных данных (опциональна)
|
||||
.бнд ; секция неинициализированных данных (опциональна)
|
||||
; ... переменные без начального значения ...
|
||||
```
|
||||
|
||||
|
|
@ -182,8 +209,8 @@ _start: ; метка _start
|
|||
переместить_имм рбикс, переменная
|
||||
загрузить раикс, [рбикс]
|
||||
|
||||
; Работа с BSS-секцией
|
||||
.бсс
|
||||
; Работа с BND-секцией
|
||||
.бнд
|
||||
счётчик: .байт 0
|
||||
```
|
||||
|
||||
|
|
@ -286,12 +313,16 @@ _start: ; метка _start
|
|||
|-----------|------------|--------|
|
||||
| `.текст` | Начало секции кода | `.текст` |
|
||||
| `.данные` | Начало секции инициализированных данных | `.данные` |
|
||||
| `.бсс` | Начало секции неинициализированных данных | `.бсс` |
|
||||
| `.бнд` | Начало секции неинициализированных данных | `.бнд` |
|
||||
| `.глобал` | Объявление глобальной метки | `.глобал _start` |
|
||||
| `.строка` | Строка без завершающего нуля | `.строка "Hello"` |
|
||||
| `.строка_нуль` | Строка с завершающим нулём | `.строка_нуль "Hello"` |
|
||||
| `.байт` | Последовательность байтов | `.байт 0x48, 0x65, 108` |
|
||||
| `.константа` | Определение константы | `.константа LEN = 10` |
|
||||
| `.резб` | Резервирование байтов в BND | `.резб 100` |
|
||||
| `.резс` | Резервирование слов в BND | `.резс 50` |
|
||||
| `.рездс` | Резервирование двойных слов в BND | `.рездс 25` |
|
||||
| `.резкс` | Резервирование квадрослов в BND | `.резкс 10` |
|
||||
|
||||
## 📝 Примеры программ
|
||||
|
||||
|
|
@ -366,14 +397,14 @@ loop:
|
|||
вызов_системы
|
||||
```
|
||||
|
||||
### Использование BSS-секции
|
||||
### Использование BND-секции
|
||||
|
||||
```assembly
|
||||
.текст
|
||||
.глобал _start
|
||||
|
||||
_start:
|
||||
; инициализация счётчика в BSS
|
||||
; инициализация счётчика в BND
|
||||
переместить_имм раикс,0
|
||||
сохранить [счётчик], раикс
|
||||
|
||||
|
|
@ -392,7 +423,7 @@ loop:
|
|||
переместить_имм раикс,60
|
||||
вызов_системы
|
||||
|
||||
.бсс
|
||||
.бнд
|
||||
счётчик: .байт 0
|
||||
```
|
||||
|
||||
|
|
@ -473,44 +504,46 @@ gdb ./программа.elf
|
|||
|
||||
### Поддерживается
|
||||
|
||||
- ✅ 64-битные, 32-битные, 16-битные и 8-битные регистры (AL, BL, CL, DL)
|
||||
- ✅ Непосредственная загрузка констант (imm) в регистры
|
||||
- ✅ Сравнение регистров и регистров с константами
|
||||
- ✅ Условные и безусловные переходы (длинные и короткие)
|
||||
- ✅ Арифметические операции (ADD, SUB, INC, DEC)
|
||||
- ✅ Логическая операция TEST
|
||||
- ✅ Системные вызовы Linux (syscall)
|
||||
- ✅ Секции `.текст`, `.данные` и `.бсс`
|
||||
- ✅ Строковые литералы с escape-последовательностями (`\n`, `\t`, `\\`, `\"`)
|
||||
- ✅ Директива `.байт` для raw-данных
|
||||
- ✅ Директива `.константа` для имён констант
|
||||
- ✅ **Абсолютная адресация** по меткам и числовым адресам `[метка]` / `[0x402000]`
|
||||
- ✅ **Косвенная адресация через регистр** `[раикс]`
|
||||
- ✅ RIP-relative кодирование для всех видов адресации
|
||||
- 64-битные, 32-битные, 16-битные и 8-битные регистры (AL, BL, CL, DL)
|
||||
- Непосредственная загрузка констант (imm) в регистры
|
||||
- Сравнение регистров и регистров с константами
|
||||
- Условные и безусловные переходы (длинные и короткие)
|
||||
- Арифметические операции (ADD, SUB, INC, DEC)
|
||||
- Логическая операция TEST
|
||||
- Системные вызовы Linux (syscall)
|
||||
- Секции `.текст`, `.данные` и `.бнд`
|
||||
- Строковые литералы с escape-последовательностями (`\n`, `\t`, `\\`, `\"`)
|
||||
- Директива `.байт` для raw-данных
|
||||
- Директива `.константа` для имён констант
|
||||
- Директивы резервирования `.резб`, `.резс`, `.рездс`, `.резкс`
|
||||
- Абсолютная адресация по меткам и числовым адресам `[метка]` / `[0x402000]`
|
||||
- Косвенная адресация через регистр `[раикс]`
|
||||
- RIP-relative кодирование для всех видов адресации
|
||||
|
||||
### Не поддерживается (в разработке)
|
||||
|
||||
- ❌ Адресация со смещением `[reg + disp]`
|
||||
- ❌ Сложная адресация с индексом `[reg + reg*scale]` и полная SIB-адресация
|
||||
- ❌ Инструкции для работы со стеком (PUSH, POP, CALL, RET)
|
||||
- ❌ Старшие 8-битные регистры (AH, BH, CH, DH) и расширенные младшие (SPL, BPL, SIL, DIL)
|
||||
- ❌ Регистры R8–R15 и их байтовые/словные версии
|
||||
- ❌ Поддержка плавающей запятой (FPU/SSE)
|
||||
- ❌ Многомодульная компиляция
|
||||
- ❌ Макросы
|
||||
- Адресация со смещением `[reg + disp]`
|
||||
- Сложная адресация с индексом `[reg + reg*scale]` и полная SIB-адресация
|
||||
- Инструкции для работы со стеком (PUSH, POP, CALL, RET) — кроме базовых PUSH/POP reg
|
||||
- Поддержка плавающей запятой (FPU/SSE)
|
||||
- Многомодульная компиляция
|
||||
- Макросы
|
||||
|
||||
## 📈 План развития
|
||||
|
||||
### Реализовано (v2.0)
|
||||
|
||||
- Лексер с токенами `[`, `]`, `NUMBER`
|
||||
- Лексер с токенами `[`, `]`, `NUMBER`, `+`, `-`, `*`
|
||||
- Парсер с поддержкой операндов в квадратных скобках
|
||||
- Четырёхпроходная схема сборки
|
||||
- Первый проход с корректным расчётом размера инструкций с памятью
|
||||
- Второй проход с кодированием абсолютной адресации через RIP-relative
|
||||
- Второй проход с разрешением меток
|
||||
- Третий проход с подстановкой констант
|
||||
- Четвёртый проход с перекодированием инструкций
|
||||
- Поддержка меток в операндах памяти `[переменная]`
|
||||
- Поддержка числовых адресов `[0x402000]`
|
||||
- Поддержка косвенной адресации `[регистр]`
|
||||
- Секция `.бсс` для неинициализированных данных
|
||||
- Секция `.бнд` для неинициализированных данных
|
||||
- Рефакторинг: выделение кодировщика в отдельный модуль
|
||||
|
||||
### В планах (v3.0)
|
||||
|
|
@ -518,7 +551,6 @@ gdb ./программа.elf
|
|||
- Адресация со смещением `[reg + disp]`
|
||||
- Сложная адресация с индексом `[reg + reg*scale]`
|
||||
- Полная SIB-адресация `[reg + reg*scale + disp]`
|
||||
- Поддержка инструкций PUSH/POP/CALL/RET для стековых операций
|
||||
- Стандартная библиотека (`libkvs.квс`): malloc, free, strlen, strcmp, print
|
||||
|
||||
## 📄 Лицензия
|
||||
|
|
|
|||
3
todo.txt
3
todo.txt
|
|
@ -250,4 +250,5 @@ Pass2 (шаг 5):
|
|||
изучить работу с кучей
|
||||
|
||||
|
||||
сохранить_байт и загрузить_байт_из_памяти есть в INSTRUCTIONS, но не реализованы в диспетчере encode_instruction
|
||||
сохранить_байт и загрузить_байт_из_памяти есть в INSTRUCTIONS, но не реализованы в диспетчере encode_instruction
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue