perfaware/part1: Support listing 0053"

This commit is contained in:
doyle 2023-04-18 21:28:41 +10:00
parent 39ec4213d6
commit 35fe0b899a
7 changed files with 127 additions and 24 deletions

View File

@ -220,3 +220,18 @@ nasm %build_dir_listing_0052%_disassembled.asm
fc /B %build_dir_listing_0052% %build_dir_listing_0052%_disassembled || exit /b 1
fc /N %build_dir_listing_0052%.txt %build_dir_listing_0052%_disassembled.txt || exit /b 1
REM ================================================================================================
set listing_0053=listing_0053_add_loop_challenge
set build_dir_listing_0053=%build_dir%\%listing_0053%
copy /Y %script_dir%\%listing_0053% %build_dir% 1>NUL
copy /Y %script_dir%\%listing_0053%.txt %build_dir% 1>NUL
%build_dir%\sim8086.exe --exec --log-instruction-ptr %build_dir_listing_0053% > %build_dir_listing_0053%_disassembled.txt
%build_dir%\sim8086.exe %build_dir_listing_0053% > %build_dir_listing_0053%_disassembled.asm
nasm %build_dir_listing_0053%_disassembled.asm
fc /B %build_dir_listing_0053% %build_dir_listing_0053%_disassembled || exit /b 1
fc /N %build_dir_listing_0053%.txt %build_dir_listing_0053%_disassembled.txt || exit /b 1

Binary file not shown.

View File

@ -0,0 +1,35 @@
; ========================================================================
;
; (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 53
; ========================================================================
bits 16
mov dx, 6
mov bp, 1000
mov si, 0
init_loop_start:
mov word [bp + si], si
add si, 2
cmp si, dx
jnz init_loop_start
mov bx, 0
mov si, dx
sub bp, 2
add_loop_start:
add bx, word [bp + si]
sub si, 2
jnz add_loop_start

View File

@ -0,0 +1,36 @@
--- test\listing_0053_add_loop_challenge execution ---
mov dx, 6 ; dx:0x0->0x6 ip:0x0->0x3
mov bp, 1000 ; bp:0x0->0x3e8 ip:0x3->0x6
mov si, 0 ; ip:0x6->0x9
mov word [bp+si], si ; ip:0x9->0xb
add si, 2 ; si:0x0->0x2 ip:0xb->0xe
cmp si, dx ; ip:0xe->0x10 flags:->CPAS
jne $-7 ; ip:0x10->0x9
mov word [bp+si], si ; ip:0x9->0xb
add si, 2 ; si:0x2->0x4 ip:0xb->0xe flags:CPAS->
cmp si, dx ; ip:0xe->0x10 flags:->CAS
jne $-7 ; ip:0x10->0x9
mov word [bp+si], si ; ip:0x9->0xb
add si, 2 ; si:0x4->0x6 ip:0xb->0xe flags:CAS->P
cmp si, dx ; ip:0xe->0x10 flags:P->PZ
jne $-7 ; ip:0x10->0x12
mov bx, 0 ; ip:0x12->0x15
mov si, dx ; ip:0x15->0x17
sub bp, 2 ; bp:0x3e8->0x3e6 ip:0x17->0x1a flags:PZ->
add bx, [bp+si] ; bx:0x0->0x4 ip:0x1a->0x1c
sub si, 2 ; si:0x6->0x4 ip:0x1c->0x1f
jne $-5 ; ip:0x1f->0x1a
add bx, [bp+si] ; bx:0x4->0x6 ip:0x1a->0x1c flags:->P
sub si, 2 ; si:0x4->0x2 ip:0x1c->0x1f flags:P->
jne $-5 ; ip:0x1f->0x1a
add bx, [bp+si] ; ip:0x1a->0x1c flags:->P
sub si, 2 ; si:0x2->0x0 ip:0x1c->0x1f flags:P->PZ
jne $-5 ; ip:0x1f->0x21
Final registers:
bx: 0x0006 (6)
dx: 0x0006 (6)
bp: 0x03e6 (998)
ip: 0x0021 (33)
flags: PZ

View File

@ -231,19 +231,6 @@ void S86_PrintOpcodeMnemonicOp(S86_Opcode opcode, bool src)
bool effective_addr = ( src && opcode.effective_addr == S86_EffectiveAddress_Src) ||
(!src && opcode.effective_addr == S86_EffectiveAddress_Dest);
bool wide_prefix = false;
if (opcode.effective_addr == S86_EffectiveAddress_Dest && opcode.effective_addr_loads_mem) {
if (opcode.src == S86_MnemonicOp_DirectAddress ||
opcode.src == S86_MnemonicOp_Immediate ||
opcode.src == S86_MnemonicOp_Invalid ||
(opcode.src >= S86_MnemonicOp_AL && opcode.src <= S86_MnemonicOp_BH) ||
(opcode.src == S86_MnemonicOp_SI)) {
// TODO: Not sure why SI needs the prefix as well, but, according
// to the reference decoder its being emitted here.
wide_prefix = (src == false); // NOTE: Only print on the dest op
}
}
if (mnemonic_op == S86_MnemonicOp_Invalid)
return;
@ -252,8 +239,8 @@ void S86_PrintOpcodeMnemonicOp(S86_Opcode opcode, bool src)
else
S86_PrintFmt(" ");
if (wide_prefix)
S86_PrintFmt("%s ", opcode.wide ? "word" : "byte");
if (!src && opcode.word_byte_prefix != S86_WordBytePrefix_None)
S86_PrintFmt("%s ", opcode.word_byte_prefix == S86_WordBytePrefix_Word ? "word" : "byte");
if (effective_addr && opcode.seg_reg_prefix != S86_MnemonicOp_Invalid) {
S86_Str8 prefix = S86_MnemonicOpStr8(opcode.seg_reg_prefix);
@ -844,6 +831,18 @@ S86_Opcode S86_DecodeOpcode(S86_BufferIterator *buffer_it,
if (op_decode_type != S86_OpDecodeType_SEGMENT)
*seg_reg = S86_MnemonicOp_Invalid;
if (result.effective_addr == S86_EffectiveAddress_Dest && result.effective_addr_loads_mem) {
if (result.src == S86_MnemonicOp_DirectAddress ||
result.src == S86_MnemonicOp_Immediate ||
result.src == S86_MnemonicOp_Invalid ||
(result.src >= S86_MnemonicOp_AL && result.src <= S86_MnemonicOp_BH) ||
(result.src == S86_MnemonicOp_SI)) {
// TODO: Not sure why SI needs the prefix as well, but, according
// to the reference decoder its being emitted here.
result.word_byte_prefix = result.wide ? S86_WordBytePrefix_Word : S86_WordBytePrefix_Byte;
}
}
size_t buffer_end_index = buffer_it->index;
result.byte_size = S86_CAST(uint8_t)(buffer_end_index - buffer_start_index);
result.instruction_ptr = S86_CAST(uint16_t)buffer_start_index;
@ -1430,7 +1429,8 @@ int main(int argc, char **argv)
src_map = item;
}
if (src_map->mnemonic_op >= S86_MnemonicOp_BX_SI && src_map->mnemonic_op <= S86_MnemonicOp_BP_DI) {
if (src_map->mnemonic_op >= S86_MnemonicOp_BX_SI &&
src_map->mnemonic_op <= S86_MnemonicOp_BP_DI) {
uint16_t address = 0;
if (src_map->mnemonic_op == S86_MnemonicOp_BX_SI) {
address = src_map->reg->word + register_file.reg.file.si.word;
@ -1524,6 +1524,9 @@ int main(int argc, char **argv)
S86_ASSERT(opcode->immediate < S86_CAST(uint16_t)-1);
src = S86_CAST(uint16_t)opcode->immediate;
}
} else if (opcode->src == S86_MnemonicOp_DirectAddress) {
S86_ASSERT(opcode->displacement >= 0);
src = memory[opcode->displacement];
} else {
S86_MnemonicOpToRegisterFileMap const *src_map = NULL;
for (size_t index = 0; !src_map && index < S86_ARRAY_UCOUNT(mnemonic_op_to_register_file_map); index++) {
@ -1532,14 +1535,21 @@ int main(int argc, char **argv)
src_map = item;
}
if (src_map->mnemonic_op == S86_MnemonicOp_BX_SI) {
src = src_map->reg->word + register_file.reg.file.si.word;
} else if (src_map->mnemonic_op == S86_MnemonicOp_BX_DI) {
src = src_map->reg->word + register_file.reg.file.di.word;
} else if (src_map->mnemonic_op == S86_MnemonicOp_BP_SI) {
src = src_map->reg->word + register_file.reg.file.si.word;
} else if (src_map->mnemonic_op == S86_MnemonicOp_BP_DI) {
src = src_map->reg->word + register_file.reg.file.di.word;
if (src_map->mnemonic_op >= S86_MnemonicOp_BX_SI &&
src_map->mnemonic_op <= S86_MnemonicOp_BP_DI) {
uint16_t address = 0;
if (src_map->mnemonic_op == S86_MnemonicOp_BX_SI) {
address = src_map->reg->word + register_file.reg.file.si.word;
} else if (src_map->mnemonic_op == S86_MnemonicOp_BX_DI) {
address = src_map->reg->word + register_file.reg.file.di.word;
} else if (src_map->mnemonic_op == S86_MnemonicOp_BP_SI) {
address = src_map->reg->word + register_file.reg.file.si.word;
} else if (src_map->mnemonic_op == S86_MnemonicOp_BP_DI) {
address = src_map->reg->word + register_file.reg.file.di.word;
} else {
S86_ASSERT(!"Invalid code path");
}
src = *(uint16_t *)&memory[address];
} else {
src = byte_op ? src_map->reg->bytes[src_map->byte] : src_map->reg->word;
}

View File

@ -315,6 +315,12 @@ typedef enum S86_EffectiveAddress {
S86_EffectiveAddress_Dest,
} S86_EffectiveAddress;
typedef enum S86_WordBytePrefix {
S86_WordBytePrefix_None,
S86_WordBytePrefix_Byte,
S86_WordBytePrefix_Word,
} S86_WordBytePrefix;
typedef struct S86_Opcode {
uint8_t byte_size; ///< Number of bytes used to encode this opcode
uint16_t instruction_ptr; ///< The instruction pointer value at this opcode
@ -325,6 +331,7 @@ typedef struct S86_Opcode {
bool lock_prefix; ///< Prefix the opcode with "lock" instruction
bool rep_prefix; ///< Prefix the opcode with "rep" instruction
bool wide; ///< Opcode has the 'w' flag set
S86_WordBytePrefix word_byte_prefix; ///< Opcode has the 'word' or 'byte' prefix
S86_MnemonicOp src; ///< Source op for the mnemonic
S86_MnemonicOp dest; ///< Destination op for the mnemonic
int32_t displacement; ///< Opcode has displacement/data/offset

Binary file not shown.