mirror of
https://github.com/Ed94/perfaware.git
synced 2024-12-22 06:54:45 -08:00
initial implmeentation...
the direction bit is throwing me off vs the order I'm seeing from nasm's syntax.
This commit is contained in:
parent
a12ba641f1
commit
5b230d5653
@ -1,5 +1,5 @@
|
|||||||
project( 'sim_8086', 'c', 'cpp' )
|
project( 'sim_8086', 'c', 'cpp', default_options : ['buildtype=debug'] )
|
||||||
|
|
||||||
include_thirdparty = include_directories( '../thirdparty' )
|
include_thirdparty = include_directories( '../thirdparty' )
|
||||||
|
|
||||||
executable( 'sim_8086', 'sim_8086.c', include_directories : include_thirdparty )
|
executable( 'sim_8086', 'sim_8086.cpp', include_directories : include_thirdparty )
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
#define ZPL_IMPLEMENTATION
|
|
||||||
#include "zpl.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
zpl_printf("sim 8086!");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
647
part_1/sim_8086.cpp
Normal file
647
part_1/sim_8086.cpp
Normal file
@ -0,0 +1,647 @@
|
|||||||
|
#if __clang__
|
||||||
|
#pragma clang diagnostic ignored "-Wunused-const-variable"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#pragma region ZPL INCLUDE
|
||||||
|
|
||||||
|
#if __clang__
|
||||||
|
#pragma clang diagnostic push
|
||||||
|
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||||
|
#pragma clang diagnostic ignored "-Wbraced-scalar-init"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ZPL_IMPLEMENTATION
|
||||||
|
#include "zpl.h"
|
||||||
|
|
||||||
|
#if __clang__
|
||||||
|
#pragma clang diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#pragma endregion ZPL INCLUDE
|
||||||
|
|
||||||
|
|
||||||
|
// This has me screwing around with generating lookup tables.
|
||||||
|
// Going to measure the difference between them and jump tables instructions at some point...
|
||||||
|
|
||||||
|
// Binary formatting for literals is used heavily as that is
|
||||||
|
// how the encoding is conveyed in the hardware reference from intel.
|
||||||
|
|
||||||
|
|
||||||
|
#define bit( value ) ( 1 << value )
|
||||||
|
#define bitfield_is_equal( field_, mask_ ) ( ( mask_ & field_ ) == mask_ )
|
||||||
|
#define ct constexpr
|
||||||
|
#define forceinline ZPL_ALWAYS_INLINE
|
||||||
|
#define MSG_INVALID_VALUE "INVALID VALUE PROVIDED"
|
||||||
|
|
||||||
|
|
||||||
|
using u8 = unsigned char;
|
||||||
|
using u16 = unsigned short;
|
||||||
|
using u32 = unsigned long;
|
||||||
|
|
||||||
|
// using bytecode = u8;
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
char char_binary( u8 value, u8 pos )
|
||||||
|
{
|
||||||
|
constexpr u8 baseline = 1;
|
||||||
|
u8 mask = baseline << pos;
|
||||||
|
|
||||||
|
return ( (baseline << pos) & value) == mask ? '1' : '0';
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
void str_binary( char* result, u8 value )
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
result[0] = char_binary( value, 0);
|
||||||
|
result[1] = char_binary( value, 1);
|
||||||
|
result[2] = char_binary( value, 2);
|
||||||
|
result[3] = char_binary( value, 3);
|
||||||
|
result[4] = char_binary( value, 4);
|
||||||
|
result[5] = char_binary( value, 5);
|
||||||
|
result[6] = char_binary( value, 6);
|
||||||
|
result[7] = char_binary( value, 7);
|
||||||
|
#else
|
||||||
|
result[0] = char_binary( value, 7);
|
||||||
|
result[1] = char_binary( value, 6);
|
||||||
|
result[2] = char_binary( value, 5);
|
||||||
|
result[3] = char_binary( value, 4);
|
||||||
|
result[4] = char_binary( value, 3);
|
||||||
|
result[5] = char_binary( value, 2);
|
||||||
|
result[6] = char_binary( value, 1);
|
||||||
|
result[7] = char_binary( value, 0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define USE_LOOKUP_TABLE 0
|
||||||
|
namespace Op
|
||||||
|
{
|
||||||
|
ct u8 Mask = 0b11111100;
|
||||||
|
|
||||||
|
#define D_Opcodes \
|
||||||
|
D_Entry( mov_88 ) \
|
||||||
|
D_Entry( mov_89 ) \
|
||||||
|
|
||||||
|
using Type = u8;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
#if USE_LOOKUP_TABLE
|
||||||
|
#define D_Entry( Entry_ ) Entry_,
|
||||||
|
D_Opcodes
|
||||||
|
#undef D_Entry
|
||||||
|
|
||||||
|
#else
|
||||||
|
mov_88 = 0b10001000,
|
||||||
|
mov_89 = 0b11000100,
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Num = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
#if USE_LOOKUP_TABLE
|
||||||
|
ct u8 code( Type type )
|
||||||
|
{
|
||||||
|
constexpr u8
|
||||||
|
type_to_code[ Num ] =
|
||||||
|
{
|
||||||
|
0b01000100, // mov_88
|
||||||
|
0b11000100, // mov_89
|
||||||
|
};
|
||||||
|
|
||||||
|
return type_to_code[ type ];
|
||||||
|
}
|
||||||
|
|
||||||
|
ct u8 type( u8 code )
|
||||||
|
{
|
||||||
|
switch ( code )
|
||||||
|
{
|
||||||
|
#define D_Entry
|
||||||
|
case 0b01000100:
|
||||||
|
return mov_88;
|
||||||
|
|
||||||
|
#undef D_Entry
|
||||||
|
}
|
||||||
|
|
||||||
|
return Num;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char const* str( Type type )
|
||||||
|
{
|
||||||
|
#if Op_USE_LOOKUP_TABLE
|
||||||
|
static char const*
|
||||||
|
type_to_str[ Num ] =
|
||||||
|
{
|
||||||
|
#define D_Entry( Entry_ ) #Entry_,
|
||||||
|
D_Opcodes
|
||||||
|
#undef D_Entry
|
||||||
|
};
|
||||||
|
|
||||||
|
return type_to_str[ type ];
|
||||||
|
|
||||||
|
#else
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case mov_88:
|
||||||
|
return "mov_88";
|
||||||
|
case mov_89:
|
||||||
|
return "mov_89";
|
||||||
|
}
|
||||||
|
|
||||||
|
return MSG_INVALID_VALUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ct char const* helper_meumonic( Type type )
|
||||||
|
{
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case mov_88:
|
||||||
|
case mov_89:
|
||||||
|
return "mov";
|
||||||
|
}
|
||||||
|
|
||||||
|
return MSG_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* meumonic( Type type )
|
||||||
|
{
|
||||||
|
#if USE_LOOKUP_TABLE
|
||||||
|
static char const*
|
||||||
|
type_to_meumonic[ Num ] =
|
||||||
|
{
|
||||||
|
#define D_Entry( Entry_ ) helper_meumonic( Entry_ ),
|
||||||
|
D_Opcodes
|
||||||
|
#undef D_Entry
|
||||||
|
};
|
||||||
|
|
||||||
|
return type_to_meumonic[ type ];
|
||||||
|
|
||||||
|
#else
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case mov_88:
|
||||||
|
case mov_89:
|
||||||
|
return "mov";
|
||||||
|
}
|
||||||
|
|
||||||
|
return MSG_INVALID_VALUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
ct char const* helper_intuitive( Type type )
|
||||||
|
{
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case mov_88:
|
||||||
|
case mov_89:
|
||||||
|
return "move";
|
||||||
|
}
|
||||||
|
|
||||||
|
return MSG_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* intuitive( Type type )
|
||||||
|
{
|
||||||
|
#if USE_LOOKUP_TABLE
|
||||||
|
static char const*
|
||||||
|
type_to_meumonic[ Num ] =
|
||||||
|
{
|
||||||
|
#define D_Entry( Entry_ ) helper_intuitive( Entry_ ),
|
||||||
|
D_Opcodes
|
||||||
|
#undef D_Entry
|
||||||
|
};
|
||||||
|
|
||||||
|
return type_to_meumonic[ type ];
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case mov_88:
|
||||||
|
case mov_89:
|
||||||
|
return "move";
|
||||||
|
}
|
||||||
|
|
||||||
|
return MSG_INVALID_VALUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef D_Opcodes
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Field
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
using Type = u8;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Dir_REG_Dest = 0b00,
|
||||||
|
Dir_REG_Src = 0b10,
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
ct u8 Mask_Dir = 0b00000010;
|
||||||
|
ct u8 Mask_Width = 0b00000001;
|
||||||
|
ct u8 Mask_Mode = 0b11000000;
|
||||||
|
|
||||||
|
// Mask: Effective Address
|
||||||
|
inline u8 mask_reg_operand( u8 reg )
|
||||||
|
{
|
||||||
|
return reg << 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://i.imgur.com/drsyYnM.png
|
||||||
|
ct u8 Dir_REG_Src = 0b00;
|
||||||
|
ct u8 Dir_REG_Dest = 0b10;
|
||||||
|
|
||||||
|
inline
|
||||||
|
char const* str_direction( u8 direction )
|
||||||
|
{
|
||||||
|
switch ( direction )
|
||||||
|
{
|
||||||
|
case Dir_REG_Dest:
|
||||||
|
return "Destination";
|
||||||
|
|
||||||
|
case Dir_REG_Src:
|
||||||
|
return "Source";
|
||||||
|
}
|
||||||
|
|
||||||
|
return MSG_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://i.imgur.com/9Op8Lnd.png
|
||||||
|
ct u8 Width_Byte = 0b00;
|
||||||
|
ct u8 Width_Word = 0b01;
|
||||||
|
|
||||||
|
inline
|
||||||
|
char const* str_width( u8 width )
|
||||||
|
{
|
||||||
|
switch ( width )
|
||||||
|
{
|
||||||
|
case Width_Byte:
|
||||||
|
return "Byte";
|
||||||
|
|
||||||
|
case Width_Word:
|
||||||
|
return "Word";
|
||||||
|
}
|
||||||
|
|
||||||
|
return MSG_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// https://i.imgur.com/Job2oPd.png
|
||||||
|
ct u8 Mode_Mem = 0b00000000;
|
||||||
|
ct u8 Mode_Mem8 = 0b01000000;
|
||||||
|
ct u8 Mode_Mem16 = 0b10000000;
|
||||||
|
ct u8 Mode_Reg = 0b11000000;
|
||||||
|
|
||||||
|
char const* str_mode( u8 mode )
|
||||||
|
{
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case Mode_Mem:
|
||||||
|
return "Memory: No Displacement";
|
||||||
|
|
||||||
|
case Mode_Mem8:
|
||||||
|
return "Memory: 8-bit Displacment";
|
||||||
|
|
||||||
|
case Mode_Mem16:
|
||||||
|
return "Memory: 16-bit Displacement";
|
||||||
|
|
||||||
|
case Mode_Reg:
|
||||||
|
return "Register";
|
||||||
|
}
|
||||||
|
|
||||||
|
return MSG_INVALID_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
ct u8 RegMem_AL = 0b00000000;
|
||||||
|
ct u8 RegMem_AX = 0b00000000;
|
||||||
|
ct u8 RegMem_BX_SI = 0b00000000;
|
||||||
|
ct u8 RegMem_BX_SI_D8 = 0b00000000;
|
||||||
|
ct u8 RegMem_BX_SI_D16 = 0b00000000;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Register
|
||||||
|
{
|
||||||
|
ct u8 Mask_Left = 0b00111000;
|
||||||
|
ct u8 Mask_Right = 0b00000111;
|
||||||
|
|
||||||
|
#define D_Opcodes \
|
||||||
|
D_Entry( AL ) \
|
||||||
|
D_Entry( CL ) \
|
||||||
|
D_Entry( DL ) \
|
||||||
|
D_Entry( BL ) \
|
||||||
|
D_Entry( AH ) \
|
||||||
|
D_Entry( CH ) \
|
||||||
|
D_Entry( DH ) \
|
||||||
|
D_Entry( BH ) \
|
||||||
|
D_Entry( AX ) \
|
||||||
|
D_Entry( CX ) \
|
||||||
|
D_Entry( DX ) \
|
||||||
|
D_Entry( BX ) \
|
||||||
|
D_Entry( SP ) \
|
||||||
|
D_Entry( BP ) \
|
||||||
|
D_Entry( SI ) \
|
||||||
|
D_Entry( DI ) \
|
||||||
|
|
||||||
|
using Type = u8;
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
// Endianness is prob wrong...
|
||||||
|
AL = 0b000,
|
||||||
|
CL = 0b001,
|
||||||
|
DL = 0b010,
|
||||||
|
BL = 0b011,
|
||||||
|
|
||||||
|
AH = 0b100,
|
||||||
|
CH = 0b101,
|
||||||
|
DH = 0b110,
|
||||||
|
BH = 0b111,
|
||||||
|
|
||||||
|
AX = 0b000,
|
||||||
|
CX = 0b001,
|
||||||
|
DX = 0b010,
|
||||||
|
BX = 0b011,
|
||||||
|
|
||||||
|
SP = 0b100,
|
||||||
|
BP = 0b101,
|
||||||
|
SI = 0b110,
|
||||||
|
DI = 0b111,
|
||||||
|
|
||||||
|
Num = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
char const* meumonic( Type type, u8 Width )
|
||||||
|
{
|
||||||
|
static char const*
|
||||||
|
Type_To_Meumonic[ Num ] =
|
||||||
|
{
|
||||||
|
#define D_Entry( Entry_ ) #Entry_,
|
||||||
|
D_Opcodes
|
||||||
|
#undef D_Entry
|
||||||
|
};
|
||||||
|
|
||||||
|
return Type_To_Meumonic[ type + Width * 7 + 1 ];
|
||||||
|
}
|
||||||
|
|
||||||
|
char const* intuitive( Type type, u8 Width )
|
||||||
|
{
|
||||||
|
static char const*
|
||||||
|
Type_To_Intuitive[ Num ] =
|
||||||
|
{
|
||||||
|
"A.Low",
|
||||||
|
"C.Low",
|
||||||
|
"D.Low",
|
||||||
|
"B.Low",
|
||||||
|
"A.High",
|
||||||
|
"C.High",
|
||||||
|
"D.High",
|
||||||
|
"B.High",
|
||||||
|
"A.16",
|
||||||
|
"C.16",
|
||||||
|
"D.16",
|
||||||
|
"B.16",
|
||||||
|
"Stack.Pointer",
|
||||||
|
"Stack.Base",
|
||||||
|
"Source.Index",
|
||||||
|
"Destination.Index",
|
||||||
|
};
|
||||||
|
|
||||||
|
return Type_To_Intuitive[ type + 8 * Width ];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8086 Instructions are 1 to 6 bytes in length.
|
||||||
|
struct POD_Instruction
|
||||||
|
{
|
||||||
|
u8 Byte_1;
|
||||||
|
u8 Byte_2;
|
||||||
|
u8 Byte_3;
|
||||||
|
u8 Byte_4;
|
||||||
|
u8 Byte_5;
|
||||||
|
u8 Byte_6;
|
||||||
|
|
||||||
|
u16 Pad;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Instruction : public POD_Instruction
|
||||||
|
{
|
||||||
|
inline
|
||||||
|
u8 direction()
|
||||||
|
{
|
||||||
|
u8 direction = Byte_1 & Field::Mask_Dir;
|
||||||
|
|
||||||
|
return direction;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
u8 mode()
|
||||||
|
{
|
||||||
|
u8 mode = Byte_2 & Field::Mask_Mode;
|
||||||
|
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
u8 opcode()
|
||||||
|
{
|
||||||
|
u8
|
||||||
|
opcode = Byte_1 & Op::Mask;
|
||||||
|
|
||||||
|
return opcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
u8 operand_left()
|
||||||
|
{
|
||||||
|
u8
|
||||||
|
operand = Byte_2 & Register::Mask_Left;
|
||||||
|
operand >>= 3;
|
||||||
|
|
||||||
|
return operand;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
u8 operand_right()
|
||||||
|
{
|
||||||
|
u8
|
||||||
|
operand = Byte_2 & Register::Mask_Right;
|
||||||
|
// operand <<= 1;
|
||||||
|
|
||||||
|
return operand;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
u8 width()
|
||||||
|
{
|
||||||
|
u8 width = Byte_1 & Field::Mask_Width;
|
||||||
|
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
void disassemble()
|
||||||
|
{
|
||||||
|
using namespace Field;
|
||||||
|
using namespace Op;
|
||||||
|
using namespace Register;
|
||||||
|
|
||||||
|
u8 width_val = width();
|
||||||
|
|
||||||
|
char const* opcode_str = Op::meumonic( opcode() );
|
||||||
|
char const* direction_str = Field::str_direction( direction() );
|
||||||
|
char const* width_str = Field::str_width( width_val );
|
||||||
|
char const* mode_str = Field::str_mode( mode() );
|
||||||
|
char const* operand_left_str = Register::meumonic( operand_left(), width_val );
|
||||||
|
char const* operand_right_str = Register::meumonic( operand_right(), width_val );
|
||||||
|
|
||||||
|
char
|
||||||
|
binary_string[9];
|
||||||
|
binary_string[8] = '\0';
|
||||||
|
|
||||||
|
str_binary( binary_string, opcode() );
|
||||||
|
zpl_printf("\nOpcode : %s : %s", binary_string, opcode_str);
|
||||||
|
|
||||||
|
str_binary( binary_string, direction() );
|
||||||
|
zpl_printf("\nDirection : %s : %s", binary_string, direction_str);
|
||||||
|
|
||||||
|
str_binary( binary_string, width_val );
|
||||||
|
zpl_printf("\nWidth : %s : %s", binary_string, width_str);
|
||||||
|
|
||||||
|
str_binary( binary_string, mode() );
|
||||||
|
zpl_printf("\nMode : %s : %s", binary_string, mode_str);
|
||||||
|
|
||||||
|
str_binary( binary_string, operand_left() );
|
||||||
|
zpl_printf("\nOperand : %s : %s", binary_string, operand_left_str);
|
||||||
|
|
||||||
|
str_binary( binary_string, operand_right() );
|
||||||
|
zpl_printf("\nOperand EA : %s : %s", binary_string, operand_right_str);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Tests
|
||||||
|
{
|
||||||
|
zpl_arena BlobArena {};
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
zpl_arena_init_from_allocator( & BlobArena, zpl_heap(), zpl_megabytes(1) );
|
||||||
|
|
||||||
|
if ( BlobArena.total_size == 0 )
|
||||||
|
{
|
||||||
|
zpl_assert_crash( "Failed to reserve memory for Tests:: BLobArena" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Try_MockInstruction()
|
||||||
|
{
|
||||||
|
using namespace Field;
|
||||||
|
using namespace Op;
|
||||||
|
using namespace Register;
|
||||||
|
|
||||||
|
Instruction
|
||||||
|
mock; // mov AX, BX
|
||||||
|
#if USE_LOOKUP_TABLE
|
||||||
|
mock.Byte_1 = Op::code(mov_88) | Dir_REG_Dest | Field::Width_Word;
|
||||||
|
#else
|
||||||
|
mock.Byte_1 = mov_88 | Dir_REG_Src | Field::Width_Word;
|
||||||
|
#endif
|
||||||
|
mock.Byte_2 = Field::Mode_Reg | Field::mask_reg_operand(BX) | CX;
|
||||||
|
|
||||||
|
zpl_printf("\n\nAttempting Mock Instruction: mov CX, BX");
|
||||||
|
|
||||||
|
char
|
||||||
|
binary_string[9];
|
||||||
|
binary_string[8] = '\0';
|
||||||
|
|
||||||
|
str_binary( binary_string, mock.Byte_1 );
|
||||||
|
zpl_printf("\n%s", binary_string);
|
||||||
|
|
||||||
|
str_binary( binary_string, mock.Byte_2 );
|
||||||
|
zpl_printf("\n%s", binary_string);
|
||||||
|
|
||||||
|
mock.disassemble();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Try_Blob_SingleRegisterMove()
|
||||||
|
{
|
||||||
|
zpl_printf("\n\nAttempting to read blob: listing_0037_single_register_mov");
|
||||||
|
|
||||||
|
zpl_file_contents
|
||||||
|
blob = zpl_file_read_contents( zpl_arena_allocator( & BlobArena), false,
|
||||||
|
"tests/listing_0037_single_register_mov"
|
||||||
|
// "tests/listing_0038_many_register_mov"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (blob.data == nullptr )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\nContents:\n");
|
||||||
|
|
||||||
|
u32 left = blob.size;
|
||||||
|
u8* data = cast(u8*)blob.data
|
||||||
|
// + blob.size - 1
|
||||||
|
;
|
||||||
|
|
||||||
|
char
|
||||||
|
binary_string[9];
|
||||||
|
binary_string[8] = '\0';
|
||||||
|
|
||||||
|
while ( left-- )
|
||||||
|
{
|
||||||
|
str_binary( binary_string, data[0]);
|
||||||
|
|
||||||
|
printf("%s\n", binary_string );
|
||||||
|
|
||||||
|
data += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
left = blob.size;
|
||||||
|
// data += blob.size;
|
||||||
|
data -= blob.size;
|
||||||
|
while ( left-- )
|
||||||
|
{
|
||||||
|
str_binary( binary_string, data[0]);
|
||||||
|
|
||||||
|
printf("%X", data[0] );
|
||||||
|
|
||||||
|
data += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instruction
|
||||||
|
instr;
|
||||||
|
instr.Byte_1 = ((u8*)blob.data)[0];
|
||||||
|
instr.Byte_2 = ((u8*)blob.data)[1];
|
||||||
|
instr.disassemble();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
zpl_printf("sim 8086!");
|
||||||
|
|
||||||
|
Tests::Init();
|
||||||
|
|
||||||
|
zpl_f64 start = zpl_time_rel();
|
||||||
|
|
||||||
|
Tests::Try_MockInstruction();
|
||||||
|
Tests::Try_Blob_SingleRegisterMove();
|
||||||
|
|
||||||
|
zpl_f64 end = zpl_time_rel();
|
||||||
|
|
||||||
|
printf("\n\nElapsed Time: %lf", end - start);
|
||||||
|
printf("\n\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
1
part_1/tests/listing_0037_single_register_mov
Normal file
1
part_1/tests/listing_0037_single_register_mov
Normal file
@ -0,0 +1 @@
|
|||||||
|
菓
|
1
part_1/tests/listing_0038_many_register_mov
Normal file
1
part_1/tests/listing_0038_many_register_mov
Normal file
@ -0,0 +1 @@
|
|||||||
|
‰Ùˆå‰Ú‰Þ‰ûˆÈˆí‰Ã‰ó‰ü‰Å
|
Loading…
Reference in New Issue
Block a user