1
+ use super :: flag_set:: FlagSet ;
1
2
use super :: memory:: Memory ;
2
3
use super :: register_set:: RegisterSet ;
4
+ use crate :: interpreter:: flag_set:: Flag ;
3
5
use crate :: utils:: { min, HexdumpFormatter } ;
4
- use crate :: x86:: { Address , Displacement , Register } ;
6
+ use crate :: x86:: { Address , Displacement , Operand , Register } ;
5
7
use crate :: { minix:: Program , x86:: IR } ;
6
8
7
9
use log:: trace;
@@ -10,23 +12,29 @@ use log::trace;
10
12
mod opcodes;
11
13
use opcodes:: OpcodeExecutable ;
12
14
15
+ #[ allow( dead_code) ]
13
16
struct VM {
14
17
// cpu
15
18
pub ip : u16 ,
16
19
// memory
17
20
pub text : Memory ,
18
21
pub data : Memory ,
19
- // registers
22
+ // registers, flags
20
23
pub regs : RegisterSet ,
21
- pub flags : u16 ,
24
+ pub flags : FlagSet ,
22
25
}
23
26
24
27
impl From < Program > for VM {
25
28
fn from ( program : Program ) -> Self {
26
29
let text = Memory :: from ( program. text_segment . data ) ;
27
- let data = Memory :: from ( program. data_segment . data ) ;
28
- let regs = RegisterSet :: new ( ) ;
29
- let flags = 0 ;
30
+
31
+ let size = 0x1000 ;
32
+ let mut data = Memory :: new ( size) ;
33
+ data. write_bytes ( 0 , & program. data_segment . data ) ;
34
+
35
+ let mut regs = RegisterSet :: new ( ) ;
36
+ regs. set ( Register :: SP , ( data. len ( ) - 2 ) as i16 ) ;
37
+ let flags = FlagSet :: new ( ) ;
30
38
let ip = 0 ;
31
39
VM {
32
40
ip,
@@ -83,21 +91,56 @@ impl VmIrExecutable for VM {
83
91
IR :: Add { dest, src } => {
84
92
self . add ( dest, src) ;
85
93
}
86
- // pop, push, ...
87
- _ => panic ! ( "Not implemented" ) ,
94
+ IR :: Xor { dest, src } => {
95
+ self . xor ( dest, src) ;
96
+ }
97
+ IR :: Lea { dest, src } => {
98
+ self . lea ( dest, src) ;
99
+ }
100
+ IR :: Cmp { dest, src, byte : _ } => {
101
+ self . cmp ( dest, src) ;
102
+ }
103
+ IR :: Jnb { dest } => {
104
+ self . jnb ( dest) ;
105
+ }
106
+ IR :: Jne { dest } => {
107
+ self . jne ( dest) ;
108
+ }
109
+ IR :: Je { dest } => {
110
+ self . je ( dest) ;
111
+ }
112
+ IR :: Test { dest, src, byte : _ } => {
113
+ self . test ( dest, src) ;
114
+ }
115
+ IR :: Push { src } => {
116
+ self . push ( src) ;
117
+ }
118
+ IR :: Call { dest } => {
119
+ self . call ( dest) ;
120
+ }
121
+ IR :: In { dest, src } => {
122
+ self . in_ ( dest, src) ;
123
+ }
124
+ IR :: Loopnz { dest } => {
125
+ self . loopnz ( dest) ;
126
+ }
127
+ IR :: Or { dest, src } => {
128
+ self . or ( dest, src) ;
129
+ }
130
+ _ => panic ! ( "{}: Not implemented" , ir) ,
88
131
}
89
132
}
90
133
91
134
fn run ( & mut self ) {
92
- trace ! ( " AX BX CX DX SP BP SI DI FLAGS IP" ) ;
135
+ trace ! ( " AX BX CX DX SP BP SI DI IP" ) ;
93
136
while let Some ( ir) = self . fetch ( ) {
94
137
let ( decoded_ir, ir_len) = self . decode ( ir) ;
95
138
96
139
// Trace with format:
97
140
// AX BX CX DX SP BP SI DI FLAGS IP
98
141
// 0000 0000 0000 0000 0000 0000 0000 0000 ---- 0000:bb0000 mov bx, 000
99
142
trace ! (
100
- "{} \t {}" ,
143
+ "{} \t {}" ,
101
144
{
102
145
let mut regs = String :: new( ) ;
103
146
for reg in vec![
@@ -112,10 +155,14 @@ impl VmIrExecutable for VM {
112
155
] {
113
156
regs. push_str( & format!( "{:04x} " , self . regs. get( reg) ) ) ;
114
157
}
158
+ let mut flags = String :: new( ) ;
159
+ for flag in Flag :: iter( ) {
160
+ flags. push_str( & format!( "{}" , self . flags. get( flag) as u8 ) ) ;
161
+ }
115
162
format!(
116
- "{} {:04x } {:04x}:{}" ,
163
+ "{} {} {:04x}:{}" ,
117
164
regs,
118
- self . flags,
165
+ flags,
119
166
self . ip,
120
167
& ir[ ..ir_len]
121
168
. iter( )
@@ -131,7 +178,7 @@ impl VmIrExecutable for VM {
131
178
// Increment the instruction pointer (ip) appropriately
132
179
self . ip += ir_len as u16 ;
133
180
}
134
- trace ! ( "Execution finished:\n {}" , self ) ;
181
+ // trace!("Execution finished:\n{}", self);
135
182
}
136
183
}
137
184
@@ -165,12 +212,26 @@ impl VM {
165
212
166
213
base. wrapping_add ( index) . wrapping_add ( disp) as u16
167
214
}
215
+
216
+ fn into_value ( & self , operand : Operand ) -> i16 {
217
+ match operand {
218
+ Operand :: Register ( reg) => self . regs . get ( reg) ,
219
+ Operand :: Immediate ( value) => value as i16 ,
220
+ Operand :: LongImmediate ( value) => value as i16 ,
221
+ Operand :: SignExtendedImmediate ( value) => value as i16 ,
222
+ Operand :: MemoryAddress ( address) => {
223
+ let ea = self . get_effective_address ( address) ;
224
+ self . data . read_word ( ea) as i16
225
+ }
226
+ Operand :: Displacement ( value) => self . ip . wrapping_add ( value. into ( ) ) as i16 ,
227
+ }
228
+ }
168
229
}
169
230
170
231
impl std:: fmt:: Display for VM {
171
232
fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
172
233
writeln ! ( f, "IP: {:04x}" , self . ip) ?;
173
- writeln ! ( f, "FLAGS: {:04x }" , self . flags) ?;
234
+ writeln ! ( f, "FLAGS: {}" , self . flags) ?;
174
235
writeln ! ( f, "TEXT:" ) ?;
175
236
write ! ( f, "{:?}" , HexdumpFormatter ( & self . text. data) ) ?;
176
237
writeln ! ( f, "DATA:" ) ?;
0 commit comments