Completed add, sub, cmp and jump simulations
This commit is contained in:
@@ -1,11 +1,18 @@
|
||||
#include "include/aliases.h"
|
||||
#include "include/flag_access.h"
|
||||
#include "include/reg_access.h"
|
||||
#include "include/sim86_lib.h"
|
||||
#include <bits/types/FILE.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
void decode_operand(instruction_operand operand);
|
||||
struct basic_string {
|
||||
char str[4096];
|
||||
};
|
||||
|
||||
u16 get_operand_value(instruction_operand operand);
|
||||
basic_string get_operand_string(instruction_operand operand);
|
||||
void print_instruction(instruction inst);
|
||||
void mov_to_register(const register_access ®,
|
||||
const instruction_operand &source);
|
||||
|
||||
@@ -44,6 +51,8 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
bool accessed_registers[REGISTER_COUNT] = {false};
|
||||
|
||||
printf("\nDisassembly:\n");
|
||||
|
||||
while (offset < size) {
|
||||
instruction decoded;
|
||||
Sim86_Decode8086Instruction(size - offset, buffer + offset, &decoded);
|
||||
@@ -51,46 +60,129 @@ int main(int argc, char *argv[]) {
|
||||
if (decoded.Op) {
|
||||
offset += decoded.Size;
|
||||
|
||||
if (decoded.Op == Op_mov) {
|
||||
instruction_operand dest = decoded.Operands[0];
|
||||
instruction_operand source = decoded.Operands[1];
|
||||
print_instruction(decoded);
|
||||
|
||||
instruction_operand dest = decoded.Operands[0];
|
||||
instruction_operand source = decoded.Operands[1];
|
||||
|
||||
switch (decoded.Op) {
|
||||
case Op_mov: {
|
||||
|
||||
if (dest.Type == Operand_Register) {
|
||||
mov_to_register(dest.Register, source);
|
||||
|
||||
accessed_registers[dest.Register.Index] = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Op_add: {
|
||||
if (dest.Type == Operand_Register) {
|
||||
u16 value = get_register(dest.Register);
|
||||
|
||||
value += get_operand_value(source);
|
||||
set_flags(value);
|
||||
|
||||
set_register(dest.Register, value);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Op_sub:
|
||||
case Op_cmp: {
|
||||
if (dest.Type == Operand_Register) {
|
||||
u16 value = get_register(dest.Register);
|
||||
|
||||
value -= get_operand_value(source);
|
||||
set_flags(value);
|
||||
|
||||
if (decoded.Op == Op_sub) {
|
||||
set_register(dest.Register, value);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case Op_jne: {
|
||||
if (!get_flag(FLAG_ZERO)) {
|
||||
i16 inst_offset = get_operand_value(dest);
|
||||
|
||||
offset += inst_offset;
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\nFinal registers:\n");
|
||||
|
||||
for (u32 i = 0; i < REGISTER_COUNT; ++i) {
|
||||
if (accessed_registers[i]) {
|
||||
register_access reg = {i, 0, 2};
|
||||
u16 value = get_register(reg);
|
||||
|
||||
printf("%s: 0x%04x (%d)\n", get_register_name(reg), value, value);
|
||||
printf("\t%s: 0x%04x (%d)\n", get_register_name(reg), value, value);
|
||||
}
|
||||
}
|
||||
|
||||
// Print the instruction pointer register
|
||||
printf("\tip: 0x%04x (%d)\n", offset, offset);
|
||||
|
||||
printf("\nFinal flags:\n");
|
||||
print_flags();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void decode_operand(instruction_operand operand) {
|
||||
u16 get_operand_value(instruction_operand operand) {
|
||||
switch (operand.Type) {
|
||||
case Operand_Register:
|
||||
printf("Register operand: %d, %d, %d\n", operand.Register.Index,
|
||||
operand.Register.Offset, operand.Register.Count);
|
||||
return get_register(operand.Register);
|
||||
|
||||
break;
|
||||
case Operand_Memory:
|
||||
// printf("Memory operand\n");
|
||||
return 0;
|
||||
|
||||
break;
|
||||
case Operand_Immediate:
|
||||
// printf("Immediate operand\n");
|
||||
return operand.Immediate.Value;
|
||||
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
basic_string get_operand_string(instruction_operand operand) {
|
||||
basic_string output = {""};
|
||||
|
||||
switch (operand.Type) {
|
||||
case Operand_Register:
|
||||
sprintf(output.str, "%s", get_register_name(operand.Register));
|
||||
|
||||
break;
|
||||
case Operand_Memory:
|
||||
sprintf(output.str, "%s", "MEM OPERAND");
|
||||
|
||||
break;
|
||||
case Operand_Immediate:
|
||||
sprintf(output.str, "%d", operand.Immediate.Value);
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void print_instruction(instruction inst) {
|
||||
printf("\t%s %s, %s\n", Sim86_MnemonicFromOperationType(inst.Op),
|
||||
get_operand_string(inst.Operands[0]).str,
|
||||
get_operand_string(inst.Operands[1]).str);
|
||||
}
|
||||
|
||||
void mov_to_register(const register_access ®,
|
||||
|
||||
Reference in New Issue
Block a user