haxor 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/haxor.rb +1 -2
- data/lib/haxor/compiler/core.rb +35 -35
- data/lib/haxor/consts.rb +1 -1
- data/lib/haxor/linker.rb +1 -1
- data/lib/haxor/vm/core.rb +2 -2
- data/lib/haxor/vm/cpu.rb +258 -0
- data/lib/haxor/vm/os.rb +2 -2
- data/lib/haxor/vm/stack.rb +4 -4
- metadata +3 -4
- data/lib/haxor/vm/cpu/core.rb +0 -260
- data/lib/haxor/vm/registers.rb +0 -42
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a4e2b69873a7f50003c2fb9d403f9529a7fc88e
|
4
|
+
data.tar.gz: 1531d3af090791055290d4bfb982fca8e9ae188e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e01e17918aaa669fc8404b5bd294e5e2d29251c480fb867ff9a679ac0cbcb134d17336c070175394d9014de02dd50343f5710036edf389b727e32a359b80ad9e
|
7
|
+
data.tar.gz: c0220e732f98cff88b1045bcd5418d36983a838197d8e765d49c1e7434f52fcc8cc7bc6eff93c1c33f62fdd0dcf8cc29c4a3b6e4e9d590a0bf62a3eb2a1136e1
|
data/lib/haxor.rb
CHANGED
@@ -15,8 +15,7 @@ require_relative 'haxor/vm/subsystem'
|
|
15
15
|
require_relative 'haxor/vm/mem'
|
16
16
|
require_relative 'haxor/vm/stack'
|
17
17
|
require_relative 'haxor/vm/os'
|
18
|
-
require_relative 'haxor/vm/
|
19
|
-
require_relative 'haxor/vm/cpu/core'
|
18
|
+
require_relative 'haxor/vm/cpu'
|
20
19
|
|
21
20
|
# compiler
|
22
21
|
require_relative 'haxor/compiler/unit'
|
data/lib/haxor/compiler/core.rb
CHANGED
@@ -2,9 +2,9 @@ module Haxor
|
|
2
2
|
module Compiler
|
3
3
|
class Core
|
4
4
|
REG_ALIASES = {
|
5
|
-
'$sp' => Vm::Cpu::
|
6
|
-
'$ret' => Vm::Cpu::
|
7
|
-
'$sc' => Vm::Cpu::
|
5
|
+
'$sp' => Vm::Cpu::REG_STACK,
|
6
|
+
'$ret' => Vm::Cpu::REG_RETURN,
|
7
|
+
'$sc' => Vm::Cpu::REG_SYSCALL
|
8
8
|
}
|
9
9
|
|
10
10
|
def initialize
|
@@ -41,37 +41,37 @@ module Haxor
|
|
41
41
|
bind_cmd 'bgtz', [:reg, :imm], :cmd_bgtz
|
42
42
|
bind_cmd 'beqz', [:reg, :imm], :cmd_beqz
|
43
43
|
|
44
|
-
bind_cmd 'nop', [], Vm::Cpu::
|
45
|
-
bind_cmd 'add', [:reg, :reg, :reg], Vm::Cpu::
|
46
|
-
bind_cmd 'addi', [:reg, :reg, :imm], Vm::Cpu::
|
47
|
-
bind_cmd 'sub', [:reg, :reg, :reg], Vm::Cpu::
|
48
|
-
bind_cmd 'mult', [:reg, :reg, :reg], Vm::Cpu::
|
49
|
-
bind_cmd 'div', [:reg, :reg, :reg], Vm::Cpu::
|
50
|
-
bind_cmd 'mod', [:reg, :reg, :reg], Vm::Cpu::
|
51
|
-
bind_cmd 'lw', [:reg, :reg, :imm], Vm::Cpu::
|
52
|
-
bind_cmd 'sw', [:reg, :imm, :reg], Vm::Cpu::
|
53
|
-
bind_cmd 'lui', [:reg, :imm], Vm::Cpu::
|
54
|
-
bind_cmd 'and', [:reg, :reg, :reg], Vm::Cpu::
|
55
|
-
bind_cmd 'andi', [:reg, :reg, :imm], Vm::Cpu::
|
56
|
-
bind_cmd 'or', [:reg, :reg, :reg], Vm::Cpu::
|
57
|
-
bind_cmd 'ori', [:reg, :reg, :imm], Vm::Cpu::
|
58
|
-
bind_cmd 'xor', [:reg, :reg, :reg], Vm::Cpu::
|
59
|
-
bind_cmd 'nor', [:reg, :reg, :reg], Vm::Cpu::
|
60
|
-
bind_cmd 'slt', [:reg, :reg, :reg], Vm::Cpu::
|
61
|
-
bind_cmd 'slti', [:reg, :reg, :imm], Vm::Cpu::
|
62
|
-
bind_cmd 'slli', [:reg, :reg, :imm], Vm::Cpu::
|
63
|
-
bind_cmd 'srli', [:reg, :reg, :imm], Vm::Cpu::
|
64
|
-
bind_cmd 'sll', [:reg, :reg, :reg], Vm::Cpu::
|
65
|
-
bind_cmd 'srl', [:reg, :reg, :reg], Vm::Cpu::
|
66
|
-
bind_cmd 'beq', [:reg, :reg, :imm], Vm::Cpu::
|
67
|
-
bind_cmd 'beql', [:reg, :reg, :imm], Vm::Cpu::
|
68
|
-
bind_cmd 'bne', [:reg, :reg, :imm], Vm::Cpu::
|
69
|
-
bind_cmd 'bnel', [:reg, :reg, :imm], Vm::Cpu::
|
70
|
-
bind_cmd 'j', [:imm], Vm::Cpu::
|
71
|
-
bind_cmd 'jr', [:reg], Vm::Cpu::
|
72
|
-
bind_cmd 'jal', [:imm], Vm::Cpu::
|
73
|
-
bind_cmd 'exiti', [:imm], Vm::Cpu::
|
74
|
-
bind_cmd 'syscall', [], Vm::Cpu::
|
44
|
+
bind_cmd 'nop', [], Vm::Cpu::OP_NOP
|
45
|
+
bind_cmd 'add', [:reg, :reg, :reg], Vm::Cpu::OP_ADD
|
46
|
+
bind_cmd 'addi', [:reg, :reg, :imm], Vm::Cpu::OP_ADDI
|
47
|
+
bind_cmd 'sub', [:reg, :reg, :reg], Vm::Cpu::OP_SUB
|
48
|
+
bind_cmd 'mult', [:reg, :reg, :reg], Vm::Cpu::OP_MULT
|
49
|
+
bind_cmd 'div', [:reg, :reg, :reg], Vm::Cpu::OP_DIV
|
50
|
+
bind_cmd 'mod', [:reg, :reg, :reg], Vm::Cpu::OP_MOD
|
51
|
+
bind_cmd 'lw', [:reg, :reg, :imm], Vm::Cpu::OP_LW
|
52
|
+
bind_cmd 'sw', [:reg, :imm, :reg], Vm::Cpu::OP_SW
|
53
|
+
bind_cmd 'lui', [:reg, :imm], Vm::Cpu::OP_LUI
|
54
|
+
bind_cmd 'and', [:reg, :reg, :reg], Vm::Cpu::OP_AND
|
55
|
+
bind_cmd 'andi', [:reg, :reg, :imm], Vm::Cpu::OP_ANDI
|
56
|
+
bind_cmd 'or', [:reg, :reg, :reg], Vm::Cpu::OP_OR
|
57
|
+
bind_cmd 'ori', [:reg, :reg, :imm], Vm::Cpu::OP_ORI
|
58
|
+
bind_cmd 'xor', [:reg, :reg, :reg], Vm::Cpu::OP_XOR
|
59
|
+
bind_cmd 'nor', [:reg, :reg, :reg], Vm::Cpu::OP_NOR
|
60
|
+
bind_cmd 'slt', [:reg, :reg, :reg], Vm::Cpu::OP_SLT
|
61
|
+
bind_cmd 'slti', [:reg, :reg, :imm], Vm::Cpu::OP_SLTI
|
62
|
+
bind_cmd 'slli', [:reg, :reg, :imm], Vm::Cpu::OP_SLLI
|
63
|
+
bind_cmd 'srli', [:reg, :reg, :imm], Vm::Cpu::OP_SRLI
|
64
|
+
bind_cmd 'sll', [:reg, :reg, :reg], Vm::Cpu::OP_SLL
|
65
|
+
bind_cmd 'srl', [:reg, :reg, :reg], Vm::Cpu::OP_SRL
|
66
|
+
bind_cmd 'beq', [:reg, :reg, :imm], Vm::Cpu::OP_BEQ, [:rel_imm, :x8]
|
67
|
+
bind_cmd 'beql', [:reg, :reg, :imm], Vm::Cpu::OP_BEQL, [:rel_imm, :x8]
|
68
|
+
bind_cmd 'bne', [:reg, :reg, :imm], Vm::Cpu::OP_BNE, [:rel_imm, :x8]
|
69
|
+
bind_cmd 'bnel', [:reg, :reg, :imm], Vm::Cpu::OP_BNEL, [:rel_imm, :x8]
|
70
|
+
bind_cmd 'j', [:imm], Vm::Cpu::OP_J, [:x8]
|
71
|
+
bind_cmd 'jr', [:reg], Vm::Cpu::OP_JR
|
72
|
+
bind_cmd 'jal', [:imm], Vm::Cpu::OP_JAL, [:x8]
|
73
|
+
bind_cmd 'exiti', [:imm], Vm::Cpu::OP_EXITI
|
74
|
+
bind_cmd 'syscall', [], Vm::Cpu::OP_SYSCALL
|
75
75
|
end
|
76
76
|
|
77
77
|
def bind_cmd(cmd, args, opcode, opts = [])
|
@@ -155,7 +155,7 @@ module Haxor
|
|
155
155
|
end
|
156
156
|
|
157
157
|
def cmd_ret(*_args)
|
158
|
-
process_cmd 'jr', ['$' + Vm::Cpu::
|
158
|
+
process_cmd 'jr', ['$' + Vm::Cpu::REG_RETURN.to_s]
|
159
159
|
end
|
160
160
|
|
161
161
|
def cmd_b(*args)
|
data/lib/haxor/consts.rb
CHANGED
data/lib/haxor/linker.rb
CHANGED
data/lib/haxor/vm/core.rb
CHANGED
@@ -5,7 +5,7 @@ module Haxor
|
|
5
5
|
|
6
6
|
def initialize
|
7
7
|
@subsystems = {}
|
8
|
-
register_subsystem :cpu, Cpu
|
8
|
+
register_subsystem :cpu, Cpu.new
|
9
9
|
register_subsystem :mem, Mem.new(Consts::RESERVED_MEM)
|
10
10
|
register_subsystem :stack, Stack.new
|
11
11
|
register_subsystem :os, Os.new
|
@@ -45,7 +45,7 @@ module Haxor
|
|
45
45
|
subsystem(:cpu).ip = @hdr.entry_point # instruction pointer
|
46
46
|
subsystem(:mem).enlarge @hdr.bss_size
|
47
47
|
subsystem(:mem).enlarge @hdr.stack_size
|
48
|
-
subsystem(:cpu).reg Vm::Cpu::
|
48
|
+
subsystem(:cpu).reg Vm::Cpu::REG_STACK, subsystem(:mem).size
|
49
49
|
end
|
50
50
|
end
|
51
51
|
end
|
data/lib/haxor/vm/cpu.rb
ADDED
@@ -0,0 +1,258 @@
|
|
1
|
+
module Haxor
|
2
|
+
module Vm
|
3
|
+
class Cpu < Subsystem
|
4
|
+
attr_accessor :ip
|
5
|
+
|
6
|
+
# Misc
|
7
|
+
OP_NOP = 0x00
|
8
|
+
OP_EXITI = 0x01
|
9
|
+
OP_SYSCALL = 0x02
|
10
|
+
|
11
|
+
# Arithmetic
|
12
|
+
OP_ADD = 0x10
|
13
|
+
OP_ADDI = 0x11
|
14
|
+
OP_SUB = 0x12
|
15
|
+
OP_MULT = 0x13
|
16
|
+
OP_DIV = 0x14
|
17
|
+
OP_MOD = 0x15
|
18
|
+
|
19
|
+
# Data transfer
|
20
|
+
OP_LW = 0x20
|
21
|
+
OP_SW = 0x21
|
22
|
+
OP_LUI = 0x22
|
23
|
+
|
24
|
+
# Logical
|
25
|
+
OP_AND = 0x30
|
26
|
+
OP_ANDI = 0x31
|
27
|
+
OP_OR = 0x32
|
28
|
+
OP_ORI = 0x33
|
29
|
+
OP_XOR = 0x34
|
30
|
+
OP_NOR = 0x35
|
31
|
+
OP_SLT = 0x36
|
32
|
+
OP_SLTI = 0x37
|
33
|
+
|
34
|
+
# Bitwise shift
|
35
|
+
OP_SLLI = 0x40
|
36
|
+
OP_SRLI = 0x41
|
37
|
+
OP_SLL = 0x42
|
38
|
+
OP_SRL = 0x43
|
39
|
+
|
40
|
+
# Branch/Jumps
|
41
|
+
OP_BEQ = 0x50
|
42
|
+
OP_BEQL = 0x51
|
43
|
+
OP_BNE = 0x52
|
44
|
+
OP_BNEL = 0x53
|
45
|
+
OP_J = 0x54
|
46
|
+
OP_JR = 0x55
|
47
|
+
OP_JAL = 0x56
|
48
|
+
|
49
|
+
REG_ZERO = 0
|
50
|
+
REG_STACK = 61
|
51
|
+
REG_RETURN = 62
|
52
|
+
REG_SYSCALL = 63
|
53
|
+
|
54
|
+
def initialize
|
55
|
+
@registers = Array.new(64, 0)
|
56
|
+
@units = []
|
57
|
+
@opcodes = {}
|
58
|
+
init_opcodes
|
59
|
+
end
|
60
|
+
|
61
|
+
def init_opcodes
|
62
|
+
bind_opcode OP_NOP, :op_nop
|
63
|
+
bind_opcode OP_ADD, :op_add
|
64
|
+
bind_opcode OP_ADDI, :op_addi
|
65
|
+
bind_opcode OP_SUB, :op_sub
|
66
|
+
bind_opcode OP_MULT, :op_mult
|
67
|
+
bind_opcode OP_DIV, :op_div
|
68
|
+
bind_opcode OP_MOD, :op_mod
|
69
|
+
bind_opcode OP_LW, :op_lw
|
70
|
+
bind_opcode OP_SW, :op_sw
|
71
|
+
bind_opcode OP_LUI, :op_lui
|
72
|
+
bind_opcode OP_AND, :op_and
|
73
|
+
bind_opcode OP_ANDI, :op_andi
|
74
|
+
bind_opcode OP_OR, :op_or
|
75
|
+
bind_opcode OP_ORI, :op_ori
|
76
|
+
bind_opcode OP_XOR, :op_xor
|
77
|
+
bind_opcode OP_NOR, :op_nor
|
78
|
+
bind_opcode OP_SLT, :op_slt
|
79
|
+
bind_opcode OP_SLTI, :op_slti
|
80
|
+
bind_opcode OP_SLLI, :op_slli
|
81
|
+
bind_opcode OP_SRLI, :op_srli
|
82
|
+
bind_opcode OP_SLL, :op_sll
|
83
|
+
bind_opcode OP_SRL, :op_srl
|
84
|
+
bind_opcode OP_BEQ, :op_beq
|
85
|
+
bind_opcode OP_BEQL, :op_beql
|
86
|
+
bind_opcode OP_BNE, :op_bne
|
87
|
+
bind_opcode OP_BNEL, :op_bnel
|
88
|
+
bind_opcode OP_J, :op_j
|
89
|
+
bind_opcode OP_JR, :op_jr
|
90
|
+
bind_opcode OP_JAL, :op_jal
|
91
|
+
bind_opcode OP_EXITI, :op_exiti
|
92
|
+
bind_opcode OP_SYSCALL, :op_syscall
|
93
|
+
end
|
94
|
+
|
95
|
+
def op_nop(info)
|
96
|
+
end
|
97
|
+
|
98
|
+
def op_add(info)
|
99
|
+
reg info.reg1, reg(info.reg2) + reg(info.reg3)
|
100
|
+
end
|
101
|
+
|
102
|
+
def op_addi(info)
|
103
|
+
reg info.reg1, reg(info.reg2) + info.imm
|
104
|
+
end
|
105
|
+
|
106
|
+
def op_sub(info)
|
107
|
+
reg info.reg1, reg(info.reg2) - reg(info.reg3)
|
108
|
+
end
|
109
|
+
|
110
|
+
def op_mult(info)
|
111
|
+
reg info.reg1, reg(info.reg2) * reg(info.reg3)
|
112
|
+
end
|
113
|
+
|
114
|
+
def op_div(info)
|
115
|
+
reg info.reg1, reg(info.reg2) / reg(info.reg3)
|
116
|
+
end
|
117
|
+
|
118
|
+
def op_mod(info)
|
119
|
+
reg info.reg1, reg(info.reg2) % reg(info.reg3)
|
120
|
+
end
|
121
|
+
|
122
|
+
# reg1 = memory[reg2+imm]
|
123
|
+
def op_lw(info)
|
124
|
+
addr = reg(info.reg2) + info.imm
|
125
|
+
reg info.reg1, subsystem(:mem).read(addr)
|
126
|
+
end
|
127
|
+
|
128
|
+
# memory[reg1+imm] = reg2
|
129
|
+
def op_sw(info)
|
130
|
+
addr = reg(info.reg1) + info.imm
|
131
|
+
subsystem(:mem).write addr, reg(info.reg2)
|
132
|
+
end
|
133
|
+
|
134
|
+
def op_lui(info)
|
135
|
+
reg info.reg1, (info.imm << 32)
|
136
|
+
end
|
137
|
+
|
138
|
+
def op_and(info)
|
139
|
+
reg info.reg1, reg(info.reg2) & reg(info.reg3)
|
140
|
+
end
|
141
|
+
|
142
|
+
def op_andi(info)
|
143
|
+
reg info.reg1, reg(info.reg2) & info.imm
|
144
|
+
end
|
145
|
+
|
146
|
+
def op_or(info)
|
147
|
+
reg info.reg1, reg(info.reg2) | reg(info.reg3)
|
148
|
+
end
|
149
|
+
|
150
|
+
def op_ori(info)
|
151
|
+
reg info.reg1, reg(info.reg2) | info.imm
|
152
|
+
end
|
153
|
+
|
154
|
+
def op_xor(info)
|
155
|
+
reg info.reg1, reg(info.reg2) ^ reg(info.reg3)
|
156
|
+
end
|
157
|
+
|
158
|
+
def op_nor(info)
|
159
|
+
reg info.reg1, ~(reg(info.reg2) | reg(info.reg3))
|
160
|
+
end
|
161
|
+
|
162
|
+
def op_slt(info)
|
163
|
+
reg info.reg1, reg(info.reg2) < reg(info.reg3) ? 1 : 0
|
164
|
+
end
|
165
|
+
|
166
|
+
def op_slti(info)
|
167
|
+
reg info.reg1, reg(info.reg2) < info.imm ? 1 : 0
|
168
|
+
end
|
169
|
+
|
170
|
+
def op_slli(info)
|
171
|
+
reg info.reg1, reg(info.reg2) << info.imm
|
172
|
+
end
|
173
|
+
|
174
|
+
def op_srli(info)
|
175
|
+
reg info.reg1, reg(info.reg2) >> info.imm
|
176
|
+
end
|
177
|
+
|
178
|
+
def op_sll(info)
|
179
|
+
reg info.reg1, reg(info.reg2) << reg(info.reg3)
|
180
|
+
end
|
181
|
+
|
182
|
+
def op_srl(info)
|
183
|
+
reg info.reg1, reg(info.reg2) >> reg(info.reg3)
|
184
|
+
end
|
185
|
+
|
186
|
+
def op_beq(info)
|
187
|
+
branch(info.imm) if reg(info.reg1) == reg(info.reg2)
|
188
|
+
end
|
189
|
+
|
190
|
+
def op_beql(info)
|
191
|
+
return if reg(info.reg1) != reg(info.reg2)
|
192
|
+
|
193
|
+
reg REG_RETURN, @ip
|
194
|
+
branch(info.imm)
|
195
|
+
end
|
196
|
+
|
197
|
+
def op_bne(info)
|
198
|
+
branch info.imm if reg(info.reg1) != reg(info.reg2)
|
199
|
+
end
|
200
|
+
|
201
|
+
def op_bnel(info)
|
202
|
+
return if reg(info.reg1) == reg(info.reg2)
|
203
|
+
|
204
|
+
reg REG_RETURN, @ip
|
205
|
+
branch(info.imm)
|
206
|
+
end
|
207
|
+
|
208
|
+
def op_j(info)
|
209
|
+
jmp info.imm
|
210
|
+
end
|
211
|
+
|
212
|
+
def op_jr(info)
|
213
|
+
@ip = reg(info.reg1)
|
214
|
+
end
|
215
|
+
|
216
|
+
def op_jal(info)
|
217
|
+
reg REG_RETURN, @ip
|
218
|
+
jmp info.imm
|
219
|
+
end
|
220
|
+
|
221
|
+
def op_exiti(info)
|
222
|
+
exit info.imm
|
223
|
+
end
|
224
|
+
|
225
|
+
def op_syscall(_info)
|
226
|
+
@vm.subsystem(:os).syscall
|
227
|
+
end
|
228
|
+
|
229
|
+
def reg(id, value = nil)
|
230
|
+
return @registers[id] if value.nil?
|
231
|
+
return if id == REG_ZERO # $0 cannot be overwritten
|
232
|
+
@registers[id] = value
|
233
|
+
end
|
234
|
+
|
235
|
+
def jmp(addr)
|
236
|
+
@ip = addr * Consts::WORD_SIZE
|
237
|
+
end
|
238
|
+
|
239
|
+
def branch(rel_addr)
|
240
|
+
@ip += rel_addr * Consts::WORD_SIZE
|
241
|
+
end
|
242
|
+
|
243
|
+
def bind_opcode(opcode, method)
|
244
|
+
fail "OpCode already defined - #{opcode}." if @opcodes.key? opcode
|
245
|
+
@opcodes[opcode] = {
|
246
|
+
method: method
|
247
|
+
}
|
248
|
+
end
|
249
|
+
|
250
|
+
def iterate
|
251
|
+
opcode = subsystem(:mem).read @ip
|
252
|
+
@ip += Consts::WORD_SIZE
|
253
|
+
info = Utils.decode_opcode opcode
|
254
|
+
send @opcodes[info.cmd][:method], info
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
data/lib/haxor/vm/os.rb
CHANGED
@@ -8,7 +8,7 @@ module Haxor
|
|
8
8
|
}
|
9
9
|
|
10
10
|
def syscall
|
11
|
-
func = subsystem(:cpu).reg(Vm::Cpu::
|
11
|
+
func = subsystem(:cpu).reg(Vm::Cpu::REG_SYSCALL)
|
12
12
|
send(TABLE[func])
|
13
13
|
end
|
14
14
|
|
@@ -78,7 +78,7 @@ module Haxor
|
|
78
78
|
result = file.scanf fmt
|
79
79
|
|
80
80
|
if result.size != types.size
|
81
|
-
subsystem(:cpu).reg Vm::Cpu::
|
81
|
+
subsystem(:cpu).reg Vm::Cpu::REG_SYSCALL, -1
|
82
82
|
return
|
83
83
|
end
|
84
84
|
|
data/lib/haxor/vm/stack.rb
CHANGED
@@ -7,9 +7,9 @@ module Haxor
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def push_value(value)
|
10
|
-
sp = @vm.subsystem(:cpu).reg Vm::Cpu::
|
10
|
+
sp = @vm.subsystem(:cpu).reg Vm::Cpu::REG_STACK
|
11
11
|
sp -= Consts::WORD_SIZE
|
12
|
-
@vm.subsystem(:cpu).reg Vm::Cpu::
|
12
|
+
@vm.subsystem(:cpu).reg Vm::Cpu::REG_STACK, sp
|
13
13
|
@vm.subsystem(:mem).write sp, value
|
14
14
|
end
|
15
15
|
|
@@ -19,10 +19,10 @@ module Haxor
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def pop_value
|
22
|
-
sp = @vm.subsystem(:cpu).reg Vm::Cpu::
|
22
|
+
sp = @vm.subsystem(:cpu).reg Vm::Cpu::REG_STACK
|
23
23
|
value = @vm.subsystem(:mem).read sp
|
24
24
|
sp += Consts::WORD_SIZE
|
25
|
-
@vm.subsystem(:cpu).reg Vm::Cpu::
|
25
|
+
@vm.subsystem(:cpu).reg Vm::Cpu::REG_STACK, sp
|
26
26
|
|
27
27
|
value
|
28
28
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: haxor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Krzysztof Magosa
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -75,10 +75,9 @@ files:
|
|
75
75
|
- lib/haxor/token/pointer.rb
|
76
76
|
- lib/haxor/utils.rb
|
77
77
|
- lib/haxor/vm/core.rb
|
78
|
-
- lib/haxor/vm/cpu
|
78
|
+
- lib/haxor/vm/cpu.rb
|
79
79
|
- lib/haxor/vm/mem.rb
|
80
80
|
- lib/haxor/vm/os.rb
|
81
|
-
- lib/haxor/vm/registers.rb
|
82
81
|
- lib/haxor/vm/stack.rb
|
83
82
|
- lib/haxor/vm/subsystem.rb
|
84
83
|
- media/memory.png
|
data/lib/haxor/vm/cpu/core.rb
DELETED
@@ -1,260 +0,0 @@
|
|
1
|
-
module Haxor
|
2
|
-
module Vm
|
3
|
-
module Cpu
|
4
|
-
class Core < Subsystem
|
5
|
-
attr_accessor :ip
|
6
|
-
|
7
|
-
# Misc
|
8
|
-
OP_NOP = 0x00
|
9
|
-
OP_EXITI = 0x01
|
10
|
-
OP_SYSCALL = 0x02
|
11
|
-
|
12
|
-
# Arithmetic
|
13
|
-
OP_ADD = 0x10
|
14
|
-
OP_ADDI = 0x11
|
15
|
-
OP_SUB = 0x12
|
16
|
-
OP_MULT = 0x13
|
17
|
-
OP_DIV = 0x14
|
18
|
-
OP_MOD = 0x15
|
19
|
-
|
20
|
-
# Data transfer
|
21
|
-
OP_LW = 0x20
|
22
|
-
OP_SW = 0x21
|
23
|
-
OP_LUI = 0x22
|
24
|
-
|
25
|
-
# Logical
|
26
|
-
OP_AND = 0x30
|
27
|
-
OP_ANDI = 0x31
|
28
|
-
OP_OR = 0x32
|
29
|
-
OP_ORI = 0x33
|
30
|
-
OP_XOR = 0x34
|
31
|
-
OP_NOR = 0x35
|
32
|
-
OP_SLT = 0x36
|
33
|
-
OP_SLTI = 0x37
|
34
|
-
|
35
|
-
# Bitwise shift
|
36
|
-
OP_SLLI = 0x40
|
37
|
-
OP_SRLI = 0x41
|
38
|
-
OP_SLL = 0x42
|
39
|
-
OP_SRL = 0x43
|
40
|
-
|
41
|
-
# Branch/Jumps
|
42
|
-
OP_BEQ = 0x50
|
43
|
-
OP_BEQL = 0x51
|
44
|
-
OP_BNE = 0x52
|
45
|
-
OP_BNEL = 0x53
|
46
|
-
OP_J = 0x54
|
47
|
-
OP_JR = 0x55
|
48
|
-
OP_JAL = 0x56
|
49
|
-
|
50
|
-
REG_ZERO = 0
|
51
|
-
REG_STACK = 61
|
52
|
-
REG_RETURN = 62
|
53
|
-
REG_SYSCALL = 63
|
54
|
-
|
55
|
-
def initialize
|
56
|
-
@registers = Array.new(64, 0)
|
57
|
-
@units = []
|
58
|
-
@opcodes = {}
|
59
|
-
init_opcodes
|
60
|
-
end
|
61
|
-
|
62
|
-
def init_opcodes
|
63
|
-
bind_opcode OP_NOP, :op_nop
|
64
|
-
bind_opcode OP_ADD, :op_add
|
65
|
-
bind_opcode OP_ADDI, :op_addi
|
66
|
-
bind_opcode OP_SUB, :op_sub
|
67
|
-
bind_opcode OP_MULT, :op_mult
|
68
|
-
bind_opcode OP_DIV, :op_div
|
69
|
-
bind_opcode OP_MOD, :op_mod
|
70
|
-
bind_opcode OP_LW, :op_lw
|
71
|
-
bind_opcode OP_SW, :op_sw
|
72
|
-
bind_opcode OP_LUI, :op_lui
|
73
|
-
bind_opcode OP_AND, :op_and
|
74
|
-
bind_opcode OP_ANDI, :op_andi
|
75
|
-
bind_opcode OP_OR, :op_or
|
76
|
-
bind_opcode OP_ORI, :op_ori
|
77
|
-
bind_opcode OP_XOR, :op_xor
|
78
|
-
bind_opcode OP_NOR, :op_nor
|
79
|
-
bind_opcode OP_SLT, :op_slt
|
80
|
-
bind_opcode OP_SLTI, :op_slti
|
81
|
-
bind_opcode OP_SLLI, :op_slli
|
82
|
-
bind_opcode OP_SRLI, :op_srli
|
83
|
-
bind_opcode OP_SLL, :op_sll
|
84
|
-
bind_opcode OP_SRL, :op_srl
|
85
|
-
bind_opcode OP_BEQ, :op_beq
|
86
|
-
bind_opcode OP_BEQL, :op_beql
|
87
|
-
bind_opcode OP_BNE, :op_bne
|
88
|
-
bind_opcode OP_BNEL, :op_bnel
|
89
|
-
bind_opcode OP_J, :op_j
|
90
|
-
bind_opcode OP_JR, :op_jr
|
91
|
-
bind_opcode OP_JAL, :op_jal
|
92
|
-
bind_opcode OP_EXITI, :op_exiti
|
93
|
-
bind_opcode OP_SYSCALL, :op_syscall
|
94
|
-
end
|
95
|
-
|
96
|
-
def op_nop(info)
|
97
|
-
end
|
98
|
-
|
99
|
-
def op_add(info)
|
100
|
-
reg info.reg1, reg(info.reg2) + reg(info.reg3)
|
101
|
-
end
|
102
|
-
|
103
|
-
def op_addi(info)
|
104
|
-
reg info.reg1, reg(info.reg2) + info.imm
|
105
|
-
end
|
106
|
-
|
107
|
-
def op_sub(info)
|
108
|
-
reg info.reg1, reg(info.reg2) - reg(info.reg3)
|
109
|
-
end
|
110
|
-
|
111
|
-
def op_mult(info)
|
112
|
-
reg info.reg1, reg(info.reg2) * reg(info.reg3)
|
113
|
-
end
|
114
|
-
|
115
|
-
def op_div(info)
|
116
|
-
reg info.reg1, reg(info.reg2) / reg(info.reg3)
|
117
|
-
end
|
118
|
-
|
119
|
-
def op_mod(info)
|
120
|
-
reg info.reg1, reg(info.reg2) % reg(info.reg3)
|
121
|
-
end
|
122
|
-
|
123
|
-
# reg1 = memory[reg2+imm]
|
124
|
-
def op_lw(info)
|
125
|
-
addr = reg(info.reg2) + info.imm
|
126
|
-
reg info.reg1, subsystem(:mem).read(addr)
|
127
|
-
end
|
128
|
-
|
129
|
-
# memory[reg1+imm] = reg2
|
130
|
-
def op_sw(info)
|
131
|
-
addr = reg(info.reg1) + info.imm
|
132
|
-
subsystem(:mem).write addr, reg(info.reg2)
|
133
|
-
end
|
134
|
-
|
135
|
-
def op_lui(info)
|
136
|
-
reg info.reg1, (info.imm << 32)
|
137
|
-
end
|
138
|
-
|
139
|
-
def op_and(info)
|
140
|
-
reg info.reg1, reg(info.reg2) & reg(info.reg3)
|
141
|
-
end
|
142
|
-
|
143
|
-
def op_andi(info)
|
144
|
-
reg info.reg1, reg(info.reg2) & info.imm
|
145
|
-
end
|
146
|
-
|
147
|
-
def op_or(info)
|
148
|
-
reg info.reg1, reg(info.reg2) | reg(info.reg3)
|
149
|
-
end
|
150
|
-
|
151
|
-
def op_ori(info)
|
152
|
-
reg info.reg1, reg(info.reg2) | info.imm
|
153
|
-
end
|
154
|
-
|
155
|
-
def op_xor(info)
|
156
|
-
reg info.reg1, reg(info.reg2) ^ reg(info.reg3)
|
157
|
-
end
|
158
|
-
|
159
|
-
def op_nor(info)
|
160
|
-
reg info.reg1, ~(reg(info.reg2) | reg(info.reg3))
|
161
|
-
end
|
162
|
-
|
163
|
-
def op_slt(info)
|
164
|
-
reg info.reg1, reg(info.reg2) < reg(info.reg3) ? 1 : 0
|
165
|
-
end
|
166
|
-
|
167
|
-
def op_slti(info)
|
168
|
-
reg info.reg1, reg(info.reg2) < info.imm ? 1 : 0
|
169
|
-
end
|
170
|
-
|
171
|
-
def op_slli(info)
|
172
|
-
reg info.reg1, reg(info.reg2) << info.imm
|
173
|
-
end
|
174
|
-
|
175
|
-
def op_srli(info)
|
176
|
-
reg info.reg1, reg(info.reg2) >> info.imm
|
177
|
-
end
|
178
|
-
|
179
|
-
def op_sll(info)
|
180
|
-
reg info.reg1, reg(info.reg2) << reg(info.reg3)
|
181
|
-
end
|
182
|
-
|
183
|
-
def op_srl(info)
|
184
|
-
reg info.reg1, reg(info.reg2) >> reg(info.reg3)
|
185
|
-
end
|
186
|
-
|
187
|
-
def op_beq(info)
|
188
|
-
branch(info.imm) if reg(info.reg1) == reg(info.reg2)
|
189
|
-
end
|
190
|
-
|
191
|
-
def op_beql(info)
|
192
|
-
return if reg(info.reg1) != reg(info.reg2)
|
193
|
-
|
194
|
-
reg REG_RETURN, @ip
|
195
|
-
branch(info.imm)
|
196
|
-
end
|
197
|
-
|
198
|
-
def op_bne(info)
|
199
|
-
branch info.imm if reg(info.reg1) != reg(info.reg2)
|
200
|
-
end
|
201
|
-
|
202
|
-
def op_bnel(info)
|
203
|
-
return if reg(info.reg1) == reg(info.reg2)
|
204
|
-
|
205
|
-
reg REG_RETURN, @ip
|
206
|
-
branch(info.imm)
|
207
|
-
end
|
208
|
-
|
209
|
-
def op_j(info)
|
210
|
-
jmp info.imm
|
211
|
-
end
|
212
|
-
|
213
|
-
def op_jr(info)
|
214
|
-
@ip = reg(info.reg1)
|
215
|
-
end
|
216
|
-
|
217
|
-
def op_jal(info)
|
218
|
-
reg REG_RETURN, @ip
|
219
|
-
jmp info.imm
|
220
|
-
end
|
221
|
-
|
222
|
-
def op_exiti(info)
|
223
|
-
exit info.imm
|
224
|
-
end
|
225
|
-
|
226
|
-
def op_syscall(_info)
|
227
|
-
@vm.subsystem(:os).syscall
|
228
|
-
end
|
229
|
-
|
230
|
-
def reg(id, value = nil)
|
231
|
-
return @registers[id] if value.nil?
|
232
|
-
return if id == REG_ZERO # $0 cannot be overwritten
|
233
|
-
@registers[id] = value
|
234
|
-
end
|
235
|
-
|
236
|
-
def jmp(addr)
|
237
|
-
@ip = addr * Consts::WORD_SIZE
|
238
|
-
end
|
239
|
-
|
240
|
-
def branch(rel_addr)
|
241
|
-
@ip += rel_addr * Consts::WORD_SIZE
|
242
|
-
end
|
243
|
-
|
244
|
-
def bind_opcode(opcode, method)
|
245
|
-
fail "OpCode already defined - #{opcode}." if @opcodes.key? opcode
|
246
|
-
@opcodes[opcode] = {
|
247
|
-
method: method
|
248
|
-
}
|
249
|
-
end
|
250
|
-
|
251
|
-
def iterate
|
252
|
-
opcode = subsystem(:mem).read @ip
|
253
|
-
@ip += Consts::WORD_SIZE
|
254
|
-
info = Utils.decode_opcode opcode
|
255
|
-
send @opcodes[info.cmd][:method], info
|
256
|
-
end
|
257
|
-
end
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end
|
data/lib/haxor/vm/registers.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
module Haxor
|
2
|
-
module Vm
|
3
|
-
class Registers < Subsystem
|
4
|
-
def initialize
|
5
|
-
@registers = {}
|
6
|
-
end
|
7
|
-
|
8
|
-
def flag(flag, enabled)
|
9
|
-
flags = read 'fr'
|
10
|
-
if enabled
|
11
|
-
flags |= flag
|
12
|
-
else
|
13
|
-
flags &= ~flag
|
14
|
-
end
|
15
|
-
write 'fr', flags
|
16
|
-
end
|
17
|
-
|
18
|
-
def check_flag(flag)
|
19
|
-
flags = read 'fr'
|
20
|
-
(flags & flag) > 0
|
21
|
-
end
|
22
|
-
|
23
|
-
def read(register)
|
24
|
-
addr = resolve register
|
25
|
-
@vm.subsystem(:mem).read addr
|
26
|
-
end
|
27
|
-
|
28
|
-
def write(register, value)
|
29
|
-
addr = resolve register
|
30
|
-
@vm.subsystem(:mem).write addr, value
|
31
|
-
end
|
32
|
-
|
33
|
-
def resolve(register)
|
34
|
-
@registers[register]
|
35
|
-
end
|
36
|
-
|
37
|
-
def add_register(register, addr)
|
38
|
-
@registers[register] = addr
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|