Детальна документація користувача та розробника EnotVM32 від https://chat.qwen.ai Повна документація EnotVM32 1. Загальний опис EnotVM32 — це віртуальний 32-бітний процесор з регістрово-стековою архітектурою. Емулятор створений з акцентом на простоту перенесення на інші платформи, схожість із синтаксисом ASM32 та можливість використання асемблера FASM (Flat Assembler) для написання програм. Особливість архітектури: EnotVM32 є 32-бітним емулятором, але у 16-бітних середовищах (наприклад, Turbo Pascal / DOS) для збереження швидкодії використовуються 16-бітні адреси переходів. --- 2. Архітектура віртуального процесора 2.1. Регістри У процесора 256 регістрів загального призначення. Кожен регістр має розмірність Int32 (32-бітне знакове ціле). Короткі імена: `A` ... `Z` (ідентифікатори `0` ... `25`). Довгі імена: `AA` ... `JV`. (Якщо ім'я зайняте середовищем FASM, додається `_`, наприклад `AH_`, `AL_`). Спеціальні регістри для EXTR: `YA` ... `YH` (232 ... 239) — для передачі вхідних параметрів. `ZA` ... `ZH` (240 ... 247) — для повернення результатів. Регістри порівняння: `CMP1` (254) та `CMP2` (255). Використовуються для умовних переходів. Службові регістри: `RgEIP` — вказівник інструкції (лічильник команд). `RgESP` — вказівник стеку. (Вони недоступні для прямого читання/запису через звичайні команди `MOV`). 2.2. Пам'ять та Стек Основна пам'ять (RAM): Лінійний масив байтів. Розмір: 48 КБ (49152 байт, індекси `0..49151`). Виконання програми завжди починається з адреси `0`. Стек (RAMc): Окремий масив для стеку. Розмір: 255 елементів. Важливо: Стек зберігає елементи типу `Int32` (4 байти). `RgESP` індексує елементи, а не байти! Команди `PUSH/POP` змінюють `RgESP` на `1`. 2.3. Розширена пам'ять Для роботи з об'ємами даних, що перевищують 48 КБ, передбачена розширена пам'ять. Розмір однієї сторінки: 48 КБ. Кількість сторінок: до 10 (індекси `0..cMaxPagesOfRAMext`). --- 3. Система команд (ISA) 3.1. Команди пересилання даних (MOV) На відміну від класичного x86, де `MOV` універсальний, в EnotVM32 розмірність даних задається окремою командою: 32-бітні (DWORD): `MOVrv`, `MOVrr`, `MOVrm`, `MOVrmr`, `MOVmr`, `MOVmrr` 16-бітні (WORD): `MOV2rm`, `MOV2rmr`, `MOV2mr`, `MOV2mrr` (доповнюються нулями до 32 біт). 8-бітні (BYTE): `MOV1rm`, `MOV1rmr`, `MOV1mr`, `MOV1mrr` (доповнюються нулями до 32 біт). 3.2. Керування потоком `CALLa DWA1` / `CALLr Rg1` — виклик підпрограми (адреса або регістр). `RET` — повернення з підпрограми. `GOTOa DWA1` / `GOTOr Rg1` — безумовний перехід (аналог `JMP`). 3.3. Умовні переходи Порівнюються тільки регістри `CMP1` та `CMP2` (знакове порівняння). `GOTOsa...` — перехід за абсолютною адресою. `GOTOsr...` — перехід за адресою з регістру. Умови: `Is` (=), `NotIs` (<>), `MoreIs` (>=), `Less` (<). 3.4. Робота зі стеком `PUSHr Rg1` / `POPr Rg1` — для одного регістру. `PUSHrsvr Rg1, Rg2` / `POPrsvr Rg1, Rg2` — збереження/відновлення діапазону регістрів (дуже зручно для прологів/епілогів функцій). 3.5. Арифметика та логіка Працюють лише з 32-бітними регістрами. Формат: `Rg1 = Rg1 op Rg2`. Арифметика: `ADD`, `SUB`, `MUL`, `DIV`, `MOD`, `INC`, `DEC`. Логіка: `AND`, `OR`, `XOR`, `NOT`, `SHL`, `SHR`. `CMPrr Rg1, Rg2` — завантажує `Rg1` в `CMP1`, а `Rg2` в `CMP2` для подальших умовних переходів. --- 4. Системні виклики (EXTR) Команда `$2A` (`EXTR Adr1, Adr2`) — це аналог переривань (INT) або BIOS. Вона викликає розширення емулятора. Адресація відбувається за групами за номером типа word, який "розбивається" на старший та молодший байти Adr1 та Adr2 (`Adr2` визначає групу, `Adr1` — номер функції). Група 0 (0-255): Системні функції | Код | Опис | | | 0 | `EXTR_NOP` (Пуста команда для тестів) | | 1 | `CheckEXTR` (Перевірка існування команди EXTR) | | 2 | `HALT` (Негайний вихід, код виходу в `YA`) | | 3 | `Writeln_GetTimeStr` (Вивести поточний час) | | 4 | `Readln0` (Очікування натискання Enter) | | 5 | `VersionEnotVM` (Повертає версію емулятора в `ZA`) | | 6 | `Writeln0` (Вивести порожній рядок) | | 7 | `CONT` (Пауза: очікує введення 'cont' або 'CONT') | | 8 | `WritelnYA` (Вивести вміст регістра `YA` у Dec та Hex) | | 9 | `Wait00secTime...` (Очікування 00 секунди та вивід часу) | | 10 | `EndProgram` (Коректне завершення роботи двигуна) | | 11-17| Інформація про середовище, розміри RAM та стеку. | Група 1 (256-511): Робота з рядками 256: `WritelnStr` — вивести рядок з переходом на новий. 257: `WriteStr` — вивести рядок без переходу. Вказівник на структуру рядка передається через регістр `YA`. Група 2 (512-767): Робота з розширеною пам'яттю 512: `CopyMainToMain` (Копіювання в основній пам'яті). 513: `CopyMainToExt` (З основної в розширену). 514: `CopyExtToMain` (З розширеної в основну). 515: `CopyExtToExt` (Між сторінками розширеної пам'яті). Група 3 (768-1023): Беззнакові умовні переходи Аналогічні переходам з Групи 1, але порівняння `CMP1` та `CMP2` відбувається як беззнакових 32-бітних чисел (`GOTOuaMoreIs`, `GOTOuaLess`, `GOTOurMoreIs`, `GOTOurLess`). --- 5. Формати рядків (для EXTR 256/257) Рядки в EnotVM32 зберігаються у пам'яті зі спеціальним заголовком, який вказує на тип та розмір. Програма зчитує байт за адресою з `YA`: Тип 1: 8-бітні розміри (FullSize, CurSize). Тип 2: 16-бітні розміри. Тип 3: 24-бітні розміри. Тип 4: 32-бітні розміри. Дані рядка починаються після заголовка і можуть бути більшими за 255 байт (емулятор виводить їх частинами). --- 6. Встановлення та запуск емулятора 1. Розпакування: Розпакуйте архів `EnotVM32` на диск `C:\`. Структура папки має виглядати так: `C:\EnotVM32\BP4_001\` (де `BP4` вказує на те, що емулятор скомпільований у Turbo Pascal 4.0). 2. Підготовка програми: Перейдіть у папку `C:\EnotVM32\BP4_001\Examples\`, виберіть будь-який приклад (файл `BOOT.bin`) і скопіюйте його в корінь папки `C:\EnotVM32\BP4_001\`. 3. Запуск: Запустіть файл `EnotVM32.EXE`. Емулятор автоматично завантажить `BOOT.bin` в пам'ять і почне виконання з адреси 0. --- 7. Розробка програм для EnotVM32 (FASM) Для написання програм рекомендується використовувати flat assembler (FASM) версії 1.73.25 або новішої. Налаштування середовища: 1. Завантажте FASM з офіційного сайту (https://flatassembler.net/). 2. Розпакуйте його у папку `C:\FASMdos\` (для DOS) або `C:\FASMwin\` (для Windows). 3. Переконайтеся, що у папці з вашим проектом обов'язково присутні файли: `Macros.asm` — файл макросів, який описує ідентифікатори регістрів (`AA`, `YA`, `CMP1` тощо) та мнемоніки команд EnotVM32. `BOOT.asm` — шаблонний файл для написання вашої програми. Компіляція: Ви можете редагувати `BOOT.asm` у будь-якому текстовому редакторі. Для зручності створені bat-файли: `EditDos.Bat` / `EditWin.Bat` — для відкриття редактора. `ComplDos.Bat` / `ComplWin.Bat` — для компіляції. Важливо: Bat-файли компіляції за замовчуванням видаляють старий `BOOT.bin` (`del BOOT.bin`). Якщо ви хочете зберегти стару версію, закоментуйте цей рядок (`REM del BOOT.bin`). Після успішної компіляції з'явиться оновлений файл `BOOT.bin`, який готовий до запуску в `EnotVM32.EXE`.