mirror of
https://github.com/AntKrotov/oberon-07-compiler.git
synced 2026-10-05 09:45:47 +00:00
RVM32I: мелкие правки + описание
This commit is contained in:
1 parent
e762e05400
commit
f08b78cccf
7 files changed
+319
-63
No files matched your search
Binary file not shown.
+11
-6
@@ -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);
|
||||
|
||||
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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 (* зарезервировано *)
|
||||
---------------------------------------------------------------------------------------------------
|
||||
Reference in new issue
Block a user