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