Completed add, sub, cmp and jump simulations

This commit is contained in:
Abdelrahman Said 2023-04-08 19:26:31 +01:00
parent 43c748e0c5
commit c320371432
10 changed files with 333 additions and 10 deletions

8
8086_sim/.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
listing_0043_immediate_movs
listing_0044_register_movs
listing_0045_challenge_register_movs
listing_0046_add_sub_cmp
listing_0047_challenge_flags
listing_0048_ip_register
listing_0049_conditional_jumps
listing_0050_challenge_jumps

57
8086_sim/flag_access.cpp Normal file
View File

@ -0,0 +1,57 @@
#include "include/flag_access.h"
#include "include/aliases.h"
#include <stdio.h>
const char *get_flag_string(flag_access flag);
static bool flags[FLAG_COUNT] = {false};
bool get_flag(flag_access flag) {
if (flag < FLAG_COUNT) {
return flags[flag];
}
return false;
}
void set_flags(u16 value) {
if (value == 0) {
flags[FLAG_ZERO] = true;
flags[FLAG_SIGN] = false;
} else if ((value & 0x8000) == 0x8000) {
flags[FLAG_ZERO] = false;
flags[FLAG_SIGN] = true;
} else {
flags[FLAG_ZERO] = false;
flags[FLAG_SIGN] = false;
}
}
void print_flags() {
printf("\t");
for (u32 i = 0; i < FLAG_COUNT; ++i) {
if (flags[i]) {
printf("%s", get_flag_string((flag_access)i));
}
}
printf("\n");
}
const char *get_flag_string(flag_access flag) {
const char *output = "";
switch (flag) {
case FLAG_ZERO:
output = "Z";
break;
case FLAG_SIGN:
output = "S";
break;
default:
break;
}
return output;
}

View File

@ -0,0 +1,17 @@
#ifndef FLAG_ACCESS_H
#define FLAG_ACCESS_H
#include "aliases.h"
enum flag_access : u8 {
FLAG_ZERO,
FLAG_SIGN,
FLAG_COUNT
};
bool get_flag(flag_access flag);
void set_flags(u16 value);
void print_flags();
#endif // !FLAG_ACCESS_H

View File

@ -0,0 +1,28 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 46
; ========================================================================
bits 16
mov bx, -4093
mov cx, 3841
sub bx, cx
mov sp, 998
mov bp, 999
cmp bp, sp
add bp, 1027
sub bp, 2026

View File

@ -0,0 +1,36 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 47
; ========================================================================
bits 16
add bx, 30000
add bx, 10000
sub bx, 5000
sub bx, 5000
mov bx, 1
mov cx, 100
add bx, cx
mov dx, 10
sub cx, dx
add bx, 40000
add cx, -90
mov sp, 99
mov bp, 98
cmp bp, sp

View File

@ -0,0 +1,23 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 48
; ========================================================================
bits 16
mov cx, 200
mov bx, cx
add cx, 1000
mov bx, 2000
sub cx, bx

View File

@ -0,0 +1,24 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 49
; ========================================================================
bits 16
mov cx, 3
mov bx, 1000
loop_start:
add bx, 10
sub cx, 1
jnz loop_start

View File

@ -0,0 +1,38 @@
; ========================================================================
;
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
;
; This software is provided 'as-is', without any express or implied
; warranty. In no event will the authors be held liable for any damages
; arising from the use of this software.
;
; Please see https://computerenhance.com for further information
;
; ========================================================================
; ========================================================================
; LISTING 50
; ========================================================================
bits 16
mov ax, 10
mov bx, 10
mov cx, 10
label_0:
cmp bx, cx
je label_1
add ax, 1
jp label_2
label_1:
sub bx, 5
jb label_3
label_2:
sub cx, 2
label_3:
loopnz label_0

BIN
8086_sim/sim86 Executable file

Binary file not shown.

View File

@ -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 &reg,
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 &reg,