perfaware/part1: Support listing 0043
This commit is contained in:
parent
7378c4349f
commit
36ef7ff7e2
@ -13,6 +13,8 @@ copy /Y %script_dir%\listing_0039_more_movs %build_dir% 1>NUL
|
|||||||
copy /Y %script_dir%\listing_0040_challenge_movs %build_dir% 1>NUL
|
copy /Y %script_dir%\listing_0040_challenge_movs %build_dir% 1>NUL
|
||||||
copy /Y %script_dir%\listing_0041_add_sub_cmp_jnz %build_dir% 1>NUL
|
copy /Y %script_dir%\listing_0041_add_sub_cmp_jnz %build_dir% 1>NUL
|
||||||
copy /Y %script_dir%\listing_0042_completionist_decode %build_dir% 1>NUL
|
copy /Y %script_dir%\listing_0042_completionist_decode %build_dir% 1>NUL
|
||||||
|
copy /Y %script_dir%\listing_0043_immediate_movs %build_dir% 1>NUL
|
||||||
|
copy /Y %script_dir%\listing_0043_immediate_movs.txt %build_dir% 1>NUL
|
||||||
|
|
||||||
REM Build
|
REM Build
|
||||||
REM ===========================================================================
|
REM ===========================================================================
|
||||||
@ -51,3 +53,7 @@ set listing_0042=%build_dir%\listing_0042_completionist_decode
|
|||||||
%build_dir%\sim8086.exe %listing_0042% > %listing_0042%_disassembled.asm
|
%build_dir%\sim8086.exe %listing_0042% > %listing_0042%_disassembled.asm
|
||||||
nasm %listing_0042%_disassembled.asm
|
nasm %listing_0042%_disassembled.asm
|
||||||
fc /B %listing_0042% %listing_0042%_disassembled || exit /b 1
|
fc /B %listing_0042% %listing_0042%_disassembled || exit /b 1
|
||||||
|
|
||||||
|
set listing_0043=%build_dir%\listing_0043_immediate_movs
|
||||||
|
%build_dir%\sim8086.exe --exec %listing_0043% > %listing_0043%_disassembled.txt
|
||||||
|
fc /N %listing_0043%.txt %listing_0043%_disassembled.txt || exit /b 1
|
||||||
|
BIN
part1/listing_0043_immediate_movs
Normal file
BIN
part1/listing_0043_immediate_movs
Normal file
Binary file not shown.
27
part1/listing_0043_immediate_movs.asm
Normal file
27
part1/listing_0043_immediate_movs.asm
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
; ========================================================================
|
||||||
|
;
|
||||||
|
; (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 43
|
||||||
|
; ========================================================================
|
||||||
|
|
||||||
|
bits 16
|
||||||
|
|
||||||
|
mov ax, 1
|
||||||
|
mov bx, 2
|
||||||
|
mov cx, 3
|
||||||
|
mov dx, 4
|
||||||
|
|
||||||
|
mov sp, 5
|
||||||
|
mov bp, 6
|
||||||
|
mov si, 7
|
||||||
|
mov di, 8
|
20
part1/listing_0043_immediate_movs.txt
Normal file
20
part1/listing_0043_immediate_movs.txt
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
--- test\listing_0043_immediate_movs execution ---
|
||||||
|
mov ax, 1 ; ax:0x0->0x1
|
||||||
|
mov bx, 2 ; bx:0x0->0x2
|
||||||
|
mov cx, 3 ; cx:0x0->0x3
|
||||||
|
mov dx, 4 ; dx:0x0->0x4
|
||||||
|
mov sp, 5 ; sp:0x0->0x5
|
||||||
|
mov bp, 6 ; bp:0x0->0x6
|
||||||
|
mov si, 7 ; si:0x0->0x7
|
||||||
|
mov di, 8 ; di:0x0->0x8
|
||||||
|
|
||||||
|
Final registers:
|
||||||
|
ax: 0x0001 (1)
|
||||||
|
bx: 0x0002 (2)
|
||||||
|
cx: 0x0003 (3)
|
||||||
|
dx: 0x0004 (4)
|
||||||
|
sp: 0x0005 (5)
|
||||||
|
bp: 0x0006 (6)
|
||||||
|
si: 0x0007 (7)
|
||||||
|
di: 0x0008 (8)
|
||||||
|
|
110
part1/sim8086.c
110
part1/sim8086.c
@ -3,6 +3,17 @@
|
|||||||
|
|
||||||
#include "sim8086_stdlib.c"
|
#include "sim8086_stdlib.c"
|
||||||
|
|
||||||
|
typedef struct RegisterFile {
|
||||||
|
uint16_t ax;
|
||||||
|
uint16_t cx;
|
||||||
|
uint16_t dx;
|
||||||
|
uint16_t bx;
|
||||||
|
uint16_t sp;
|
||||||
|
uint16_t bp;
|
||||||
|
uint16_t si;
|
||||||
|
uint16_t di;
|
||||||
|
} RegisterFile;
|
||||||
|
|
||||||
S86_Str8 S86_MnemonicStr8(S86_Mnemonic type)
|
S86_Str8 S86_MnemonicStr8(S86_Mnemonic type)
|
||||||
{
|
{
|
||||||
S86_Str8 result = {0};
|
S86_Str8 result = {0};
|
||||||
@ -256,8 +267,6 @@ void S86_PrintOpcode(S86_Opcode opcode)
|
|||||||
|
|
||||||
if (opcode.mnemonic == S86_Mnemonic_LOCK)
|
if (opcode.mnemonic == S86_Mnemonic_LOCK)
|
||||||
S86_Print(S86_STR8(" "));
|
S86_Print(S86_STR8(" "));
|
||||||
else
|
|
||||||
S86_Print(S86_STR8("\n"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void S86_DecodeEffectiveAddr(S86_Opcode *opcode, S86_BufferIterator *buffer_it, uint8_t rm, uint8_t mod, uint8_t w)
|
void S86_DecodeEffectiveAddr(S86_Opcode *opcode, S86_BufferIterator *buffer_it, uint8_t rm, uint8_t mod, uint8_t w)
|
||||||
@ -766,16 +775,39 @@ S86_Opcode S86_DecodeOpcode(S86_BufferIterator *buffer_it,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#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)
|
||||||
{
|
{
|
||||||
// NOTE: Argument handling
|
// NOTE: Argument handling
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
if (argc != 2) {
|
if (argc != 2 && argc != 3) {
|
||||||
S86_PrintLn(S86_STR8("usage: sim8086.exe <binary asm file>"));
|
PRINT_USAGE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
char const *file_path = argv[1];
|
bool exec_mode = false;
|
||||||
|
char const *file_path = NULL;
|
||||||
|
if (argc == 3) {
|
||||||
|
S86_Str8 exec_mode_str8 = {argv[1], strlen(argv[1])};
|
||||||
|
file_path = argv[2];
|
||||||
|
if (!S86_Str8_Equals(exec_mode_str8, S86_STR8("--exec"))) {
|
||||||
|
PRINT_USAGE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
exec_mode = true;
|
||||||
|
} else {
|
||||||
|
file_path = argv[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
char const *file_name = file_path;
|
||||||
|
size_t file_path_size = strlen(file_path);
|
||||||
|
for (size_t index = file_path_size - 1; index < file_path_size; index--) {
|
||||||
|
if (file_path[index] == '\\' || file_path[index] == '/') {
|
||||||
|
file_name = file_path + index + 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
S86_Buffer buffer = S86_FileRead(file_path);
|
S86_Buffer buffer = S86_FileRead(file_path);
|
||||||
if (!S86_BufferIsValid(buffer)) {
|
if (!S86_BufferIsValid(buffer)) {
|
||||||
S86_PrintLnFmt("File read failed [path=\"%s\"]", argv[1], buffer.size);
|
S86_PrintLnFmt("File read failed [path=\"%s\"]", argv[1], buffer.size);
|
||||||
@ -1076,11 +1108,46 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
// NOTE: Decode assembly
|
// NOTE: Decode assembly
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
if (exec_mode)
|
||||||
|
S86_PrintLnFmt("--- test\\%s execution ---", file_name);
|
||||||
|
else
|
||||||
S86_PrintLn(S86_STR8("bits 16"));
|
S86_PrintLn(S86_STR8("bits 16"));
|
||||||
|
|
||||||
|
RegisterFile register_file = {0};
|
||||||
S86_BufferIterator buffer_it = S86_BufferIteratorInit(buffer);
|
S86_BufferIterator buffer_it = S86_BufferIteratorInit(buffer);
|
||||||
S86_MnemonicOp seg_reg = {0};
|
S86_MnemonicOp seg_reg = {0};
|
||||||
bool lock_prefix = false;
|
bool lock_prefix = false;
|
||||||
|
|
||||||
|
typedef struct MnemonicOpToRegisterFileMap {
|
||||||
|
S86_MnemonicOp mnemonic_op;
|
||||||
|
uint16_t mask;
|
||||||
|
uint16_t r_shift;
|
||||||
|
uint16_t *reg;
|
||||||
|
} MnemonicOpToRegisterFileMap;
|
||||||
|
|
||||||
|
MnemonicOpToRegisterFileMap mnemonic_op_to_register_file_map[] = {
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_AX, .reg = ®ister_file.ax, .mask = 0xFFFF, .r_shift = 0},
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_AL, .reg = ®ister_file.ax, .mask = 0x00FF, .r_shift = 0},
|
||||||
|
{.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_CL, .reg = ®ister_file.cx, .mask = 0x00FF, .r_shift = 0},
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_CH, .reg = ®ister_file.cx, .mask = 0xFF00, .r_shift = 8},
|
||||||
|
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_DX, .reg = ®ister_file.dx, .mask = 0xFFFF, .r_shift = 0},
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_DL, .reg = ®ister_file.dx, .mask = 0x00FF, .r_shift = 0},
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_DH, .reg = ®ister_file.dx, .mask = 0xFF00, .r_shift = 8},
|
||||||
|
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_BX, .reg = ®ister_file.bx, .mask = 0xFFFF, .r_shift = 0},
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_BL, .reg = ®ister_file.bx, .mask = 0x00FF, .r_shift = 0},
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_BH, .reg = ®ister_file.bx, .mask = 0xFF00, .r_shift = 8},
|
||||||
|
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_SP, .reg = ®ister_file.sp, .mask = 0xFFFF, .r_shift = 0},
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_BP, .reg = ®ister_file.bp, .mask = 0xFFFF, .r_shift = 0},
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_SI, .reg = ®ister_file.si, .mask = 0xFFFF, .r_shift = 0},
|
||||||
|
{.mnemonic_op = S86_MnemonicOp_DI, .reg = ®ister_file.di, .mask = 0xFFFF, .r_shift = 0},
|
||||||
|
};
|
||||||
|
|
||||||
while (S86_BufferIteratorHasMoreBytes(buffer_it)) {
|
while (S86_BufferIteratorHasMoreBytes(buffer_it)) {
|
||||||
S86_Opcode opcode = S86_DecodeOpcode(&buffer_it,
|
S86_Opcode opcode = S86_DecodeOpcode(&buffer_it,
|
||||||
DECODE_TABLE,
|
DECODE_TABLE,
|
||||||
@ -1088,5 +1155,38 @@ int main(int argc, char **argv)
|
|||||||
&lock_prefix,
|
&lock_prefix,
|
||||||
&seg_reg);
|
&seg_reg);
|
||||||
S86_PrintOpcode(opcode);
|
S86_PrintOpcode(opcode);
|
||||||
|
if (opcode.mnemonic == S86_Mnemonic_LOCK || opcode.mnemonic == S86_Mnemonic_SEGMENT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (exec_mode && opcode.mnemonic == S86_Mnemonic_MOV) {
|
||||||
|
MnemonicOpToRegisterFileMap const *dest_map = NULL;
|
||||||
|
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;
|
||||||
|
if (item->mnemonic_op == opcode.dest)
|
||||||
|
dest_map = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest_map) {
|
||||||
|
uint16_t *dest = dest_map->reg;
|
||||||
|
if (opcode.src == S86_MnemonicOp_Immediate) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
S86_Print(S86_STR8("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exec_mode) {
|
||||||
|
S86_PrintLn(S86_STR8("\nFinal registers:"));
|
||||||
|
S86_PrintLnFmt(" ax: 0x%04x (%u)", register_file.ax, register_file.ax);
|
||||||
|
S86_PrintLnFmt(" bx: 0x%04x (%u)", register_file.bx, register_file.bx);
|
||||||
|
S86_PrintLnFmt(" cx: 0x%04x (%u)", register_file.cx, register_file.cx);
|
||||||
|
S86_PrintLnFmt(" dx: 0x%04x (%u)", register_file.dx, register_file.dx);
|
||||||
|
S86_PrintLnFmt(" sp: 0x%04x (%u)", register_file.sp, register_file.sp);
|
||||||
|
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(" di: 0x%04x (%u)", register_file.di, register_file.di);
|
||||||
|
S86_Print(S86_STR8("\n"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,11 @@
|
|||||||
// NOTE: Implementation
|
// NOTE: Implementation
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
bool S86_Str8_Equals(S86_Str8 lhs, S86_Str8 rhs)
|
||||||
|
{
|
||||||
|
bool result = lhs.size == rhs.size && memcmp(lhs.data, rhs.data, lhs.size) == 0;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
bool S86_BufferIsValid(S86_Buffer buffer)
|
bool S86_BufferIsValid(S86_Buffer buffer)
|
||||||
{
|
{
|
||||||
bool result = buffer.data && buffer.size;
|
bool result = buffer.data && buffer.size;
|
||||||
|
@ -39,6 +39,8 @@ typedef struct S86_Str8 {
|
|||||||
#define S86_STR8(string) (S86_Str8){.data = (string), .size = S86_ARRAY_UCOUNT(string) - 1 }
|
#define S86_STR8(string) (S86_Str8){.data = (string), .size = S86_ARRAY_UCOUNT(string) - 1 }
|
||||||
#define S86_STR8_FMT(string) (int)((string).size), (string).data
|
#define S86_STR8_FMT(string) (int)((string).size), (string).data
|
||||||
|
|
||||||
|
bool S86_Str8_Equals(S86_Str8 lhs, S86_Str8 rhs);
|
||||||
|
|
||||||
// NOTE: Buffer
|
// NOTE: Buffer
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
typedef struct S86_Buffer {
|
typedef struct S86_Buffer {
|
||||||
|
BIN
project.rdbg
BIN
project.rdbg
Binary file not shown.
Loading…
Reference in New Issue
Block a user