RVM32I: мелкие правки + описание

This commit is contained in:
AntKrotov committed 2021-01-29 17:12:05 +03:00
1 parent e762e05400
commit f08b78cccf
7 files changed
+319 -63

No files matched your search

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
+11 -6
View File
@@ -1,7 +1,7 @@
(*
BSD 2-Clause License
Copyright (c) 2020, Anton Krotov
Copyright (c) 2020-2021, Anton Krotov
All rights reserved.
*)
@@ -10,15 +10,20 @@ MODULE Trap;
IMPORT SYSTEM;
CONST
SP = 4;
PROCEDURE [code] sp* (): INTEGER
22, 0, 4; (* MOV R0, SP *)
22, 0, SP; (* MOV R0, SP *)
PROCEDURE [code] syscall* (ptr: INTEGER)
22, 0, 4, (* MOV R0, SP *)
27, 0, 4, (* ADD R0, 4 *)
9, 0, 0, (* LDR32 R0, R0 *)
80, 0, 0; (* SYSCALL R0 *)
22, 0, SP, (* MOV R0, SP *)
27, 0, 4, (* ADD R0, 4 *)
9, 0, 0, (* LDW R0, R0 *)
80, 0, 0; (* SYSCALL R0 *)
PROCEDURE Char (c: CHAR);
+1 -1
View File
@@ -201,7 +201,7 @@ BEGIN
C.Ln;
C.String("Akron Oberon Compiler v"); C.Int(UTILS.vMajor); C.String("."); C.Int2(UTILS.vMinor);
C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit) 2021-01-27");
C.String(" ("); C.Int(UTILS.bit_depth); C.StringLn("-bit) 2021-01-29");
C.StringLn("Copyright (c) 2018-2021, Anton Krotov");
IF inname = "" THEN
+24 -24
View File
@@ -30,23 +30,23 @@ CONST
GPRs = {0 .. 2} + {5 .. numGPRs + 1};
opSTOP = 0; opRET = 1; opENTER = 2; opNEG = 3; opNOT = 4; opABS = 5;
opXCHG = 6; opLDR8 = 7; opLDR16 = 8; opLDR32 = 9; opPUSH = 10; opPUSHC = 11;
opPOP = 12; opJGZ = 13; opJZ = 14; opJNZ = 15; opLLA = 16; opJGA = 17;
opXCHG = 6; opLDB = 7; opLDH = 8; opLDW = 9; opPUSH = 10; opPUSHC = 11;
opPOP = 12; opJGZ = 13; opJZ = 14; opJNZ = 15; opJNA = 16; opJGA = 17;
opJLA = 18; opJMP = 19; opCALL = 20; opCALLI = 21;
opMOV = 22; opMUL = 24; opADD = 26; opSUB = 28; opDIV = 30; opMOD = 32;
opSTR8 = 34; opSTR16 = 36; opSTR32 = 38; opINCL = 40; opEXCL = 42;
opSTB = 34; opSTH = 36; opSTW = 38; opINCL = 40; opEXCL = 42;
opIN = 44; opAND = 46; opOR = 48; opXOR = 50; opASR = 52; opLSR = 54;
opLSL = 56; opROR = 58; opMIN = 60; opMAX = 62; opEQ = 64; opNE = 66;
opLT = 68; opLE = 70; opGT = 72; opGE = 74; opBT = 76;
opMOVC = 23; opMULC = 25; opADDC = 27; opSUBC = 29; opDIVC = 31; opMODC = 33;
opSTR8C = 35; opSTR16C = 37; opSTR32C = 39; opINCLC = 41; opEXCLC = 43;
opSTBC = 35; opSTHC = 37; opSTWC = 39; opINCLC = 41; opEXCLC = 43;
opINC = 45; opANDC = 47; opORC = 49; opXORC = 51; opASRC = 53; opLSRC = 55;
opLSLC = 57; opRORC = 59; opMINC = 61; opMAXC = 63; opEQC = 65; opNEC = 67;
opLTC = 69; opLEC = 71; opGTC = 73; opGEC = 75; opBTC = 77;
opLEA = 78; opLABEL = 79; opSYSCALL = 80; opADDRC = 81; opJNA = 82;
opLEA = 78; opLABEL = 79; opSYSCALL = 80; opADDRC = 81; opLLA = 82;
inf = 7F800000H;
@@ -176,37 +176,37 @@ END sub;
PROCEDURE ldr32 (r1, r2: INTEGER);
BEGIN
Emit(opLDR32, r2 * 256 + r1, 0)
Emit(opLDW, r2 * 256 + r1, 0)
END ldr32;
PROCEDURE ldr16 (r1, r2: INTEGER);
BEGIN
Emit(opLDR16, r2 * 256 + r1, 0)
Emit(opLDH, r2 * 256 + r1, 0)
END ldr16;
PROCEDURE ldr8 (r1, r2: INTEGER);
BEGIN
Emit(opLDR8, r2 * 256 + r1, 0)
Emit(opLDB, r2 * 256 + r1, 0)
END ldr8;
PROCEDURE str32 (r1, r2: INTEGER);
BEGIN
Emit(opSTR32, r1 * 256 + r2, 0)
Emit(opSTW, r1 * 256 + r2, 0)
END str32;
PROCEDURE str16 (r1, r2: INTEGER);
BEGIN
Emit(opSTR16, r1 * 256 + r2, 0)
Emit(opSTH, r1 * 256 + r2, 0)
END str16;
PROCEDURE str8 (r1, r2: INTEGER);
BEGIN
Emit(opSTR8, r1 * 256 + r2, 0)
Emit(opSTB, r1 * 256 + r2, 0)
END str8;
@@ -293,17 +293,17 @@ BEGIN
next := cmd.next(IL.COMMAND);
IF (next.opcode = IL.opSAVE) OR (next.opcode = IL.opSAVE32) OR (next.opcode = IL.opSAVEF) THEN
UnOp(r1);
Emit(opSTR32, BP * 256 + r1, param2 * 4);
Emit(opSTW, BP * 256 + r1, param2 * 4);
drop;
cmd := next
ELSIF next.opcode = IL.opSAVE16 THEN
UnOp(r1);
Emit(opSTR16, BP * 256 + r1, param2 * 4);
Emit(opSTH, BP * 256 + r1, param2 * 4);
drop;
cmd := next
ELSIF next.opcode = IL.opSAVE8 THEN
UnOp(r1);
Emit(opSTR8, BP * 256 + r1, param2 * 4);
Emit(opSTB, BP * 256 + r1, param2 * 4);
drop;
cmd := next
ELSE
@@ -367,17 +367,17 @@ BEGIN
|IL.opSAVEC:
UnOp(r1);
Emit(opSTR32C, r1, param2);
Emit(opSTWC, r1, param2);
drop
|IL.opSAVE8C:
UnOp(r1);
Emit(opSTR8C, r1, param2 MOD 256);
Emit(opSTBC, r1, param2 MOD 256);
drop
|IL.opSAVE16C:
UnOp(r1);
Emit(opSTR16C, r1, param2 MOD 65536);
Emit(opSTHC, r1, param2 MOD 65536);
drop
|IL.opSAVE, IL.opSAVE32, IL.opSAVEF:
@@ -410,11 +410,11 @@ BEGIN
ldr32(r1, r1)
|IL.opVADR, IL.opLLOAD32:
Emit(opLDR32, BP * 256 + GetAnyReg(), param2 * 4)
Emit(opLDW, BP * 256 + GetAnyReg(), param2 * 4)
|IL.opVLOAD32:
r1 := GetAnyReg();
Emit(opLDR32, BP * 256 + r1, param2 * 4);
Emit(opLDW, BP * 256 + r1, param2 * 4);
ldr32(r1, r1)
|IL.opGLOAD16:
@@ -423,11 +423,11 @@ BEGIN
ldr16(r1, r1)
|IL.opLLOAD16:
Emit(opLDR16, BP * 256 + GetAnyReg(), param2 * 4)
Emit(opLDH, BP * 256 + GetAnyReg(), param2 * 4)
|IL.opVLOAD16:
r1 := GetAnyReg();
Emit(opLDR32, BP * 256 + r1, param2 * 4);
Emit(opLDW, BP * 256 + r1, param2 * 4);
ldr16(r1, r1)
|IL.opGLOAD8:
@@ -436,11 +436,11 @@ BEGIN
ldr8(r1, r1)
|IL.opLLOAD8:
Emit(opLDR8, BP * 256 + GetAnyReg(), param2 * 4)
Emit(opLDB, BP * 256 + GetAnyReg(), param2 * 4)
|IL.opVLOAD8:
r1 := GetAnyReg();
Emit(opLDR32, BP * 256 + r1, param2 * 4);
Emit(opLDW, BP * 256 + r1, param2 * 4);
ldr8(r1, r1)
|IL.opLOAD8:
@@ -778,7 +778,7 @@ BEGIN
|IL.opSBOOLC:
UnOp(r1);
Emit(opSTR8C, r1, ORD(param2 # 0));
Emit(opSTBC, r1, ORD(param2 # 0));
drop
|IL.opINCC:
+32 -32
View File
@@ -23,23 +23,23 @@ IMPORT SYSTEM, File, Args, Out, API, HOST, RTL;
CONST
opSTOP = 0; opRET = 1; opENTER = 2; opNEG = 3; opNOT = 4; opABS = 5;
opXCHG = 6; opLDR8 = 7; opLDR16 = 8; opLDR32 = 9; opPUSH = 10; opPUSHC = 11;
opPOP = 12; opJGZ = 13; opJZ = 14; opJNZ = 15; opLLA = 16; opJGA = 17;
opXCHG = 6; opLDB = 7; opLDH = 8; opLDW = 9; opPUSH = 10; opPUSHC = 11;
opPOP = 12; opJGZ = 13; opJZ = 14; opJNZ = 15; opJNA = 16; opJGA = 17;
opJLA = 18; opJMP = 19; opCALL = 20; opCALLI = 21;
opMOV = 22; opMUL = 24; opADD = 26; opSUB = 28; opDIV = 30; opMOD = 32;
opSTR8 = 34; opSTR16 = 36; opSTR32 = 38; opINCL = 40; opEXCL = 42;
opSTB = 34; opSTH = 36; opSTW = 38; opINCL = 40; opEXCL = 42;
opIN = 44; opAND = 46; opOR = 48; opXOR = 50; opASR = 52; opLSR = 54;
opLSL = 56; opROR = 58; opMIN = 60; opMAX = 62; opEQ = 64; opNE = 66;
opLT = 68; opLE = 70; opGT = 72; opGE = 74; opBT = 76;
opMOVC = 23; opMULC = 25; opADDC = 27; opSUBC = 29; opDIVC = 31; opMODC = 33;
opSTR8C = 35; opSTR16C = 37; opSTR32C = 39; opINCLC = 41; opEXCLC = 43;
opSTBC = 35; opSTHC = 37; opSTWC = 39; opINCLC = 41; opEXCLC = 43;
opINC = 45; opANDC = 47; opORC = 49; opXORC = 51; opASRC = 53; opLSRC = 55;
opLSLC = 57; opRORC = 59; opMINC = 61; opMAXC = 63; opEQC = 65; opNEC = 67;
opLTC = 69; opLEC = 71; opGTC = 73; opGEC = 75; opBTC = 77;
opLEA = 78; opLABEL = 79; opSYSCALL = 80; opADDRC = 81; opJNA = 82;
opLEA = 78; opLABEL = 79; opSYSCALL = 80; opADDRC = 81; opLLA = 82;
nREG = 8;
@@ -162,20 +162,20 @@ BEGIN
|opNOT: R[param1] := ORD(-BITS(R[param1]))
|opABS: R[param1] := ABS(R[param1])
|opXCHG: i := R[param1]; R[param1] := R[param2]; R[param2] := i
|opLDR8: i := param1 MOD 256; SYSTEM.GET8(R[param1 DIV 256] + param2, R[i]); R[i] := R[i] MOD 256
|opLDR16: i := param1 MOD 256; SYSTEM.GET16(R[param1 DIV 256] + param2, R[i]); R[i] := R[i] MOD 65536
|opLDR32: SYSTEM.GET32(R[param1 DIV 256] + param2, R[param1 MOD 256])
|opLDB: i := param1 MOD 256; SYSTEM.GET8(R[param1 DIV 256] + param2, R[i]); R[i] := R[i] MOD 256
|opLDH: i := param1 MOD 256; SYSTEM.GET16(R[param1 DIV 256] + param2, R[i]); R[i] := R[i] MOD 65536
|opLDW: SYSTEM.GET32(R[param1 DIV 256] + param2, R[param1 MOD 256])
|opPUSH: DEC(R[SP], 4); SYSTEM.PUT32(R[SP], R[param1])
|opPUSHC: DEC(R[SP], 4); SYSTEM.PUT32(R[SP], param1)
|opJGZ: IF R[param1] > 0 THEN cmd := Labels[cmd.param2] END
|opJZ: IF R[param1] = 0 THEN cmd := Labels[cmd.param2] END
|opJNZ: IF R[param1] # 0 THEN cmd := Labels[cmd.param2] END
|opLLA: SYSTEM.GET32(SYSTEM.ADR(Labels[cmd.param2]), R[param1])
|opJGA: IF R[ACC] > param1 THEN cmd := Labels[cmd.param2] END
|opJLA: IF R[ACC] < param1 THEN cmd := Labels[cmd.param2] END
|opJNA: IF R[ACC] # param1 THEN cmd := Labels[cmd.param2] END
|opJMP: cmd := Labels[cmd.param1]
|opCALL: DEC(R[SP], 4); SYSTEM.PUT(R[SP], cmd); cmd := Labels[cmd.param1]
|opJGZ: IF R[param1] > 0 THEN cmd := Labels[param2] END
|opJZ: IF R[param1] = 0 THEN cmd := Labels[param2] END
|opJNZ: IF R[param1] # 0 THEN cmd := Labels[param2] END
|opLLA: SYSTEM.GET32(SYSTEM.ADR(Labels[param2]), R[param1])
|opJGA: IF R[ACC] > param1 THEN cmd := Labels[param2] END
|opJLA: IF R[ACC] < param1 THEN cmd := Labels[param2] END
|opJNA: IF R[ACC] # param1 THEN cmd := Labels[param2] END
|opJMP: cmd := Labels[param1]
|opCALL: DEC(R[SP], 4); SYSTEM.PUT(R[SP], cmd); cmd := Labels[param1]
|opCALLI: DEC(R[SP], 4); SYSTEM.PUT(R[SP], cmd); SYSTEM.GET(SYSTEM.ADR(R[param1]), cmd)
|opMOV: R[param1] := R[param2]
|opMOVC: R[param1] := param2
@@ -189,12 +189,12 @@ BEGIN
|opDIVC: R[param1] := R[param1] DIV param2
|opMOD: R[param1] := R[param1] MOD R[param2]
|opMODC: R[param1] := R[param1] MOD param2
|opSTR8: SYSTEM.PUT8(R[param1 DIV 256] + param2, R[param1 MOD 256])
|opSTR16: SYSTEM.PUT16(R[param1 DIV 256] + param2, R[param1 MOD 256])
|opSTR32: SYSTEM.PUT32(R[param1 DIV 256] + param2, R[param1 MOD 256])
|opSTR8C: SYSTEM.PUT8(R[param1], param2)
|opSTR16C: SYSTEM.PUT16(R[param1], param2)
|opSTR32C: SYSTEM.PUT32(R[param1], param2)
|opSTB: SYSTEM.PUT8(R[param1 DIV 256] + param2, R[param1 MOD 256])
|opSTH: SYSTEM.PUT16(R[param1 DIV 256] + param2, R[param1 MOD 256])
|opSTW: SYSTEM.PUT32(R[param1 DIV 256] + param2, R[param1 MOD 256])
|opSTBC: SYSTEM.PUT8(R[param1], param2)
|opSTHC: SYSTEM.PUT16(R[param1], param2)
|opSTWC: SYSTEM.PUT32(R[param1], param2)
|opINCL: SYSTEM.GET32(R[param1], i); SYSTEM.PUT32(R[param1], ORD(BITS(i) + {R[param2]}))
|opINCLC: SYSTEM.GET32(R[param1], i); SYSTEM.PUT32(R[param1], ORD(BITS(i) + {param2}))
|opEXCL: SYSTEM.GET32(R[param1], i); SYSTEM.PUT32(R[param1], ORD(BITS(i) - {R[param2]}))
@@ -380,9 +380,9 @@ BEGIN
|opNOT: String("NOT "); Reg(param1)
|opABS: String("ABS "); Reg(param1)
|opXCHG: String("XCHG "); Reg2(param1, param2)
|opLDR8: String("LDR8 "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|opLDR16: String("LDR16 "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|opLDR32: String("LDR32 "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|opLDB: String("LDB "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|opLDH: String("LDH "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|opLDW: String("LDW "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
|opPUSH: String("PUSH "); Reg(param1)
|opPUSHC: String("PUSH "); Hex(param1)
|opJGZ: String("JGZ "); RegL(param1, param2)
@@ -407,12 +407,12 @@ BEGIN
|opDIVC: String("DIV "); RegC(param1, param2)
|opMOD: String("MOD "); Reg2(param1, param2)
|opMODC: String("MOD "); RegC(param1, param2)
|opSTR8: String("STR8 ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|opSTR16: String("STR16 ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|opSTR32: String("STR32 ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|opSTR8C: String("STR8 ["); Reg(param1); String("], "); Hex(param2)
|opSTR16C: String("STR16 ["); Reg(param1); String("], "); Hex(param2)
|opSTR32C: String("STR32 ["); Reg(param1); String("], "); Hex(param2)
|opSTB: String("STB ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|opSTH: String("STH ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|opSTW: String("STW ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
|opSTBC: String("STB ["); Reg(param1); String("], "); Hex(param2)
|opSTHC: String("STH ["); Reg(param1); String("], "); Hex(param2)
|opSTWC: String("STW ["); Reg(param1); String("], "); Hex(param2)
|opINCL: String("INCL "); Reg2(param1, param2)
|opINCLC: String("INCL "); RegC(param1, param2)
|opEXCL: String("EXCL "); Reg2(param1, param2)
+251
View File
@@ -0,0 +1,251 @@
Экспериментальная 32-битная виртуальная машина RVM32I
---------------------------------------------------------------------------------------------------
Использование
Скомпилировать исполнитель/дизассемблер в \tools\RVM32I.ob07 (для Windows32 Console):
Compiler.exe .\tools\RVM32I.ob07 win32con -nochk a
Будет создан файл "\tools\RVM32I.exe".
Компилировать программу в байт-код RVM32I:
Compiler.exe program.ob07 rvm32i [-ram size]
-ram size -- установить размер оперативной памяти для программы в килобайтах 32768..262144
(32..256 Мбайт), по умолчанию 32768 (32 Мбайт)
Будет создан файл "program.bin".
Выпонить программу:
RVM32I.exe program.bin -run
Дизассемблировать программу:
RVM32I.exe program.bin -dis program.asm
Будет создан файл "program.asm".
---------------------------------------------------------------------------------------------------
Архитектура
Регистры
Пять 32-битных регистров:
R0, R1, R2 регистры общего назначения
BP(R3) указатель кадра стэка
SP(R4) указатель стэка (растет вниз)
Нет регистра флагов, нет регистра связи (адрес возврата передается через стэк),
регистр-счетчик команд (PC) -- скрытый.
Нет вещественных регистров, операции с плавающей точкой (single) эмулируются.
Формат кадра стэка
Стэк:
меньше <- |лок. переменные|старый BP|адрес возврата|парам1|парам2|...|парамN| -> больше
адрес(парам1) = BP + 8
адрес(парам2) = BP + 12
...
Параметры передаются через стэк справа налево (как cdecl), результат передается через R0,
вызывающая процедура очищает стэк (как cdecl).
---------------------------------------------------------------------------------------------------
Формат "исполняемого" файла
RECORD
Text: ARRAY i OF RECORD opcode, param1, param2: INTEGER END; (* байт-код *)
Types: ARRAY t OF INTEGER; (* таблица типов-записей *)
Strings: ARRAY s OF BYTE; (* строковые литералы *)
offTypes: INTEGER; (* смещение таблицы типов-записей от начала файла (в байтах) *)
offStrings: INTEGER; (* смещение строковых литералов от начала файла (в байтах) *)
GlobalSize: INTEGER; (* размер глобальных переменных (в словах; слово = 4 байта) *)
HeapStackSize: INTEGER; (* размер области кучи/стэка (в словах; слово = 4 байта) *)
Reserved: ARRAY 8 OF INTEGER (* зарезервировано *)
END
Где:
INTEGER = INT32
i = offTypes DIV 12;
t = (offStrings - offTypes) DIV 4
s = FILE_SIZE - offStrings - 48
---------------------------------------------------------------------------------------------------
Система команд
мнемоника опкод парам1 парам2 действие
STOP 0 0 0 остановить программу
RET 1 0 0 возврат из процедуры (pop PC)
ENTER imm 2 imm 0 push BP; BP := SP; WHILE imm > 0 DO push 0; DEC(imm) END
NEG Rn 3 n 0 Rn := -Rn
NOT Rn 4 n 0 Rn := ORD(-BITS(Rn))
ABS Rn 5 n 0 Rn := ABS(Rn)
XCHG Rn, Rm 6 n m temp := Rn; Rn := Rm; Rm := temp
LDB Rn, [Rm + imm] 7 m*256 + n imm Rn := BytePtr(Rm + imm)^
LDH Rn, [Rm + imm] 8 m*256 + n imm Rn := Card16Ptr(Rm + imm)^
LDW Rn, [Rm + imm] 9 m*256 + n imm Rn := Int32Ptr(Rm + imm)^
PUSH Rn 10 n 0 DEC(SP, 4); Int32Ptr(SP)^ := Rn
PUSH imm 11 imm 0 DEC(SP, 4); Int32Ptr(SP)^ := imm
POP Rn 12 n 0 Rn := Int32Ptr(SP)^; INC(SP, 4)
JGZ Rn, L#hex 13 n hex IF Rn > 0 THEN goto L#hex
JZ Rn, L#hex 14 n hex IF Rn = 0 THEN goto L#hex
JNZ Rn, L#hex 15 n hex IF Rn # 0 THEN goto L#hex
JNA imm, L#hex 16 imm hex IF R0 # imm THEN goto L#hex
JGA imm, L#hex 17 imm hex IF R0 > imm THEN goto L#hex
JLA imm, L#hex 18 imm hex IF R0 < imm THEN goto L#hex
JMP L#hex 19 hex 0 goto L#hex
CALL L#hex 20 hex 0 push PC; goto L#hex
CALL Rn 21 n 0 push PC; goto Rn
MOV Rn, Rm 22 n m Rn := Rm
MOV Rn, imm 23 n imm Rn := imm
MUL Rn, Rm 24 n m Rn := Rn * Rm
MUL Rn, imm 25 n imm Rn := Rm * imm
ADD Rn, Rm 26 n m Rn := Rn + Rm
ADD Rn, imm 27 n imm Rn := Rn + imm
SUB Rn, Rm 28 n m Rn := Rn - Rm
SUB Rn, imm 29 n imm Rn := Rn - imm
DIV Rn, Rm 30 n m Rn := Rn DIV Rm
DIV Rn, imm 31 n imm Rn := Rn DIV imm
MOD Rn, Rm 32 n m Rn := Rn MOD Rm
MOD Rn, imm 33 n imm Rn := Rn MOD imm
STB [Rn + imm], Rm 34 n*256 + m imm BytePtr(Rn + imm)^ := Rm MOD 256
STB [Rn], imm 35 n imm BytePtr(Rn)^ := imm MOD 256
STH [Rn + imm], Rm 36 n*256 + m imm Card16Ptr(Rn + imm)^ := Rm MOD 65536
STH [Rn], imm 37 n imm Card16Ptr(Rn)^ := imm MOD 65536
STW [Rn + imm], Rm 38 n*256 + m imm Int32Ptr(Rn + imm)^ := Rm
STW [Rn], imm 39 n imm Int32Ptr(Rn)^ := imm
INCL Rn, Rm 40 n m Int32Ptr(Rn)^ := ORD(BITS(Int32Ptr(Rn)^) + {Rm})
INCL Rn, imm 41 n imm Int32Ptr(Rn)^ := ORD(BITS(Int32Ptr(Rn)^) + {imm})
EXCL Rn, Rm 42 n m Int32Ptr(Rn)^ := ORD(BITS(Int32Ptr(Rn)^) - {Rm})
EXCL Rn, imm 43 n imm Int32Ptr(Rn)^ := ORD(BITS(Int32Ptr(Rn)^) - {imm})
IN Rn, Rm 44 n m Rn := ORD(Rn IN Rm)
IN Rn, imm 45 n imm Rn := ORD(Rn IN imm)
AND Rn, Rm 46 n m Rn := ORD(BITS(Rn) * BITS(Rm))
AND Rn, imm 47 n imm Rn := ORD(BITS(Rn) * BITS(imm))
OR Rn, Rm 48 n m Rn := ORD(BITS(Rn) + BITS(Rm))
OR Rn, imm 49 n imm Rn := ORD(BITS(Rn) + BITS(imm))
XOR Rn, Rm 50 n m Rn := ORD(BITS(Rn) / BITS(Rm))
XOR Rn, imm 51 n imm Rn := ORD(BITS(Rn) / BITS(imm))
ASR Rn, Rm 52 n m Rn := ASR(Rn, Rm)
ASR Rn, imm 53 n imm Rn := ASR(Rn, imm)
LSR Rn, Rm 54 n m Rn := LSR(Rn, Rm)
LSR Rn, imm 55 n imm Rn := LSR(Rn, imm)
LSL Rn, Rm 56 n m Rn := LSL(Rn, Rm)
LSL Rn, imm 57 n imm Rn := LSL(Rn, imm)
ROR Rn, Rm 58 n m Rn := ROR(Rn, Rm)
ROR Rn, imm 59 n imm Rn := ROR(Rn, imm)
MIN Rn, Rm 60 n m IF Rm < Rn THEN Rn := Rm
MIN Rn, imm 61 n imm IF imm < Rn THEN Rn := imm
MAX Rn, Rm 62 n m IF Rm > Rn THEN Rn := Rm
MAX Rn, imm 63 n imm IF imm > Rn THEN Rn := imm
EQ Rn, Rm 64 n m Rn := ORD(Rn = Rm)
EQ Rn, imm 65 n imm Rn := ORD(Rn = imm)
NE Rn, Rm 66 n m Rn := ORD(Rn # Rm)
NE Rn, imm 67 n imm Rn := ORD(Rn # imm)
LT Rn, Rm 68 n m Rn := ORD(Rn < Rm)
LT Rn, imm 69 n imm Rn := ORD(Rn < imm)
LE Rn, Rm 70 n m Rn := ORD(Rn <= Rm)
LE Rn, imm 71 n imm Rn := ORD(Rn <= imm)
GT Rn, Rm 72 n m Rn := ORD(Rn > Rm)
GT Rn, imm 73 n imm Rn := ORD(Rn > imm)
GE Rn, Rm 74 n m Rn := ORD(Rn >= Rm)
GE Rn, imm 75 n imm Rn := ORD(Rn >= imm)
BT Rn, Rm 76 n m Rn := ORD((0 <= Rn) & (Rn < Rm))
BT Rn, imm 77 n imm Rn := ORD((0 <= Rn) & (Rn < imm))
LEA Rn, TYPES + imm 78 n + 000H imm Rn := imm + address(TYPES)
LEA Rn, STRINGS + imm 78 n + 100H imm Rn := imm + address(STRINGS)
LEA Rn, GLOBAL + imm 78 n + 200H imm Rn := imm + address(GLOBAL)
LEA Rn, HEAP + imm 78 n + 300H imm Rn := imm + address(HEAP)
LEA Rn, STACK + imm 78 n + 400H imm Rn := imm + address(STACK)
L#hex: 79 hex 0 метка:
SYSCALL Rn 80 n 0 системный вызов; Rn содержит адрес параметров
ADD Rn, Rm, imm 81 m*256 + n imm Rn := Rm + imm
LLA Rn, L#hex 82 n hex Rn := address(L#hex)
---------------------------------------------------------------------------------------------------
Общая структура программы
CODE: (* машинный код *)
LEA SP, STACK + 0x00000000 (* точка входа; инициализация регистра SP *)
...
STOP (* конец программы *)
TYPES: (* таблица типов-записей *)
WORD 0x00000000, 0x00000000, 0x00000000, 0x00000000
WORD 0x00000002, 0x00000002, 0x00000002, 0x00000002
WORD 0x00000000, 0x00000006, 0x00000000, 0x00000000
WORD 0x00000002, 0x00000000, 0x0000000D, 0x0000000E
WORD 0x0000000C, 0x0000000E, 0x0000000C, 0x00000000
WORD 0x00000000, 0x0000000C, 0x0000000C, 0x00000016
WORD 0x00000000, 0x0000000C, 0x0000000C, 0x0000000C
WORD 0x00000000, 0x00000000, 0x0000000C, 0x0000000C
WORD 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000C
WORD 0x0000000C, 0x0000000C, 0x00000000, 0x00000000
WORD 0x0000000C, 0x0000000C, 0x0000000C, 0x00000000
WORD 0x00000000, 0x0000000C, 0x0000002D, 0x0000002D
WORD 0x0000002D, 0x00000030, 0x00000030, 0x00000030
WORD 0x00000030, 0x0000002D, 0x00000000, 0x00000000
WORD 0x0000000A, 0x00000000, 0x00000002, 0x00000000
WORD 0x00000000, 0x00000000, 0x00000000, 0x00000000
WORD 0x00000000, 0x00000000, 0x00000000, 0x00000000
WORD 0x00000000, 0x0000000C, 0x0000000C, 0x00000000
WORD 0x00000000, 0x0000000C, 0x00000049, 0x00000049
WORD 0x00000049, 0x0000004C, 0x0000004C, 0x0000004C
WORD 0x00000049, 0x0000000C, 0x00000000, 0x0000000C
WORD 0x00000053, 0x00000053, 0x00000053, 0x00000053
WORD 0x0000000C, 0x00000000, 0x00000000, 0x00000000
WORD 0x00000006, 0x0000000C
STRINGS: (* строковые литералы *)
BYTE 0x46, 0x50, 0x55, 0x00, 0x54, 0x72, 0x61, 0x70
BYTE 0x00, 0x0D, 0x0A, 0x00, 0x61, 0x73, 0x73, 0x65
BYTE 0x72, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x66, 0x61
BYTE 0x69, 0x6C, 0x75, 0x72, 0x65, 0x00, 0x4E, 0x49
BYTE 0x4C, 0x20, 0x64, 0x65, 0x72, 0x65, 0x66, 0x65
BYTE 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x62, 0x61
BYTE 0x64, 0x20, 0x64, 0x69, 0x76, 0x69, 0x73, 0x6F
BYTE 0x72, 0x00, 0x4E, 0x49, 0x4C, 0x20, 0x70, 0x72
BYTE 0x6F, 0x63, 0x65, 0x64, 0x75, 0x72, 0x65, 0x20
BYTE 0x63, 0x61, 0x6C, 0x6C, 0x00, 0x74, 0x79, 0x70
BYTE 0x65, 0x20, 0x67, 0x75, 0x61, 0x72, 0x64, 0x20
BYTE 0x65, 0x72, 0x72, 0x6F, 0x72, 0x00, 0x69, 0x6E
BYTE 0x64, 0x65, 0x78, 0x20, 0x6F, 0x75, 0x74, 0x20
BYTE 0x6F, 0x66, 0x20, 0x72, 0x61, 0x6E, 0x67, 0x65
BYTE 0x00, 0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64
BYTE 0x20, 0x43, 0x41, 0x53, 0x45, 0x00, 0x61, 0x72
BYTE 0x72, 0x61, 0x79, 0x20, 0x61, 0x73, 0x73, 0x69
BYTE 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x65
BYTE 0x72, 0x72, 0x6F, 0x72, 0x00, 0x43, 0x48, 0x52
BYTE 0x20, 0x6F, 0x75, 0x74, 0x20, 0x6F, 0x66, 0x20
BYTE 0x72, 0x61, 0x6E, 0x67, 0x65, 0x00, 0x57, 0x43
BYTE 0x48, 0x52, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x6F
BYTE 0x66, 0x20, 0x72, 0x61, 0x6E, 0x67, 0x65, 0x00
BYTE 0x42, 0x59, 0x54, 0x45, 0x20, 0x6F, 0x75, 0x74
BYTE 0x20, 0x6F, 0x66, 0x20, 0x72, 0x61, 0x6E, 0x67
BYTE 0x65, 0x00, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x20
BYTE 0x28, 0x00, 0x29, 0x3A, 0x20, 0x00, 0x6D, 0x6F
BYTE 0x64, 0x75, 0x6C, 0x65, 0x3A, 0x20, 0x00, 0x6C
BYTE 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x00, 0x52, 0x54
BYTE 0x4C, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x00
GLOBAL:
WORDS 0x00000004 (* размер глобальных переменных в словах (слово = 4 байта) *)
HEAP:
WORDS 0x007FFFBF (* размер области кучи/стэка в словах (слово = 4 байта) *)
STACK:
WORDS 8 (* зарезервировано *)
---------------------------------------------------------------------------------------------------