Subversion Repositories Kolibri OS

Rev

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
---------------------------------------------------------------------------------------------------