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…
Reference in New Issue
Block a user