Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
8859 | leency | 1 | |
2 | Экспериментальная 32/64-битная виртуальная машина RVMxI |
||
3 | --------------------------------------------------------------------------------------------------- |
||
4 | |||
5 | Использование |
||
6 | |||
7 | Скомпилировать исполнитель/дизассемблер в .\tools\RVMxI.ob07 |
||
8 | для Windows32/64 Console или Linux32/64: |
||
9 | |||
10 | Compiler.exe .\tools\RVMxI.ob07 win32con -nochk a -out RVMxI.exe |
||
11 | Compiler.exe .\tools\RVMxI.ob07 win64con -nochk a -out RVMxI.exe |
||
12 | Compiler ./tools/RVMxI.ob07 linux32exe -nochk a -out RVMxI |
||
13 | Compiler ./tools/RVMxI.ob07 linux64exe -nochk a -out RVMxI |
||
14 | |||
15 | Будет создан файл "RVMxI.exe" и/или "RVMxI". |
||
16 | |||
17 | Компилировать программу в байт-код RVMxI: |
||
18 | |||
19 | Compiler.exe program.ob07 rvm32i [-ram size] [-def host_linux] |
||
20 | Compiler.exe program.ob07 rvm64i [-ram size] [-def host_linux] |
||
21 | -ram size -- установить размер оперативной памяти для программы в килобайтах 32768..262144 |
||
22 | (32..256 Мбайт), по умолчанию 32768 (32 Мбайт) |
||
23 | -def host_linux -- если байт-код будет исполняться на Linux (по умолчанию -- Windows) |
||
24 | |||
25 | Будет создан файл "program.bin". |
||
26 | |||
27 | Выпонить программу: |
||
28 | |||
29 | RVMxI.exe program.bin -run <параметры> |
||
30 | |||
31 | Дизассемблировать программу: |
||
32 | |||
33 | RVMxI.exe program.bin -dis program.txt |
||
34 | |||
35 | Будет создан файл "program.txt". |
||
36 | --------------------------------------------------------------------------------------------------- |
||
37 | |||
38 | Архитектура |
||
39 | |||
40 | Регистры |
||
41 | |||
42 | Не меньше пяти 32/64-битных регистров: |
||
43 | |||
44 | R0, R1, R2 регистры общего назначения |
||
45 | BP(R3) указатель кадра стэка |
||
46 | SP(R4) указатель стэка (растет вниз) |
||
47 | |||
48 | R5, R6... регистры общего назначения (опционально) |
||
49 | |||
50 | Регистра связи нет (адрес возврата передается через стэк), |
||
51 | регистр-счетчик команд (PC) -- скрытый, регистр флагов -- скрытый. |
||
52 | |||
53 | Нет вещественных регистров, операции с плавающей точкой (single (32-бит) или double (64-бит)) |
||
54 | эмулируются. |
||
55 | |||
56 | Формат кадра стэка |
||
57 | |||
58 | Стэк: |
||
59 | |||
60 | меньше <- |лок. переменные|старый BP|адрес возврата|парам1|парам2|...|парамN| -> больше |
||
61 | |||
62 | (* 32 бита *) |
||
63 | адрес(парам1) = BP + 8 |
||
64 | адрес(парам2) = BP + 12 |
||
65 | ... |
||
66 | |||
67 | (* 64 бита *) |
||
68 | адрес(парам1) = BP + 16 |
||
69 | адрес(парам2) = BP + 24 |
||
70 | ... |
||
71 | |||
72 | Параметры передаются через стэк справа налево (как cdecl), результат передается через R0, |
||
73 | вызывающая процедура очищает стэк (как cdecl). |
||
74 | |||
75 | --------------------------------------------------------------------------------------------------- |
||
76 | |||
77 | Формат "исполняемого" файла |
||
78 | |||
79 | RECORD |
||
80 | |||
81 | Text: ARRAY i OF RECORD opcode, param1, param2: INTEGER END; (* байт-код *) |
||
82 | Types: ARRAY t OF INTEGER; (* таблица типов-записей *) |
||
83 | Strings: ARRAY s OF BYTE; (* строковые литералы *) |
||
84 | offTypes: INTEGER; (* смещение таблицы типов-записей от начала файла (в байтах) *) |
||
85 | offStrings: INTEGER; (* смещение строковых литералов от начала файла (в байтах) *) |
||
86 | GlobalSize: INTEGER; (* размер глобальных переменных (в словах; слово = 4 байта) *) |
||
87 | HeapStackSize: INTEGER; (* размер области кучи/стэка (в словах; слово = 4 байта) *) |
||
88 | Reserved: ARRAY 8 OF INTEGER (* зарезервировано *) |
||
89 | |||
90 | END |
||
91 | |||
92 | Где: |
||
93 | |||
94 | INTEGER = INT32/INT64 |
||
95 | i = offTypes DIV (3 * sizeof(INTEGER)); |
||
96 | t = (offStrings - offTypes) DIV sizeof(INTEGER) |
||
97 | s = FILE_SIZE - offStrings - 12 * sizeof(INTEGER) |
||
98 | --------------------------------------------------------------------------------------------------- |
||
99 | |||
100 | Система команд |
||
101 | |||
102 | мнемоника опкод парам1 парам2 действие |
||
103 | |||
104 | STOP 0 0 0 остановить программу |
||
105 | RET 1 0 0 возврат из процедуры (pop PC) |
||
106 | ENTER imm 2 imm 0 push BP; BP := SP; WHILE imm > 0 DO push 0; DEC(imm) END |
||
107 | NEG Rn 3 n 0 Rn := -Rn |
||
108 | NOT Rn 4 n 0 Rn := ORD(-BITS(Rn)) |
||
109 | NOP 5 0 0 нет операции |
||
110 | XCHG Rn, Rm 6 n m temp := Rn; Rn := Rm; Rm := temp |
||
111 | LDB Rn, [Rm + imm] 7 m*256 + n imm Rn := UInt8Ptr(Rm + imm)^ |
||
112 | LDH Rn, [Rm + imm] 8 m*256 + n imm Rn := UInt16Ptr(Rm + imm)^ |
||
113 | LDW Rn, [Rm + imm] 9 m*256 + n imm Rn := UInt32Ptr(Rm + imm)^ |
||
114 | * PUSH Rn 10 n 0 DEC(SP, 4); UInt32Ptr(SP)^ := Rn |
||
115 | * PUSH imm 11 imm 0 DEC(SP, 4); UInt32Ptr(SP)^ := imm |
||
116 | * POP Rn 12 n 0 Rn := UInt32Ptr(SP)^; INC(SP, 4) |
||
117 | ** PUSH Rn 10 n 0 DEC(SP, 8); UInt64Ptr(SP)^ := Rn |
||
118 | ** PUSH imm 11 imm 0 DEC(SP, 8); UInt64Ptr(SP)^ := imm |
||
119 | ** POP Rn 12 n 0 Rn := UInt64Ptr(SP)^; INC(SP, 8) |
||
120 | L#hex: 13 hex 0 метка: |
||
121 | LEA Rn, TYPES + imm 14 n + 000H imm Rn := imm + address(TYPES) |
||
122 | LEA Rn, STRINGS + imm 14 n + 100H imm Rn := imm + address(STRINGS) |
||
123 | LEA Rn, GLOBAL + imm 14 n + 200H imm Rn := imm + address(GLOBAL) |
||
124 | LEA Rn, HEAP + imm 14 n + 300H imm Rn := imm + address(HEAP) |
||
125 | LEA Rn, STACK + imm 14 n + 400H imm Rn := imm + address(STACK) |
||
126 | LLA Rn, L#hex 15 n hex Rn := address(L#hex) |
||
127 | ** LDD Rn, [Rm + imm] 16 m*256 + n imm Rn := UInt64Ptr(Rm + imm)^ |
||
128 | |||
129 | JMP L#hex 19 hex 0 goto L#hex |
||
130 | CALL L#hex 20 hex 0 push PC; goto L#hex |
||
131 | CALL Rn 21 n 0 push PC; goto Rn |
||
132 | MOV Rn, Rm 22 n m Rn := Rm |
||
133 | MOV Rn, imm 23 n imm Rn := imm |
||
134 | MUL Rn, Rm 24 n m Rn := Rn * Rm |
||
135 | MUL Rn, imm 25 n imm Rn := Rm * imm |
||
136 | ADD Rn, Rm 26 n m Rn := Rn + Rm |
||
137 | ADD Rn, imm 27 n imm Rn := Rn + imm |
||
138 | SUB Rn, Rm 28 n m Rn := Rn - Rm |
||
139 | SUB Rn, imm 29 n imm Rn := Rn - imm |
||
140 | DIV Rn, Rm 30 n m Rn := Rn DIV Rm |
||
141 | DIV Rn, imm 31 n imm Rn := Rn DIV imm |
||
142 | MOD Rn, Rm 32 n m Rn := Rn MOD Rm |
||
143 | MOD Rn, imm 33 n imm Rn := Rn MOD imm |
||
144 | STB [Rn + imm], Rm 34 n*256 + m imm UInt8Ptr(Rn + imm)^ := Rm MOD 256 |
||
145 | STB [Rn], imm 35 n imm UInt8Ptr(Rn)^ := imm MOD 256 |
||
146 | STH [Rn + imm], Rm 36 n*256 + m imm UInt16Ptr(Rn + imm)^ := Rm MOD 65536 |
||
147 | STH [Rn], imm 37 n imm UInt16Ptr(Rn)^ := imm MOD 65536 |
||
148 | * STW [Rn + imm], Rm 38 n*256 + m imm UInt32Ptr(Rn + imm)^ := Rm |
||
149 | * STW [Rn], imm 39 n imm UInt32Ptr(Rn)^ := imm |
||
150 | ** STW [Rn + imm], Rm 38 n*256 + m imm UInt32Ptr(Rn + imm)^ := Rm MOD 100000000H |
||
151 | ** STW [Rn], imm 39 n imm UInt32Ptr(Rn)^ := imm MOD 100000000H |
||
152 | ** STD [Rn + imm], Rm 40 n*256 + m imm UInt64Ptr(Rn + imm)^ := Rm |
||
153 | ** STD [Rn], imm 41 n imm UInt64Ptr(Rn)^ := imm |
||
154 | |||
155 | AND Rn, Rm 46 n m Rn := ORD(BITS(Rn) * BITS(Rm)) |
||
156 | AND Rn, imm 47 n imm Rn := ORD(BITS(Rn) * BITS(imm)) |
||
157 | OR Rn, Rm 48 n m Rn := ORD(BITS(Rn) + BITS(Rm)) |
||
158 | OR Rn, imm 49 n imm Rn := ORD(BITS(Rn) + BITS(imm)) |
||
159 | XOR Rn, Rm 50 n m Rn := ORD(BITS(Rn) / BITS(Rm)) |
||
160 | XOR Rn, imm 51 n imm Rn := ORD(BITS(Rn) / BITS(imm)) |
||
161 | ASR Rn, Rm 52 n m Rn := ASR(Rn, Rm) |
||
162 | ASR Rn, imm 53 n imm Rn := ASR(Rn, imm) |
||
163 | LSR Rn, Rm 54 n m Rn := LSR(Rn, Rm) |
||
164 | LSR Rn, imm 55 n imm Rn := LSR(Rn, imm) |
||
165 | LSL Rn, Rm 56 n m Rn := LSL(Rn, Rm) |
||
166 | LSL Rn, imm 57 n imm Rn := LSL(Rn, imm) |
||
167 | ROR Rn, Rm 58 n m Rn := ROR(Rn, Rm) |
||
168 | ROR Rn, imm 59 n imm Rn := ROR(Rn, imm) |
||
169 | |||
170 | CMP Rn, Rm 64 n m сравнить Rn и Rm |
||
171 | CMP Rn, imm 65 n imm сравнить Rn и imm |
||
172 | BIT Rn, Rm 66 n m Rn := ORD({Rm}) |
||
173 | SYSCALL Rn 67 n 0 системный вызов; Rn содержит адрес параметров |
||
174 | JBT L#hex 68 hex 0 перейти на метку L#hex, если "ниже" |
||
175 | ADD Rn, Rm, imm 69 m*256 + n imm Rn := Rm + imm |
||
176 | JEQ L#hex 70 hex 0 перейти на метку L#hex, если "равно" |
||
177 | JNE L#hex 71 hex 0 перейти на метку L#hex, если "не равно" |
||
178 | JLT L#hex 72 hex 0 перейти на метку L#hex, если "меньше" |
||
179 | JGE L#hex 73 hex 0 перейти на метку L#hex, если "не меньше" |
||
180 | JGT L#hex 74 hex 0 перейти на метку L#hex, если "больше" |
||
181 | JLE L#hex 75 hex 0 перейти на метку L#hex, если "не больше" |
||
182 | SEQ Rn 76 n 0 если "равно": Rn := 1, иначе Rn := 0 |
||
183 | SNE Rn 77 n 0 если "не равно": Rn := 1, иначе Rn := 0 |
||
184 | SLT Rn 78 n 0 если "меньше": Rn := 1, иначе Rn := 0 |
||
185 | SGE Rn 79 n 0 если "не меньше": Rn := 1, иначе Rn := 0 |
||
186 | SGT Rn 80 n 0 если "больше": Rn := 1, иначе Rn := 0 |
||
187 | SLE Rn 81 n 0 если "не больше": Rn := 1, иначе Rn := 0 |
||
188 | |||
189 | Команда CMP сохраняет результат сравнения в скрытом регистре, этот результат используется |
||
190 | в командах перехода по условию (JEQ, JNE, JLT, JGE, JGT, JLE, JBT) а также в командах |
||
191 | установки регистра по условию (SEQ, SNE, SLT, SGE, SGT, SLE). |
||
192 | |||
193 | * Команда для 32-битной виртуальной машины |
||
194 | ** Команда для 64-битной виртуальной машины |
||
195 | |||
196 | --------------------------------------------------------------------------------------------------- |
||
197 | |||
198 | Общая структура программы |
||
199 | |||
200 | CODE: (* машинный код *) |
||
201 | LEA SP, STACK + 0x00000000 (* точка входа; инициализация регистра SP *) |
||
202 | ... |
||
203 | STOP (* конец программы *) |
||
204 | |||
205 | TYPES: (* таблица типов-записей *) |
||
206 | WORD 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
||
207 | WORD 0x00000002, 0x00000002, 0x00000002, 0x00000002 |
||
208 | WORD 0x00000000, 0x00000006, 0x00000000, 0x00000000 |
||
209 | WORD 0x00000002, 0x00000000, 0x0000000D, 0x0000000E |
||
210 | WORD 0x0000000C, 0x0000000E, 0x0000000C, 0x00000000 |
||
211 | WORD 0x00000000, 0x0000000C, 0x0000000C, 0x00000016 |
||
212 | WORD 0x00000000, 0x0000000C, 0x0000000C, 0x0000000C |
||
213 | WORD 0x00000000, 0x00000000, 0x0000000C, 0x0000000C |
||
214 | WORD 0x0000000C, 0x0000000C, 0x0000000C, 0x0000000C |
||
215 | WORD 0x0000000C, 0x0000000C, 0x00000000, 0x00000000 |
||
216 | WORD 0x0000000C, 0x0000000C, 0x0000000C, 0x00000000 |
||
217 | WORD 0x00000000, 0x0000000C, 0x0000002D, 0x0000002D |
||
218 | WORD 0x0000002D, 0x00000030, 0x00000030, 0x00000030 |
||
219 | WORD 0x00000030, 0x0000002D, 0x00000000, 0x00000000 |
||
220 | WORD 0x0000000A, 0x00000000, 0x00000002, 0x00000000 |
||
221 | WORD 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
||
222 | WORD 0x00000000, 0x00000000, 0x00000000, 0x00000000 |
||
223 | WORD 0x00000000, 0x0000000C, 0x0000000C, 0x00000000 |
||
224 | WORD 0x00000000, 0x0000000C, 0x00000049, 0x00000049 |
||
225 | WORD 0x00000049, 0x0000004C, 0x0000004C, 0x0000004C |
||
226 | WORD 0x00000049, 0x0000000C, 0x00000000, 0x0000000C |
||
227 | WORD 0x00000053, 0x00000053, 0x00000053, 0x00000053 |
||
228 | WORD 0x0000000C, 0x00000000, 0x00000000, 0x00000000 |
||
229 | WORD 0x00000006, 0x0000000C |
||
230 | |||
231 | STRINGS: (* строковые литералы *) |
||
232 | BYTE 0x46, 0x50, 0x55, 0x00, 0x54, 0x72, 0x61, 0x70 |
||
233 | BYTE 0x00, 0x0D, 0x0A, 0x00, 0x61, 0x73, 0x73, 0x65 |
||
234 | BYTE 0x72, 0x74, 0x69, 0x6F, 0x6E, 0x20, 0x66, 0x61 |
||
235 | BYTE 0x69, 0x6C, 0x75, 0x72, 0x65, 0x00, 0x4E, 0x49 |
||
236 | BYTE 0x4C, 0x20, 0x64, 0x65, 0x72, 0x65, 0x66, 0x65 |
||
237 | BYTE 0x72, 0x65, 0x6E, 0x63, 0x65, 0x00, 0x62, 0x61 |
||
238 | BYTE 0x64, 0x20, 0x64, 0x69, 0x76, 0x69, 0x73, 0x6F |
||
239 | BYTE 0x72, 0x00, 0x4E, 0x49, 0x4C, 0x20, 0x70, 0x72 |
||
240 | BYTE 0x6F, 0x63, 0x65, 0x64, 0x75, 0x72, 0x65, 0x20 |
||
241 | BYTE 0x63, 0x61, 0x6C, 0x6C, 0x00, 0x74, 0x79, 0x70 |
||
242 | BYTE 0x65, 0x20, 0x67, 0x75, 0x61, 0x72, 0x64, 0x20 |
||
243 | BYTE 0x65, 0x72, 0x72, 0x6F, 0x72, 0x00, 0x69, 0x6E |
||
244 | BYTE 0x64, 0x65, 0x78, 0x20, 0x6F, 0x75, 0x74, 0x20 |
||
245 | BYTE 0x6F, 0x66, 0x20, 0x72, 0x61, 0x6E, 0x67, 0x65 |
||
246 | BYTE 0x00, 0x69, 0x6E, 0x76, 0x61, 0x6C, 0x69, 0x64 |
||
247 | BYTE 0x20, 0x43, 0x41, 0x53, 0x45, 0x00, 0x61, 0x72 |
||
248 | BYTE 0x72, 0x61, 0x79, 0x20, 0x61, 0x73, 0x73, 0x69 |
||
249 | BYTE 0x67, 0x6E, 0x6D, 0x65, 0x6E, 0x74, 0x20, 0x65 |
||
250 | BYTE 0x72, 0x72, 0x6F, 0x72, 0x00, 0x43, 0x48, 0x52 |
||
251 | BYTE 0x20, 0x6F, 0x75, 0x74, 0x20, 0x6F, 0x66, 0x20 |
||
252 | BYTE 0x72, 0x61, 0x6E, 0x67, 0x65, 0x00, 0x57, 0x43 |
||
253 | BYTE 0x48, 0x52, 0x20, 0x6F, 0x75, 0x74, 0x20, 0x6F |
||
254 | BYTE 0x66, 0x20, 0x72, 0x61, 0x6E, 0x67, 0x65, 0x00 |
||
255 | BYTE 0x42, 0x59, 0x54, 0x45, 0x20, 0x6F, 0x75, 0x74 |
||
256 | BYTE 0x20, 0x6F, 0x66, 0x20, 0x72, 0x61, 0x6E, 0x67 |
||
257 | BYTE 0x65, 0x00, 0x65, 0x72, 0x72, 0x6F, 0x72, 0x20 |
||
258 | BYTE 0x28, 0x00, 0x29, 0x3A, 0x20, 0x00, 0x6D, 0x6F |
||
259 | BYTE 0x64, 0x75, 0x6C, 0x65, 0x3A, 0x20, 0x00, 0x6C |
||
260 | BYTE 0x69, 0x6E, 0x65, 0x3A, 0x20, 0x00, 0x52, 0x54 |
||
261 | BYTE 0x4C, 0x00, 0x54, 0x65, 0x73, 0x74, 0x00, 0x00 |
||
262 | |||
263 | GLOBAL: |
||
264 | WORDS 0x00000004 (* размер глобальных переменных в словах (слово = 4 или 8 байт) *) |
||
265 | |||
266 | HEAP: |
||
267 | WORDS 0x007FFFBF (* размер области кучи/стэка в словах (слово = 4 или 8 байт) *) |
||
268 | STACK: |
||
269 | WORDS 8 (* зарезервировано *) |
||
270 | ---------------------------------------------------------------------------------------------------->параметры> |