From 9be706b28dbb16b86a938968071d9b5d17c06f89 Mon Sep 17 00:00:00 2001 From: Ed_ Date: Sun, 5 Mar 2023 20:57:40 -0500 Subject: [PATCH] Finished the first hw. On to the second... --- .vscode/launch.json | 19 + .vscode/settings.json | 4 +- part_1/bloat.hpp | 111 ++++ part_1/build.bat | 12 + part_1/debug.rdbg | Bin 0 -> 373 bytes part_1/meson.build | 8 + part_1/sim_8086.cpp | 476 +++++++----------- part_1/test.bat | 8 - .../listing_0038_many_register_mov.out.asm | 13 + 9 files changed, 350 insertions(+), 301 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 part_1/bloat.hpp create mode 100644 part_1/debug.rdbg delete mode 100644 part_1/test.bat create mode 100644 part_1/tests/listing_0038_many_register_mov.out.asm diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..cd577a3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,19 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "(Windows) Launch", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceRoot}/part_1/build/sim_8086.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceRoot}/part_1", + "environment": [], + "console": "externalTerminal" + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 1e14b6f..a928b13 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,8 @@ { "files.associations": { "*.rmd": "markdown", - "zpl.h": "c" + "zpl.h": "c", + "cstddef": "cpp", + "xtr1common": "cpp" } } \ No newline at end of file diff --git a/part_1/bloat.hpp b/part_1/bloat.hpp new file mode 100644 index 0000000..f815fc3 --- /dev/null +++ b/part_1/bloat.hpp @@ -0,0 +1,111 @@ +#if __clang__ +# pragma clang diagnostic ignored "-Wunused-const-variable" +# pragma clang diagnostic ignored "-Wswitch" +# pragma clang diagnostic ignored "-Wunused-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 +// # define ZPL_HEAP_ANALYSIS +# define ZPL_NO_MATH_H +# define ZPL_CUSTOM_MODULES +# define ZPL_MODULE_ESSENTIALS +# define ZPL_MODULE_CORE +# define ZPL_MODULE_TIMER +// # define ZPL_MODULE_HASHING +// # define ZPL_MODULE_REGEX +// # define ZPL_MODULE_EVENT +// # define ZPL_MODULE_DLL +// # define ZPL_MODULE_OPTS +// # define ZPL_MODULE_PROCESS +// # define ZPL_MODULE_MATH +// # define ZPL_MODULE_THREADING +// # define ZPL_MODULE_JOBS +// # define ZPL_MODULE_PARSER +extern "C" { +#include "zpl.h" +} + +#if __clang__ +# pragma clang diagnostic pop +#endif + +#undef cast + +#pragma endregion ZPL INCLUDE + + + +#define bit( Value_ ) ( 1 << Value_ ) +#define bitfield_is_equal( Field_, Mask_ ) ( ( Mask_ & Field_ ) == Mask_ ) +#define cast( Type_ , Value_ ) ( ( Type_ )( Value_ ) ) +#define ct constexpr +#define gen( ... ) template< __VA_ARGS__ > +#define forceinline ZPL_ALWAYS_INLINE +#define print_nl( _) zpl_printf("\n") +#define Msg_Invalid_Value "INVALID VALUE PROVIDED" +#define scast static_cast +#define rcast reinterpret_cast + +using u8 = zpl_u8; +using u16 = zpl_u16; +using u32 = zpl_u32; +using uw = zpl_usize; +using sw = zpl_isize; + +ct inline +char char_binary( u8 value, u8 pos ) +{ + u8 mask = 1 << pos ; + + return ( (1 << 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 +} + +inline +void print_as_binary( u8* data, uw size, char const* byte_term ) +{ + char + binary_string[9]; + binary_string[8] = '\0'; + + while ( size-- ) + { + str_binary( binary_string, data[0]); + + printf( "%s%s", binary_string, byte_term ); + + data += 1; + } +} diff --git a/part_1/build.bat b/part_1/build.bat index 0f678dd..e8ac896 100644 --- a/part_1/build.bat +++ b/part_1/build.bat @@ -4,4 +4,16 @@ if not exist build\nul ( meson setup build ) +echo: +if not exist tests\listing_0037_single_register_mov ( + echo Assembling: listing_0037_single_register_mov.asm + call nasm ".\tests\listing_0037_single_register_mov.asm" +) + +if not exist tests\listing_0038_many_register_mov ( + echo Assembling: listing_0038_many_register_mov.asm + call nasm ".\tests\listing_0038_many_register_mov.asm" +) + +echo: ninja -C build \ No newline at end of file diff --git a/part_1/debug.rdbg b/part_1/debug.rdbg new file mode 100644 index 0000000000000000000000000000000000000000..f350baa1368daa82fa992d42351dbd0c738fa239 GIT binary patch literal 373 zcmWG?adOvZU|?{ziYX|{&q_@$DUK;fElNu)Pb^A}DM&0Ti8qW%D$UGEi7C#^jkhqc zFw;w|NCoO(kRhOr5h$-oKn=psAa!62(|}zWL=>!$1F8d`La-dnL;!*QK}i4r literal 0 HcmV?d00001 diff --git a/part_1/meson.build b/part_1/meson.build index 8189005..64320ea 100644 --- a/part_1/meson.build +++ b/part_1/meson.build @@ -2,4 +2,12 @@ project( 'sim_8086', 'c', 'cpp', default_options : ['buildtype=debug'] ) include_thirdparty = include_directories( '../thirdparty' ) +# add_global_arguments('-E', language : 'cpp') + +if get_option('buildtype').startswith('debug') + + add_project_arguments('-DBuild_Debug', language : 'cpp') + +endif + executable( 'sim_8086', 'sim_8086.cpp', include_directories : include_thirdparty ) diff --git a/part_1/sim_8086.cpp b/part_1/sim_8086.cpp index b24a689..213412e 100644 --- a/part_1/sim_8086.cpp +++ b/part_1/sim_8086.cpp @@ -1,149 +1,42 @@ -#if __clang__ -#pragma clang diagnostic ignored "-Wunused-const-variable" -#endif +#include "bloat.hpp" +zpl_arena BlobArena {}; +#define allocator zpl_arena_allocator( & BlobArena) -#pragma region ZPL INCLUDE +void setup() +{ + zpl_arena_init_from_allocator( & BlobArena, zpl_heap(), zpl_megabytes(10) ); -#if __clang__ - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wmissing-braces" - #pragma clang diagnostic ignored "-Wbraced-scalar-init" -#endif + if ( BlobArena.total_size == 0 ) + { + zpl_assert_crash( "Failed to reserve memory for Tests:: BLobArena" ); + } +} -#define ZPL_IMPLEMENTATION -#include "zpl.h" +void cleanup() +{ + zpl_arena_free( & BlobArena); +} -#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 +// Binary formatting for literals is used heavily as that its // 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 + enum Code : u8 { - #if USE_LOOKUP_TABLE - #define D_Entry( Entry_ ) Entry_, - D_Opcodes - #undef D_Entry - - #else + Mask = 0b11111100, mov_88 = 0b10001000, mov_89 = 0b11000100, - - #endif - - Num = 2 }; -#if USE_LOOKUP_TABLE - ct u8 code( Type type ) + char const* str( Code 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: @@ -152,11 +45,10 @@ namespace Op return "mov_89"; } - return MSG_INVALID_VALUE; - #endif + return Msg_Invalid_Value; } - ct char const* helper_meumonic( Type type ) + ct char const* helper_meumonic( Code type ) { switch ( type ) { @@ -165,23 +57,11 @@ namespace Op return "mov"; } - return MSG_INVALID_VALUE; + return Msg_Invalid_Value; } - char const* meumonic( Type type ) + char const* meumonic( Code 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: @@ -189,11 +69,10 @@ namespace Op return "mov"; } - return MSG_INVALID_VALUE; - #endif + return Msg_Invalid_Value; } - ct char const* helper_intuitive( Type type ) + ct char const* helper_intuitive( Code type ) { switch ( type ) { @@ -202,24 +81,11 @@ namespace Op return "move"; } - return MSG_INVALID_VALUE; + return Msg_Invalid_Value; } - char const* intuitive( Type type ) + char const* intuitive( Code 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: @@ -227,8 +93,7 @@ namespace Op return "move"; } - return MSG_INVALID_VALUE; - #endif + return Msg_Invalid_Value; } #undef D_Opcodes @@ -236,51 +101,46 @@ namespace Op 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 ) + // Effective Address offset + inline + u8 effective_address( u8 reg ) { return reg << 3; } // https://i.imgur.com/drsyYnM.png - ct u8 Dir_REG_Src = 0b00; - ct u8 Dir_REG_Dest = 0b10; + enum Direction : u8 + { + Mask_Dir = 0b00000010, + Dir_Src = 0b00, + Dir_Dest = 0b10, + }; inline - char const* str_direction( u8 direction ) + char const* str_direction( Direction direction ) { switch ( direction ) { - case Dir_REG_Dest: + case Dir_Dest: return "Destination"; - case Dir_REG_Src: + case Dir_Src: return "Source"; } - return MSG_INVALID_VALUE; + return Msg_Invalid_Value; } // https://i.imgur.com/9Op8Lnd.png - ct u8 Width_Byte = 0b00; - ct u8 Width_Word = 0b01; + enum Width : u8 + { + Mask_Width = 0b00000001, + Width_Byte = 0b00, + Width_Word = 0b01, + }; inline - char const* str_width( u8 width ) + char const* str_width( Width width ) { switch ( width ) { @@ -291,16 +151,20 @@ namespace Field return "Word"; } - return MSG_INVALID_VALUE; + 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; + enum Mode : u8 + { + Mask_Mode = 0b11000000, + Mode_Mem = 0b00000000, + Mode_Mem8 = 0b01000000, + Mode_Mem16 = 0b10000000, + Mode_Reg = 0b11000000, + }; - char const* str_mode( u8 mode ) + char const* str_mode( Mode mode ) { switch (mode) { @@ -317,7 +181,7 @@ namespace Field return "Register"; } - return MSG_INVALID_VALUE; + return Msg_Invalid_Value; } #if 0 @@ -352,10 +216,8 @@ namespace Register D_Entry( SI ) \ D_Entry( DI ) \ - using Type = u8; - enum + enum Type : u8 { - // Endianness is prob wrong... AL = 0b000, CL = 0b001, DL = 0b010, @@ -415,7 +277,7 @@ namespace Register "Destination.Index", }; - return Type_To_Intuitive[ type + 8 * Width ]; + return Type_To_Intuitive[ type + Width * 7 + 1 ]; } } @@ -434,69 +296,75 @@ struct POD_Instruction struct Instruction : public POD_Instruction { + using Code = Op::Code; + using Direction = Field::Direction; + using Mode = Field::Mode; + using Width = Field::Width; + using Reg = Register::Type; + inline - u8 direction() + Direction direction() { - u8 direction = Byte_1 & Field::Mask_Dir; + Direction + direction = cast(Direction, Byte_1 & Field::Mask_Dir); return direction; } inline - u8 mode() + Mode mode() { - u8 mode = Byte_2 & Field::Mask_Mode; + Mode mode = cast( Mode, Byte_2 & Field::Mask_Mode ); return mode; } inline - u8 opcode() + Code opcode() { - u8 - opcode = Byte_1 & Op::Mask; + Op::Code + opcode = cast( Op::Code, Byte_1 & Op::Mask ); return opcode; } inline - u8 operand_left() + Reg operand_left() { u8 operand = Byte_2 & Register::Mask_Left; operand >>= 3; - return operand; + return cast(Reg, operand); } inline - u8 operand_right() + Reg operand_right() { - u8 - operand = Byte_2 & Register::Mask_Right; - // operand <<= 1; + u8 operand = Byte_2 & Register::Mask_Right; - return operand; + return cast( Reg, operand ); } inline - u8 width() + Width width() { - u8 width = Byte_1 & Field::Mask_Width; + Width width = cast( Width, Byte_1 & Field::Mask_Width ); return width; } - void disassemble() + void dissassemble( zpl_string* result_out ) { using namespace Field; using namespace Op; using namespace Register; - u8 width_val = width(); + Direction dir = direction(); + Width width_val = width(); char const* opcode_str = Op::meumonic( opcode() ); - char const* direction_str = Field::str_direction( direction() ); + char const* direction_str = Field::str_direction( dir ); 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 ); @@ -506,10 +374,11 @@ struct Instruction : public POD_Instruction binary_string[9]; binary_string[8] = '\0'; + #if Build_Debug str_binary( binary_string, opcode() ); zpl_printf("\nOpcode : %s : %s", binary_string, opcode_str); - str_binary( binary_string, direction() ); + str_binary( binary_string, dir ); zpl_printf("\nDirection : %s : %s", binary_string, direction_str); str_binary( binary_string, width_val ); @@ -523,107 +392,124 @@ struct Instruction : public POD_Instruction str_binary( binary_string, operand_right() ); zpl_printf("\nOperand EA : %s : %s", binary_string, operand_right_str); + #endif + + if ( result_out == nullptr ) + return; + + if ( * result_out == nullptr ) + * result_out = zpl_string_make_reserve( allocator, zpl_kilobytes(1) ); + + zpl_string assembly = zpl_string_make_reserve( allocator, 32); + + assembly = zpl_string_sprintf( allocator, assembly, zpl_kilobytes(1) - 1, "\n%s %s, %s" + , opcode_str + , dir == Dir_Src ? operand_right_str : operand_left_str + , dir == Dir_Src ? operand_left_str : operand_right_str + ); + + * result_out = zpl_string_append( * result_out, assembly ); + + #if Build_Debug + zpl_printf("\n\nAssembly: %s\n\n", assembly); + #endif } }; 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() + void try_mock_instruction() { 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; + mock; // mov CX, BX + mock.Byte_1 = mov_88 | Dir_Src | Field::Width_Word; + mock.Byte_2 = Field::Mode_Reg | effective_address(BX) | CX; zpl_printf("\n\nAttempting Mock Instruction: mov CX, BX"); - char - binary_string[9]; - binary_string[8] = '\0'; + print_nl(); + print_as_binary( & mock.Byte_1, 1, " " ); + print_as_binary( & mock.Byte_2, 1, " " ); + print_nl(); - 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(); + zpl_string dissasembly = nullptr; + + mock.dissassemble( & dissasembly); } - void Try_Blob_SingleRegisterMove() + void try_blob_single_instruction() { 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" - ); + blob = zpl_file_read_contents( allocator, false, "tests/listing_0037_single_register_mov" ); if (blob.data == nullptr ) - { return; - } - - printf("\nContents:\n"); u32 left = blob.size; - u8* data = cast(u8*)blob.data - // + blob.size - 1 - ; + u8* data = cast( u8*, blob.data ); - char - binary_string[9]; - binary_string[8] = '\0'; + print_nl(); + print_as_binary( data, left, " " ); + print_nl(); - 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; - } + zpl_string dissasembly = nullptr; Instruction instr; - instr.Byte_1 = ((u8*)blob.data)[0]; - instr.Byte_2 = ((u8*)blob.data)[1]; - instr.disassemble(); + instr.Byte_1 = data[0]; + instr.Byte_2 = data[1]; + instr.dissassemble( & dissasembly); } + + void try_blob_many_instructions() + { + zpl_printf("\n\nAttempting to read blob: listing_0038_many_register_mov"); + + zpl_file_contents + blob = zpl_file_read_contents( allocator, false, "tests/listing_0038_many_register_mov" ); + + if (blob.data == nullptr ) + return; + + u32 left = blob.size; + u8* data = cast( u8*, blob.data ); + + print_nl(); + print_as_binary( data, left, " " ); + print_nl(); + + zpl_string dissasembly = zpl_string_make( allocator, "bits 16\n"); + + while ( left ) + { + Instruction + instr; + instr.Byte_1 = data[0]; + instr.Byte_2 = data[1]; + instr.dissassemble( & dissasembly); + + data += 2; + left -= 2; + } + + zpl_printf("\n\nDissassemlby:\n%s", dissasembly); + dissasembly = zpl_string_append_fmt( dissasembly, "\n" ); + + zpl_printf("\n\nSaving to file"); + zpl_file_write_contents("tests/listing_0038_many_register_mov.out.asm" + , dissasembly + , zpl_string_length(dissasembly) + , nullptr + ); + } + + #undef allocator } @@ -631,17 +517,23 @@ int main() { zpl_printf("sim 8086!"); - Tests::Init(); + setup(); zpl_f64 start = zpl_time_rel(); - Tests::Try_MockInstruction(); - Tests::Try_Blob_SingleRegisterMove(); +#if 0 + Tests::try_mock_instruction(); + Tests::try_blob_single_instruction(); +#endif + Tests::try_blob_many_instructions(); zpl_f64 end = zpl_time_rel(); + zpl_f64 ms = (end - start) * 100; - printf("\n\nElapsed Time: %lf", end - start); + printf("\n\nElapsed Time: %lf ms", ms); printf("\n\n"); + cleanup(); + return 0; } diff --git a/part_1/test.bat b/part_1/test.bat deleted file mode 100644 index ca987aa..0000000 --- a/part_1/test.bat +++ /dev/null @@ -1,8 +0,0 @@ -@echo off - -echo Assembling: listing_0037_single_register_mov.asm -call nasm ".\tests\listing_0037_single_register_mov.asm" - - -echo Assembling: listing_0038_many_register_mov.asm -call nasm ".\tests\listing_0038_many_register_mov.asm" \ No newline at end of file diff --git a/part_1/tests/listing_0038_many_register_mov.out.asm b/part_1/tests/listing_0038_many_register_mov.out.asm new file mode 100644 index 0000000..e017295 --- /dev/null +++ b/part_1/tests/listing_0038_many_register_mov.out.asm @@ -0,0 +1,13 @@ +bits 16 + +mov CX, BX +mov DH, CH +mov DX, BX +mov SI, BX +mov BX, DI +mov CL, DL +mov DH, DH +mov BX, AX +mov BX, SI +mov SP, DI +mov BP, AX