EnotVM

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » EnotVM » EnotVM » Генератор асемблерного коду (FASM) для EnotVM32


Генератор асемблерного коду (FASM) для EnotVM32

Сообщений 1 страница 3 из 3

1

Генератор асемблерного коду (FASM) для EnotVM32

GenBP4.7z -
http://forumstatic.ru/files/001c/77/27/56695.7z

Вихідний код для https://chat.deepseek.com/
Generator.txt
https://forumstatic.ru/files/001c/77/27/49421.txt

0

2

Документація користувача EnotVM32 від https://chat.deepseek.com/

    Документація генератора коду для EnotVM32 
(на базі Turbo Pascal 4.0, ціль – FASM + Macros.asm)

   # 1. Загальна архітектура генератора
Генератор складається з кількох модулів, що реалізують рівневу модель:
- "Рівень даних" – типи та константи регістрів (`uGenTR`).
- "Базовий рівень" – робота з файлом, допоміжні функції (`uGen0`).
- "Рівень команд із числовими операндами" – мнемоніки, які приймають
числа (`uGenV`).
- "Рівень команд із мітками" – ті самі мнемоніки, але з адресами-рядками
(`uGenL`).
- "Рівень програми" – конкретна логіка генерації (ваша програма) знаходиться
в `uGen` і викликається з `uMain`.

Генератор не виконує жодної інтелектуальної роботи (адресації, підрахунку переходів) – він просто створює текстовий файл із макросами FASM, які потім обробляються самим FASM. Тобто це "генератор вихідного коду асемблера", а не прямого бінарного коду.

   # 2. Опис модулів

       2.1. `uGenTR.pas` – регістри та їхні імена
- Оголошує тип `TReg = record id: Byte; Name: string[4]; end;`
- Містить константи для всіх 256 регістрів (довгі назви:
`AA`..`JV`, короткі назви: `A`..`Z`).
- Спеціальні регістри `YA..YH` (232..239), `ZA..ZH` (240..247),
`CMP1`, `CMP2`.
- Використовується всіма іншими модулями для звертання до регістрів
за іменем (наприклад, `A`, `YA`, `CMP1`).

"Приклад оголошення констант:"
```pascal
A : TReg = (id:0;  Name:'A');
YA: TReg = (id:232; Name:'YA');
```

       2.2. `uGen0.pas` – базові операції з вихідним файлом
- "`InitGen`", "`FinalGen`" – відкривають/закривають текстовий
файл `BOOT.asm`.
- "`AddStr(s)`" – записує рядок у файл.
- "`REM(s)`" – додає коментар (`; ...`).
- "`VK`" – порожній рядок.
- "`Label_(L)`" – записує мітку (`L:`).
- "`format_binary_as_bin`" – вставляє директиву `format binary as 'bin'`.
- "`include_Macros_asm`" – вставляє `include 'Macros.asm'`.
- Допоміжні функції "`IntToStr`", "`IntToHex`"
(не використовуються в ядрі, але доступні для налагодження).

Всі наступні рівні викликають тільки процедури з цього модуля для
формування вихідного тексту.

       2.3. `uGenV.pas` – команди з числовими операндами
Містить процедури, які генерують рядки з макросами FASM, що приймають
"числові значення" (константи, адреси) або не мають параметрів.

"Категорії процедур:"
- "Пересилання": `MOVrv(Rg, Value)`, `MOVrr(Rg1, Rg2)`, `MOVrm(Rg, Addr)`,
`MOVrmr`, `MOVmr`, `MOVmrr`, `MOV2rm`, `MOV2mr`, `MOV2rmr`, `MOV2mrr`,
`MOV1rm`, `MOV1mr`, `MOV1rmr`, `MOV1mrr`.
- "Арифметика/логіка": `ADDrr`, `SUBrr`, `MULrr`, `DIVrr`, `MODrr`, `INCr`,
`DECr`, `ANDrr`, `ORrr`, `XORrr`, `NOTr`, `SHLrr`, `SHRrr`, `CMPrr`.
- "Переходи": `CALLa(Addr)`, `CALLr(Rg)`, `RET_`, `GOTOa(Addr)`,
`GOTOr(Rg)`, умовні знакові (`GOTOsaIs`, `GOTOsaNotIs`, ...) та
беззнакові (`GOTOuaMoreIs`, `GOTOuaLess`).
- "Стек": `PUSHr`, `POPr`, `PUSHrsvr`, `POPrsvr`.
- "Системні виклики EXTR": `EXTR(Value)`, а також окремі
процедури-обгортки (`WritelnStr`, `EndProgram`, `Readln0` і т.д.).
- "Рядкові макроси": `VarStrB(MaxSize, Text)`, `VarStrW`, `VarStr3B`,
`VarStrDW`, `ContStrB`, `ContStrW`, `ContStr3B`, `ContStrDW`.
- "Копіювання пам’яті": `CopyMainToMain`, `CopyMainToExt`,
`CopyExtToMain`, `CopyExtToExt`.

Усі вони просто формують відповідний текст, наприклад:
```pascal
procedure MOVrv(Rg: TReg; Value: Longint);
begin AddStr('    MOVrv ' + Rg.Name + ', ' + IntToStr(Value)); end;
```

       2.4. `uGenL.pas` – команди з мітками
Аналогічний `uGenV`, але операндами виступають "імена міток"
(тип `string255`). Це дозволяє писати:
```pascal
MOVrl(YA, 'hello1');    // MOVrv YA, hello1
GOTOslMoreIs('loop');   // GOTOsaMoreIs loop
```
Список процедур:
`MOVrl`, `MOVrml`, `MOVmlr`, `MOVmlrr`, `MOV2rml`, `MOV2mlr`,
`MOV1rml`, `MOV1mlr`, `CALLl`, `GOTOl`, `GOTOslIs`, `GOTOslNotIs`, `GOTOslMoreIs`, `GOTOslLess`, `GOTOulMoreIs`, `GOTOulLess`.

       2.5. `uGen.pas` – сама програма генерації
Це "єдине місце", яке потрібно редагувати для створення нової програми.
Містить процедуру `StartGenerator`, де послідовно викликаються потрібні
команди.

"Приклад з Hello World:"
```pascal
procedure StartGenerator;
begin
  InitGen;
  REM('Програма від ...');
  format_binary_as_bin;
  include_Macros_asm;
  MOVrl(YA, 'hello1');
  WritelnStr;
  MOVrl(YA, 'hello2');
  WritelnStr;
  Readln0;
  EndProgram;
  Label_('hello1');
  AddStr('db 1,13,13,''Hello, World!''');
  Label_('hello2');
  ConstStrB('Hello, World!');
  FinalGen;
end;
```

       2.6. `uMain.pas` та `ProjectP.pas`
- `uMain` містить `StartProgram`, яка викликає `StartGenerator`.
- `ProjectP` – головна програма, яка виконує `InitProgram;
StartProgram; FinalProgram;`.

   # 3. Робота з рядками (макроси VarStr/ContStr)
У вихідному коді рядки зберігаються в одному з чотирьох форматів
(тип 1, 2, 3, 4), що відрізняються розрядністю полів довжини.
Генератор пропонує дві групи процедур:

- "VarStrB / VarStrW / VarStr3B / VarStrDW" – примусово задається максимальний
розмір буфера. Використовуйте, коли розмір відомий заздалегідь.
- "ContStrB / ContStrW / ContStr3B / ContStrDW" – розмір обчислюється
автоматично (за фактичною довжиною рядка). Простіше, але менш гнучко, якщо треба резервувати місце.

У згенерованому `.asm`-файлі це виглядає як виклик відповідного макросу,
наприклад:
```asm
hello2: ContStrB 'Hello, World!'
```

   # 4. Як створити нову програму за допомогою генератора
1. Відредагуйте процедуру `StartGenerator` в модулі `uGen.pas`.
2. Використовуйте процедури з `uGenV` та `uGenL`, щоб описати алгоритм.
3. Для рядкових констант застосовуйте `ContStr...` або `VarStr...`.
4. Позначайте мітки через `Label_('ім'я')`.
5. Скомпілюйте проект `ProjectP.pas` – отримаєте `ProjectP.exe`.
6. Запустіть `ProjectP.exe` – у поточній папці з’явиться `BOOT.asm`.
7. Відкомпілюйте `BOOT.asm` за допомогою FASM (наприклад, `fasm BOOT.asm
BOOT.bin`).
8. Запустіть `EnotVM32.exe` (попередньо скопіювавши `BOOT.bin`
у папку з емулятором).

   # 5. Обмеження та примітки
- Генератор не перевіряє семантику (наприклад, чи існує мітка `hello1`).
Це робота FASM.
- Усі адреси та числа задаються безпосередньо користувачем.
Жодних обчислень адрес чи підрахунку довжин команд генератор не
виконує – він покладається на FASM.
- Модулі `uGenV` та `uGenL` навмисно розділені, щоб підкреслити різницю
між «числовим» та «мітковим» інтерфейсом. У майбутньому це спростить
перехід до прямого генератора бінарного коду.

   # 6. Перехід до наступного етапу (Delphi, прямий бінарний генератор)
Коли ви будете готові повернутися до прямого генератора `BOOT.bin`
(рівні 0, 1, …), цей генератор залишиться як засіб налагодження
та прототипування. Новий генератор використовуватиме `uTSSB` як
буфер та будуватиме бінарний файл напряму, вирішуючи адреси
міток самостійно.

0

3


Вы здесь » EnotVM » EnotVM » Генератор асемблерного коду (FASM) для EnotVM32