diff --git a/Compiler b/Compiler index b5df7ca..0ffeedf 100644 Binary files a/Compiler and b/Compiler differ diff --git a/Compiler.exe b/Compiler.exe index 24763d7..8a208d7 100644 Binary files a/Compiler.exe and b/Compiler.exe differ diff --git a/lib/RVM32I/Trap.ob07 b/lib/RVM32I/Trap.ob07 index 55bff41..a76be38 100644 --- a/lib/RVM32I/Trap.ob07 +++ b/lib/RVM32I/Trap.ob07 @@ -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); diff --git a/source/Compiler.ob07 b/source/Compiler.ob07 index 4d0d1c9..13e4306 100644 --- a/source/Compiler.ob07 +++ b/source/Compiler.ob07 @@ -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 diff --git a/source/RVM32I.ob07 b/source/RVM32I.ob07 index 89052d1..ecded4e 100644 --- a/source/RVM32I.ob07 +++ b/source/RVM32I.ob07 @@ -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: diff --git a/tools/RVM32I.ob07 b/tools/RVM32I.ob07 index 14fd916..9685355 100644 --- a/tools/RVM32I.ob07 +++ b/tools/RVM32I.ob07 @@ -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) diff --git a/tools/RVM32I.txt b/tools/RVM32I.txt new file mode 100644 index 0000000..1bb47a3 --- /dev/null +++ b/tools/RVM32I.txt @@ -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 (* зарезервировано *) +---------------------------------------------------------------------------------------------------