perfaware/part1: Support listing 0045
This commit is contained in:
		
							parent
							
								
									3d29edbfc8
								
							
						
					
					
						commit
						67307e81b8
					
				| @ -70,3 +70,10 @@ copy /Y %script_dir%\%listing_0044%.txt %build_dir% 1>NUL | |||||||
| set build_dir_listing_0044=%build_dir%\%listing_0044% | set build_dir_listing_0044=%build_dir%\%listing_0044% | ||||||
| %build_dir%\sim8086.exe --exec %build_dir_listing_0044% > %build_dir_listing_0044%_disassembled.txt | %build_dir%\sim8086.exe --exec %build_dir_listing_0044% > %build_dir_listing_0044%_disassembled.txt | ||||||
| fc /N %build_dir_listing_0044%.txt %build_dir_listing_0044%_disassembled.txt || exit /b 1 | fc /N %build_dir_listing_0044%.txt %build_dir_listing_0044%_disassembled.txt || exit /b 1 | ||||||
|  | 
 | ||||||
|  | set listing_0045=listing_0045_challenge_register_movs | ||||||
|  | copy /Y %script_dir%\%listing_0045% %build_dir% 1>NUL | ||||||
|  | copy /Y %script_dir%\%listing_0045%.txt %build_dir% 1>NUL | ||||||
|  | set build_dir_listing_0045=%build_dir%\%listing_0045% | ||||||
|  | %build_dir%\sim8086.exe --exec %build_dir_listing_0045% > %build_dir_listing_0045%_disassembled.txt | ||||||
|  | fc /N %build_dir_listing_0045%.txt %build_dir_listing_0045%_disassembled.txt || exit /b 1 | ||||||
|  | |||||||
							
								
								
									
										1
									
								
								part1/listing_0045_challenge_register_movs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								part1/listing_0045_challenge_register_movs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | |||||||
|  | ク""サDDケffコ<66>社杓蔀ーキ3アUカw緯鰯社杓蔀菰互姑荷 | ||||||
							
								
								
									
										43
									
								
								part1/listing_0045_challenge_register_movs.asm
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								part1/listing_0045_challenge_register_movs.asm
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | ; ======================================================================== | ||||||
|  | ; | ||||||
|  | ; (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 45 | ||||||
|  | ; ======================================================================== | ||||||
|  | 
 | ||||||
|  | bits 16 | ||||||
|  | 
 | ||||||
|  | mov ax, 0x2222 | ||||||
|  | mov bx, 0x4444 | ||||||
|  | mov cx, 0x6666 | ||||||
|  | mov dx, 0x8888 | ||||||
|  | 
 | ||||||
|  | mov ss, ax | ||||||
|  | mov ds, bx | ||||||
|  | mov es, cx | ||||||
|  | 
 | ||||||
|  | mov al, 0x11 | ||||||
|  | mov bh, 0x33 | ||||||
|  | mov cl, 0x55 | ||||||
|  | mov dh, 0x77 | ||||||
|  | 
 | ||||||
|  | mov ah, bl | ||||||
|  | mov cl, dh | ||||||
|  | 
 | ||||||
|  | mov ss, ax | ||||||
|  | mov ds, bx | ||||||
|  | mov es, cx | ||||||
|  | 
 | ||||||
|  | mov sp, ss | ||||||
|  | mov bp, ds | ||||||
|  | mov si, es | ||||||
|  | mov di, dx | ||||||
							
								
								
									
										35
									
								
								part1/listing_0045_challenge_register_movs.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								part1/listing_0045_challenge_register_movs.txt
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | --- test\listing_0045_challenge_register_movs execution --- | ||||||
|  | mov ax, 8738 ; ax:0x0->0x2222  | ||||||
|  | mov bx, 17476 ; bx:0x0->0x4444  | ||||||
|  | mov cx, 26214 ; cx:0x0->0x6666  | ||||||
|  | mov dx, 34952 ; dx:0x0->0x8888  | ||||||
|  | mov ss, ax ; ss:0x0->0x2222  | ||||||
|  | mov ds, bx ; ds:0x0->0x4444  | ||||||
|  | mov es, cx ; es:0x0->0x6666  | ||||||
|  | mov al, 17 ; ax:0x2222->0x2211  | ||||||
|  | mov bh, 51 ; bx:0x4444->0x3344  | ||||||
|  | mov cl, 85 ; cx:0x6666->0x6655  | ||||||
|  | mov dh, 119 ; dx:0x8888->0x7788  | ||||||
|  | mov ah, bl ; ax:0x2211->0x4411  | ||||||
|  | mov cl, dh ; cx:0x6655->0x6677  | ||||||
|  | mov ss, ax ; ss:0x2222->0x4411  | ||||||
|  | mov ds, bx ; ds:0x4444->0x3344  | ||||||
|  | mov es, cx ; es:0x6666->0x6677  | ||||||
|  | mov sp, ss ; sp:0x0->0x4411  | ||||||
|  | mov bp, ds ; bp:0x0->0x3344  | ||||||
|  | mov si, es ; si:0x0->0x6677  | ||||||
|  | mov di, dx ; di:0x0->0x7788  | ||||||
|  | 
 | ||||||
|  | Final registers: | ||||||
|  |       ax: 0x4411 (17425) | ||||||
|  |       bx: 0x3344 (13124) | ||||||
|  |       cx: 0x6677 (26231) | ||||||
|  |       dx: 0x7788 (30600) | ||||||
|  |       sp: 0x4411 (17425) | ||||||
|  |       bp: 0x3344 (13124) | ||||||
|  |       si: 0x6677 (26231) | ||||||
|  |       di: 0x7788 (30600) | ||||||
|  |       es: 0x6677 (26231) | ||||||
|  |       ss: 0x4411 (17425) | ||||||
|  |       ds: 0x3344 (13124) | ||||||
|  | 
 | ||||||
							
								
								
									
										184
									
								
								part1/sim8086.c
									
									
									
									
									
								
							
							
						
						
									
										184
									
								
								part1/sim8086.c
									
									
									
									
									
								
							| @ -8,10 +8,16 @@ typedef struct RegisterFile { | |||||||
|     uint16_t cx; |     uint16_t cx; | ||||||
|     uint16_t dx; |     uint16_t dx; | ||||||
|     uint16_t bx; |     uint16_t bx; | ||||||
|  | 
 | ||||||
|     uint16_t sp; |     uint16_t sp; | ||||||
|     uint16_t bp; |     uint16_t bp; | ||||||
|     uint16_t si; |     uint16_t si; | ||||||
|     uint16_t di; |     uint16_t di; | ||||||
|  | 
 | ||||||
|  |     uint16_t es; | ||||||
|  |     uint16_t cs; | ||||||
|  |     uint16_t ss; | ||||||
|  |     uint16_t ds; | ||||||
| } RegisterFile; | } RegisterFile; | ||||||
| 
 | 
 | ||||||
| S86_Str8 S86_MnemonicStr8(S86_Mnemonic type) | S86_Str8 S86_MnemonicStr8(S86_Mnemonic type) | ||||||
| @ -470,49 +476,64 @@ S86_Opcode S86_DecodeOpcode(S86_BufferIterator *buffer_it, | |||||||
|         case S86_OpDecodeType_LES:                        /*FALLTHRU*/ |         case S86_OpDecodeType_LES:                        /*FALLTHRU*/ | ||||||
|         case S86_OpDecodeType_XCHGRegOrMemWithReg:        /*FALLTHRU*/ |         case S86_OpDecodeType_XCHGRegOrMemWithReg:        /*FALLTHRU*/ | ||||||
|         case S86_OpDecodeType_CMPRegOrMemAndReg:          /*FALLTHRU*/ |         case S86_OpDecodeType_CMPRegOrMemAndReg:          /*FALLTHRU*/ | ||||||
|         case S86_OpDecodeType_MOVRegOrMemToOrFromReg: { |         case S86_OpDecodeType_MOVRegOrMemToOrFromReg:     /*FALLTHRU*/ | ||||||
|  |         case S86_OpDecodeType_MOVSegRegToRegOrMem:        /*FALLTHRU*/ | ||||||
|  |         case S86_OpDecodeType_MOVRegOrMemToSegReg: { | ||||||
|             // NOTE: Instruction does not have opcode bits in the 2nd byte
 |             // NOTE: Instruction does not have opcode bits in the 2nd byte
 | ||||||
|             S86_ASSERT(op_code_size == 1); |             if (op_decode_type == S86_OpDecodeType_MOVSegRegToRegOrMem || | ||||||
|             op_code_bytes[op_code_size++] = S86_BufferIteratorNextByte(buffer_it); |                 op_decode_type == S86_OpDecodeType_MOVRegOrMemToSegReg) { | ||||||
| 
 |                 S86_ASSERT(op_code_size == 2); | ||||||
|             uint8_t w = (op_code_bytes[0] & 0b0000'0001) >> 0; |             } else { | ||||||
|             uint8_t d = (op_code_bytes[0] & 0b0000'0010) >> 1; |                 S86_ASSERT(op_code_size == 1); | ||||||
|             if (op_decode_type == S86_OpDecodeType_XCHGRegOrMemWithReg || |                 op_code_bytes[op_code_size++] = S86_BufferIteratorNextByte(buffer_it); | ||||||
|                 op_decode_type == S86_OpDecodeType_LEA || |  | ||||||
|                 op_decode_type == S86_OpDecodeType_LDS || |  | ||||||
|                 op_decode_type == S86_OpDecodeType_LES) { |  | ||||||
|                 d = 1; // Destintation is always the register
 |  | ||||||
|                 if (op_decode_type == S86_OpDecodeType_XCHGRegOrMemWithReg) { |  | ||||||
|                     if (*lock_prefix) { |  | ||||||
|                         // NOTE: When we XCHG, NASM complains that the
 |  | ||||||
|                         // instruction is not lockable, unless, the memory
 |  | ||||||
|                         // operand comes first. Here we flip the direction
 |  | ||||||
|                         // to ensure the memory operand is the destination.
 |  | ||||||
|                         //
 |  | ||||||
|                         // listing_0042_completionist_decode_disassembled.asm|319| warning: instruction is not lockable [-w+prefix-lock]
 |  | ||||||
|                         d = 0; |  | ||||||
|                     } |  | ||||||
|                 } else { |  | ||||||
|                     w = 1; // Always 16 bit (load into register)
 |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|  |             uint8_t d   = 0; | ||||||
|             uint8_t mod = (op_code_bytes[1] & 0b1100'0000) >> 6; |             uint8_t mod = (op_code_bytes[1] & 0b1100'0000) >> 6; | ||||||
|             uint8_t reg = (op_code_bytes[1] & 0b0011'1000) >> 3; |  | ||||||
|             uint8_t rm  = (op_code_bytes[1] & 0b0000'0111) >> 0; |             uint8_t rm  = (op_code_bytes[1] & 0b0000'0111) >> 0; | ||||||
|             S86_ASSERT(d   < 2); |  | ||||||
|             S86_ASSERT(w   < 2); |  | ||||||
|             S86_ASSERT(mod < 4); |             S86_ASSERT(mod < 4); | ||||||
|             S86_ASSERT(reg < 8); |  | ||||||
|             S86_ASSERT(rm  < 8); |             S86_ASSERT(rm  < 8); | ||||||
| 
 | 
 | ||||||
|             result.wide = w; |             if (op_decode_type == S86_OpDecodeType_MOVRegOrMemToSegReg || | ||||||
|             result.src  = S86_MnemonicOpFromWReg(result.wide, reg); |                 op_decode_type == S86_OpDecodeType_MOVSegRegToRegOrMem) { | ||||||
|  |                 uint8_t sr  = (op_code_bytes[1] & 0b0001'1000) >> 3; | ||||||
|  |                 result.src  = S86_MnemonicOpFromSR(sr); | ||||||
|  |                 result.wide = 1; | ||||||
|  |                 if (op_decode_type == S86_OpDecodeType_MOVRegOrMemToSegReg) | ||||||
|  |                     d = 1; | ||||||
|  |             } else { | ||||||
|  |                 result.wide = (op_code_bytes[0] & 0b0000'0001) >> 0; | ||||||
|  |                 d = (op_code_bytes[0] & 0b0000'0010) >> 1; | ||||||
|  |                 if (op_decode_type == S86_OpDecodeType_XCHGRegOrMemWithReg || | ||||||
|  |                     op_decode_type == S86_OpDecodeType_LEA || | ||||||
|  |                     op_decode_type == S86_OpDecodeType_LDS || | ||||||
|  |                     op_decode_type == S86_OpDecodeType_LES) { | ||||||
|  |                     d = 1; // Destintation is always the register
 | ||||||
|  |                     if (op_decode_type == S86_OpDecodeType_XCHGRegOrMemWithReg) { | ||||||
|  |                         if (*lock_prefix) { | ||||||
|  |                             // NOTE: When we XCHG, NASM complains that the
 | ||||||
|  |                             // instruction is not lockable, unless, the memory
 | ||||||
|  |                             // operand comes first. Here we flip the direction
 | ||||||
|  |                             // to ensure the memory operand is the destination.
 | ||||||
|  |                             //
 | ||||||
|  |                             // listing_0042_completionist_decode_disassembled.asm|319| warning: instruction is not lockable [-w+prefix-lock]
 | ||||||
|  |                             d = 0; | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         result.wide = 1; // Always 16 bit (load into register)
 | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|  |                 uint8_t reg = (op_code_bytes[1] & 0b0011'1000) >> 3; | ||||||
|  |                 result.src  = S86_MnemonicOpFromWReg(result.wide, reg); | ||||||
|  |             } | ||||||
|  |             S86_ASSERT(result.wide < 2); | ||||||
|  |             S86_ASSERT(d < 2); | ||||||
|  | 
 | ||||||
|             if (mod == 0b11) { // NOTE: Register-to-register move
 |             if (mod == 0b11) { // NOTE: Register-to-register move
 | ||||||
|                 result.dest = S86_MnemonicOpFromWReg(result.wide, rm); |                 result.dest = S86_MnemonicOpFromWReg(result.wide, rm); | ||||||
|             } else { // NOTE: Memory mode w/ effective address calculation
 |             } else { // NOTE: Memory mode w/ effective address calculation
 | ||||||
|                 S86_DecodeEffectiveAddr(&result, buffer_it, rm, mod, w); |                 S86_DecodeEffectiveAddr(&result, buffer_it, rm, mod, result.wide); | ||||||
|                 result.src = S86_MnemonicOpFromWReg(w, reg); |  | ||||||
|                 if (d) |                 if (d) | ||||||
|                     result.effective_addr = S86_EffectiveAddress_Src; |                     result.effective_addr = S86_EffectiveAddress_Src; | ||||||
|                 else |                 else | ||||||
| @ -775,6 +796,15 @@ S86_Opcode S86_DecodeOpcode(S86_BufferIterator *buffer_it, | |||||||
|     return result; |     return result; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | typedef struct S86_MnemonicOpToRegisterFileMap { | ||||||
|  |     S86_MnemonicOp mnemonic_op;       ///< Register/op that the mnemonic is using
 | ||||||
|  |     S86_MnemonicOp mnemonic_op_reg16; ///< 16 bit register for the mnemonic op
 | ||||||
|  |     uint16_t       mask;              ///< Mask for the bits that the mnemonic op is using (hi/lo/full bit coverage)
 | ||||||
|  |     uint16_t       r_shift;           ///< Shift amount for isolating the masked value
 | ||||||
|  |     uint16_t       *reg;              ///< Pointer to the register memory this mnemonic op is using
 | ||||||
|  | } S86_MnemonicOpToRegisterFileMap; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| #define PRINT_USAGE S86_PrintLn(S86_STR8("usage: sim8086.exe [--exec] <binary asm file>")) | #define PRINT_USAGE S86_PrintLn(S86_STR8("usage: sim8086.exe [--exec] <binary asm file>")) | ||||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||||
| { | { | ||||||
| @ -1118,34 +1148,32 @@ int main(int argc, char **argv) | |||||||
|     S86_MnemonicOp seg_reg       = {0}; |     S86_MnemonicOp seg_reg       = {0}; | ||||||
|     bool lock_prefix             = false; |     bool lock_prefix             = false; | ||||||
| 
 | 
 | ||||||
|     typedef struct MnemonicOpToRegisterFileMap { |     S86_MnemonicOpToRegisterFileMap mnemonic_op_to_register_file_map[] = { | ||||||
|         S86_MnemonicOp mnemonic_op; |         {.mnemonic_op = S86_MnemonicOp_AX, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.ax, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|         uint16_t       mask; |         {.mnemonic_op = S86_MnemonicOp_AL, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.ax, .mask = 0x00FF, .r_shift = 0}, | ||||||
|         uint16_t       r_shift; |         {.mnemonic_op = S86_MnemonicOp_AH, .mnemonic_op_reg16 = S86_MnemonicOp_AX, .reg = ®ister_file.ax, .mask = 0xFF00, .r_shift = 8}, | ||||||
|         uint16_t       *reg; |  | ||||||
|     } MnemonicOpToRegisterFileMap; |  | ||||||
| 
 | 
 | ||||||
|     MnemonicOpToRegisterFileMap mnemonic_op_to_register_file_map[] = { |         {.mnemonic_op = S86_MnemonicOp_CX, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = ®ister_file.cx, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_AX, .reg = ®ister_file.ax, .mask = 0xFFFF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_CL, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = ®ister_file.cx, .mask = 0x00FF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_AL, .reg = ®ister_file.ax, .mask = 0x00FF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_CH, .mnemonic_op_reg16 = S86_MnemonicOp_CX, .reg = ®ister_file.cx, .mask = 0xFF00, .r_shift = 8}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_AH, .reg = ®ister_file.ax, .mask = 0xFF00, .r_shift = 8}, |  | ||||||
| 
 | 
 | ||||||
|         {.mnemonic_op = S86_MnemonicOp_CX, .reg = ®ister_file.cx, .mask = 0xFFFF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_DX, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_file.dx, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_CL, .reg = ®ister_file.cx, .mask = 0x00FF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_DL, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_file.dx, .mask = 0x00FF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_CH, .reg = ®ister_file.cx, .mask = 0xFF00, .r_shift = 8}, |         {.mnemonic_op = S86_MnemonicOp_DH, .mnemonic_op_reg16 = S86_MnemonicOp_DX, .reg = ®ister_file.dx, .mask = 0xFF00, .r_shift = 8}, | ||||||
| 
 | 
 | ||||||
|         {.mnemonic_op = S86_MnemonicOp_DX, .reg = ®ister_file.dx, .mask = 0xFFFF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_BX, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_file.bx, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_DL, .reg = ®ister_file.dx, .mask = 0x00FF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_BL, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_file.bx, .mask = 0x00FF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_DH, .reg = ®ister_file.dx, .mask = 0xFF00, .r_shift = 8}, |         {.mnemonic_op = S86_MnemonicOp_BH, .mnemonic_op_reg16 = S86_MnemonicOp_BX, .reg = ®ister_file.bx, .mask = 0xFF00, .r_shift = 8}, | ||||||
| 
 | 
 | ||||||
|         {.mnemonic_op = S86_MnemonicOp_BX, .reg = ®ister_file.bx, .mask = 0xFFFF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_SP, .mnemonic_op_reg16 = S86_MnemonicOp_SP, .reg = ®ister_file.sp, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_BL, .reg = ®ister_file.bx, .mask = 0x00FF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_BP, .mnemonic_op_reg16 = S86_MnemonicOp_BP, .reg = ®ister_file.bp, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_BH, .reg = ®ister_file.bx, .mask = 0xFF00, .r_shift = 8}, |         {.mnemonic_op = S86_MnemonicOp_SI, .mnemonic_op_reg16 = S86_MnemonicOp_SI, .reg = ®ister_file.si, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|  |         {.mnemonic_op = S86_MnemonicOp_DI, .mnemonic_op_reg16 = S86_MnemonicOp_DI, .reg = ®ister_file.di, .mask = 0xFFFF, .r_shift = 0}, | ||||||
| 
 | 
 | ||||||
|         {.mnemonic_op = S86_MnemonicOp_SP, .reg = ®ister_file.sp, .mask = 0xFFFF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_ES, .mnemonic_op_reg16 = S86_MnemonicOp_ES, .reg = ®ister_file.es, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_BP, .reg = ®ister_file.bp, .mask = 0xFFFF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_CS, .mnemonic_op_reg16 = S86_MnemonicOp_CS, .reg = ®ister_file.cs, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_SI, .reg = ®ister_file.si, .mask = 0xFFFF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_SS, .mnemonic_op_reg16 = S86_MnemonicOp_SS, .reg = ®ister_file.ss, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|         {.mnemonic_op = S86_MnemonicOp_DI, .reg = ®ister_file.di, .mask = 0xFFFF, .r_shift = 0}, |         {.mnemonic_op = S86_MnemonicOp_DS, .mnemonic_op_reg16 = S86_MnemonicOp_DS, .reg = ®ister_file.ds, .mask = 0xFFFF, .r_shift = 0}, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     while (S86_BufferIteratorHasMoreBytes(buffer_it)) { |     while (S86_BufferIteratorHasMoreBytes(buffer_it)) { | ||||||
| @ -1159,33 +1187,35 @@ int main(int argc, char **argv) | |||||||
|             continue; |             continue; | ||||||
| 
 | 
 | ||||||
|         if (exec_mode && opcode.mnemonic == S86_Mnemonic_MOV) { |         if (exec_mode && opcode.mnemonic == S86_Mnemonic_MOV) { | ||||||
|             MnemonicOpToRegisterFileMap const *dest_map = NULL; |             S86_MnemonicOpToRegisterFileMap const *dest_map = NULL; | ||||||
|             for (size_t index = 0; !dest_map && index < S86_ARRAY_UCOUNT(mnemonic_op_to_register_file_map); index++) { |             for (size_t index = 0; !dest_map && index < S86_ARRAY_UCOUNT(mnemonic_op_to_register_file_map); index++) { | ||||||
|                 MnemonicOpToRegisterFileMap const *item = mnemonic_op_to_register_file_map + index; |                 S86_MnemonicOpToRegisterFileMap const *item = mnemonic_op_to_register_file_map + index; | ||||||
|                 if (item->mnemonic_op == opcode.dest) |                 if (item->mnemonic_op == opcode.dest) | ||||||
|                     dest_map = item; |                     dest_map = item; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             if (dest_map) { |             S86_ASSERT(dest_map); | ||||||
|                 uint16_t *dest = dest_map->reg; |             uint16_t *dest      = dest_map->reg; | ||||||
|                 if (opcode.src == S86_MnemonicOp_Immediate) { |             uint16_t src        = 0; | ||||||
|                     S86_Str8 mnemonic_op = S86_MnemonicOpStr8(dest_map->mnemonic_op); |  | ||||||
|                     S86_PrintFmt(" ; %.*s:0x%x->0x%x ", S86_STR8_FMT(mnemonic_op), *dest, opcode.immediate); |  | ||||||
|                     *dest = (uint16_t)opcode.immediate; |  | ||||||
|                 } else if (opcode.src >= S86_MnemonicOp_AX && opcode.src <= S86_MnemonicOp_DI) { |  | ||||||
|                     MnemonicOpToRegisterFileMap const *src_map = NULL; |  | ||||||
|                     for (size_t index = 0; !src_map && index < S86_ARRAY_UCOUNT(mnemonic_op_to_register_file_map); index++) { |  | ||||||
|                         MnemonicOpToRegisterFileMap const *item = mnemonic_op_to_register_file_map + index; |  | ||||||
|                         if (item->mnemonic_op == opcode.src) |  | ||||||
|                             src_map = item; |  | ||||||
|                     } |  | ||||||
| 
 | 
 | ||||||
|                     S86_Str8 dest_op = S86_MnemonicOpStr8(dest_map->mnemonic_op); |             if (opcode.src == S86_MnemonicOp_Immediate) { | ||||||
|                     uint16_t *src    = src_map->reg; |                 src = (uint16_t)opcode.immediate; | ||||||
|                     S86_PrintFmt(" ; %.*s:0x%x->0x%x ", S86_STR8_FMT(dest_op), *dest, *src); |             } else if ((opcode.src >= S86_MnemonicOp_AL && opcode.src <= S86_MnemonicOp_DI) || | ||||||
|                     *dest = *src; |                        (opcode.src >= S86_MnemonicOp_ES && opcode.src <= S86_MnemonicOp_DS)) { | ||||||
|  |                 S86_MnemonicOpToRegisterFileMap const *src_map = NULL; | ||||||
|  |                 for (size_t index = 0; !src_map && index < S86_ARRAY_UCOUNT(mnemonic_op_to_register_file_map); index++) { | ||||||
|  |                     S86_MnemonicOpToRegisterFileMap const *item = mnemonic_op_to_register_file_map + index; | ||||||
|  |                     if (item->mnemonic_op == opcode.src) | ||||||
|  |                         src_map = item; | ||||||
|                 } |                 } | ||||||
|  | 
 | ||||||
|  |                 src = (*src_map->reg & src_map->mask) >> src_map->r_shift; | ||||||
|             } |             } | ||||||
|  | 
 | ||||||
|  |             S86_Str8 dest_reg16 = S86_MnemonicOpStr8(dest_map->mnemonic_op_reg16); | ||||||
|  |             uint16_t new_dest   = (*dest & ~dest_map->mask) | (src << dest_map->r_shift); | ||||||
|  |             S86_PrintFmt(" ; %.*s:0x%x->0x%x ", S86_STR8_FMT(dest_reg16), *dest, new_dest); | ||||||
|  |             *dest = new_dest; | ||||||
|         } |         } | ||||||
|         S86_Print(S86_STR8("\n")); |         S86_Print(S86_STR8("\n")); | ||||||
|     } |     } | ||||||
| @ -1200,6 +1230,12 @@ int main(int argc, char **argv) | |||||||
|         S86_PrintLnFmt("      bp: 0x%04x (%u)", register_file.bp, register_file.bp); |         S86_PrintLnFmt("      bp: 0x%04x (%u)", register_file.bp, register_file.bp); | ||||||
|         S86_PrintLnFmt("      si: 0x%04x (%u)", register_file.si, register_file.si); |         S86_PrintLnFmt("      si: 0x%04x (%u)", register_file.si, register_file.si); | ||||||
|         S86_PrintLnFmt("      di: 0x%04x (%u)", register_file.di, register_file.di); |         S86_PrintLnFmt("      di: 0x%04x (%u)", register_file.di, register_file.di); | ||||||
|  |         if (register_file.es) | ||||||
|  |             S86_PrintLnFmt("      es: 0x%04x (%u)", register_file.es, register_file.es); | ||||||
|  |         if (register_file.ss) | ||||||
|  |             S86_PrintLnFmt("      ss: 0x%04x (%u)", register_file.ss, register_file.ss); | ||||||
|  |         if (register_file.ds) | ||||||
|  |             S86_PrintLnFmt("      ds: 0x%04x (%u)", register_file.ds, register_file.ds); | ||||||
|         S86_Print(S86_STR8("\n")); |         S86_Print(S86_STR8("\n")); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										
											BIN
										
									
								
								project.rdbg
									
									
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								project.rdbg
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user