a bug about extract_operand
Summary
fn extract_operand(t: &Token, results: &mut Vec<u8>, symbols: &SymbolTable) {
match t {
Token::Register { reg_num } => {
results.push(*reg_num);
}
// This operand is a bit special. Since we use fixed width instructions, we only have 16-bits to use for the number.
// If the user wants to store a 32-bit register, we need to convert the number into bits, and then use two instructions to
// get the entire value into the register
Token::IntegerOperand { value } => {
if *value > MAX_I16 || *value < MIN_I16 {
// This creates the second instructino that loads the second group of 16 bits
let mut wtr = vec![];
wtr.write_i32::<LittleEndian>(*value).unwrap();
results.push(wtr[3]);
results.push(wtr[2]);
let opcode: u8 = 39;
let register_offset = results.len() - 3;
let register = results[register_offset];
// here!!!!
results.push(opcode);
results.push(register);
results.push(wtr[1]);
results.push(wtr[0]);
} else {
let mut wtr = vec![];
wtr.write_i32::<LittleEndian>(*value).unwrap();
results.push(wtr[1]);
results.push(wtr[0]);
}
}
// ...
It is a obvious bug. Because the extract_operand
is called by to_bytes
which is called by process_second_phase
.
If we add one more instruction during second phase, the jmp
instruction will behave uncorrectly.
And the function didn't deal with Token::FloatOperand
.
And, the project is still continuing?
Edited by yjhmelody