perfaware/part1: Get listing 0041 working
This commit is contained in:
parent
f5316a08fc
commit
f11c6d0b7f
@ -11,6 +11,7 @@ copy /Y %script_dir%\listing_0037_single_register_mov %build_dir% 1>NUL
|
|||||||
copy /Y %script_dir%\listing_0038_many_register_mov %build_dir% 1>NUL
|
copy /Y %script_dir%\listing_0038_many_register_mov %build_dir% 1>NUL
|
||||||
copy /Y %script_dir%\listing_0039_more_movs %build_dir% 1>NUL
|
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
|
||||||
|
|
||||||
REM Build
|
REM Build
|
||||||
REM ===========================================================================
|
REM ===========================================================================
|
||||||
@ -23,19 +24,24 @@ REM ===========================================================================
|
|||||||
set listing_0037=%build_dir%\listing_0037_single_register_mov
|
set listing_0037=%build_dir%\listing_0037_single_register_mov
|
||||||
%build_dir%\sim8086.exe %listing_0037% > %listing_0037%_disassembled.asm
|
%build_dir%\sim8086.exe %listing_0037% > %listing_0037%_disassembled.asm
|
||||||
nasm %listing_0037%_disassembled.asm
|
nasm %listing_0037%_disassembled.asm
|
||||||
fc %listing_0037% %listing_0037%_disassembled || exit /b 1
|
fc /B %listing_0037% %listing_0037%_disassembled || exit /b 1
|
||||||
|
|
||||||
set listing_0038=%build_dir%\listing_0038_many_register_mov
|
set listing_0038=%build_dir%\listing_0038_many_register_mov
|
||||||
%build_dir%\sim8086.exe %listing_0038% > %listing_0038%_disassembled.asm
|
%build_dir%\sim8086.exe %listing_0038% > %listing_0038%_disassembled.asm
|
||||||
nasm %listing_0038%_disassembled.asm
|
nasm %listing_0038%_disassembled.asm
|
||||||
fc %listing_0038% %listing_0038%_disassembled || exit /b 1
|
fc /B %listing_0038% %listing_0038%_disassembled || exit /b 1
|
||||||
|
|
||||||
set listing_0039=%build_dir%\listing_0039_more_movs
|
set listing_0039=%build_dir%\listing_0039_more_movs
|
||||||
%build_dir%\sim8086.exe %listing_0039% > %listing_0039%_disassembled.asm
|
%build_dir%\sim8086.exe %listing_0039% > %listing_0039%_disassembled.asm
|
||||||
nasm %listing_0039%_disassembled.asm
|
nasm %listing_0039%_disassembled.asm
|
||||||
fc %listing_0039% %listing_0039%_disassembled || exit /b 1
|
fc /B %listing_0039% %listing_0039%_disassembled || exit /b 1
|
||||||
|
|
||||||
set listing_0040=%build_dir%\listing_0040_challenge_movs
|
set listing_0040=%build_dir%\listing_0040_challenge_movs
|
||||||
%build_dir%\sim8086.exe %listing_0040% > %listing_0040%_disassembled.asm
|
%build_dir%\sim8086.exe %listing_0040% > %listing_0040%_disassembled.asm
|
||||||
nasm %listing_0040%_disassembled.asm
|
nasm %listing_0040%_disassembled.asm
|
||||||
fc %listing_0040% %listing_0040%_disassembled || exit /b 1
|
fc /B %listing_0040% %listing_0040%_disassembled || exit /b 1
|
||||||
|
|
||||||
|
set listing_0041=%build_dir%\listing_0041_add_sub_cmp_jnz
|
||||||
|
%build_dir%\sim8086.exe %listing_0041% > %listing_0041%_disassembled.asm
|
||||||
|
nasm %listing_0041%_disassembled.asm
|
||||||
|
fc /B %listing_0041% %listing_0041%_disassembled || exit /b 1
|
||||||
|
Binary file not shown.
@ -376,7 +376,7 @@ loopnz label
|
|||||||
jcxz label
|
jcxz label
|
||||||
|
|
||||||
int 13
|
int 13
|
||||||
int 3
|
int3
|
||||||
|
|
||||||
into
|
into
|
||||||
iret
|
iret
|
||||||
@ -408,6 +408,14 @@ sbb word cs:[bx + si - 4332], 10328
|
|||||||
|
|
||||||
lock not byte CS:[bp + 9905]
|
lock not byte CS:[bp + 9905]
|
||||||
|
|
||||||
|
;
|
||||||
|
; NOTE(casey): These were not in the original homework set, but have been added since, as people
|
||||||
|
; found instruction encodings that were not previously covered
|
||||||
|
;
|
||||||
|
|
||||||
|
call 123:456
|
||||||
|
jmp 789:34
|
||||||
|
|
||||||
;
|
;
|
||||||
; TODO(casey): I would like to uncomment this, but as far as I can tell, NASM doesn't recognize the ESC instruction :(
|
; TODO(casey): I would like to uncomment this, but as far as I can tell, NASM doesn't recognize the ESC instruction :(
|
||||||
; so even if I just force the assembler to output the bits here, our disasm will fail to assemble because it will (correctly!)
|
; so even if I just force the assembler to output the bits here, our disasm will fail to assemble because it will (correctly!)
|
||||||
|
@ -108,7 +108,7 @@ typedef enum S86_InstructionType {
|
|||||||
S86_InstructionType_LOOP,
|
S86_InstructionType_LOOP,
|
||||||
S86_InstructionType_LOOPZ_LOOPE,
|
S86_InstructionType_LOOPZ_LOOPE,
|
||||||
S86_InstructionType_LOOPNZ_LOOPNE,
|
S86_InstructionType_LOOPNZ_LOOPNE,
|
||||||
S86_InstructionType_JCZX,
|
S86_InstructionType_JCXZ,
|
||||||
|
|
||||||
S86_InstructionType_Count,
|
S86_InstructionType_Count,
|
||||||
} S86_InstructionType;
|
} S86_InstructionType;
|
||||||
@ -242,7 +242,7 @@ void S86_FileFree(S86_Buffer buffer)
|
|||||||
VirtualFree(buffer.data, 0, MEM_RELEASE);
|
VirtualFree(buffer.data, 0, MEM_RELEASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void S86_PrintLn(S86_Str8 string)
|
void S86_Print(S86_Str8 string)
|
||||||
{
|
{
|
||||||
if (s86_globals.stdout_handle == NULL) {
|
if (s86_globals.stdout_handle == NULL) {
|
||||||
s86_globals.stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
s86_globals.stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
@ -259,14 +259,38 @@ void S86_PrintLn(S86_Str8 string)
|
|||||||
if (s86_globals.write_to_console) {
|
if (s86_globals.write_to_console) {
|
||||||
DWORD chars_written = 0;
|
DWORD chars_written = 0;
|
||||||
WriteConsoleA(s86_globals.stdout_handle, string.data, (DWORD)string.size, &chars_written, NULL);
|
WriteConsoleA(s86_globals.stdout_handle, string.data, (DWORD)string.size, &chars_written, NULL);
|
||||||
WriteConsoleA(s86_globals.stdout_handle, "\n", 1, &chars_written, NULL);
|
|
||||||
} else {
|
} else {
|
||||||
DWORD bytes_written = 0;
|
DWORD bytes_written = 0;
|
||||||
WriteFile(s86_globals.stdout_handle, string.data, (DWORD)string.size, &bytes_written, NULL);
|
WriteFile(s86_globals.stdout_handle, string.data, (DWORD)string.size, &bytes_written, NULL);
|
||||||
WriteFile(s86_globals.stdout_handle, "\n", 1, &bytes_written, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void S86_PrintLn(S86_Str8 string)
|
||||||
|
{
|
||||||
|
S86_Print(string);
|
||||||
|
S86_Print(S86_STR8("\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void S86_PrintFmt(char const *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list args, args_copy;
|
||||||
|
va_start(args, fmt);
|
||||||
|
|
||||||
|
va_copy(args_copy, args);
|
||||||
|
int string_size = vsnprintf(NULL, 0, fmt, args_copy);
|
||||||
|
va_end(args_copy);
|
||||||
|
|
||||||
|
char buffer[8192];
|
||||||
|
S86_ASSERT(string_size >= 0 && string_size < S86_ARRAY_UCOUNT(buffer));
|
||||||
|
if (string_size) {
|
||||||
|
vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||||
|
S86_Str8 string = {.data = buffer, .size = string_size};
|
||||||
|
S86_Print(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
void S86_PrintLnFmt(char const *fmt, ...)
|
void S86_PrintLnFmt(char const *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list args, args_copy;
|
va_list args, args_copy;
|
||||||
@ -420,9 +444,9 @@ S86_Instruction const S86_INSTRUCTIONS[S86_InstructionType_Count] = {
|
|||||||
[S86_InstructionType_CMPImmediateWithAccum] = {.op_mask0 = 0b1111'1110, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_CMPImmediateWithAccum] = {.op_mask0 = 0b1111'1110, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0011'1100, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("cmp")},
|
.op_bits0 = 0b0011'1100, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("cmp")},
|
||||||
[S86_InstructionType_JE_JZ] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JE_JZ] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'0101, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jz")},
|
.op_bits0 = 0b0111'0100, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("je")},
|
||||||
[S86_InstructionType_JL_JNGE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JL_JNGE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'1101, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jl")},
|
.op_bits0 = 0b0111'1100, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jl")},
|
||||||
[S86_InstructionType_JLE_JNG] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JLE_JNG] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'1110, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jle")},
|
.op_bits0 = 0b0111'1110, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jle")},
|
||||||
[S86_InstructionType_JB_JNAE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JB_JNAE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
@ -436,15 +460,15 @@ S86_Instruction const S86_INSTRUCTIONS[S86_InstructionType_Count] = {
|
|||||||
[S86_InstructionType_JS] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JS] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'1000, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("js")},
|
.op_bits0 = 0b0111'1000, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("js")},
|
||||||
[S86_InstructionType_JNE_JNZ] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JNE_JNZ] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'0101, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jne")},
|
.op_bits0 = 0b0111'0101, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jnz")},
|
||||||
[S86_InstructionType_JNL_JGE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JNL_JGE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'1101, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jnl")},
|
.op_bits0 = 0b0111'1101, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jnl")},
|
||||||
[S86_InstructionType_JNLE_JG] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JNLE_JG] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'1111, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jnle")},
|
.op_bits0 = 0b0111'1111, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jg")},
|
||||||
[S86_InstructionType_JNB_JAE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JNB_JAE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'0011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jnb")},
|
.op_bits0 = 0b0111'0011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jnb")},
|
||||||
[S86_InstructionType_JNBE_JA] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JNBE_JA] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'0111, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jnbe")},
|
.op_bits0 = 0b0111'0111, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("ja")},
|
||||||
[S86_InstructionType_JNP_JO] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JNP_JO] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b0111'1011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jnp")},
|
.op_bits0 = 0b0111'1011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jnp")},
|
||||||
[S86_InstructionType_JNO] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JNO] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
@ -457,8 +481,8 @@ S86_Instruction const S86_INSTRUCTIONS[S86_InstructionType_Count] = {
|
|||||||
.op_bits0 = 0b1110'0001, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("loopz")},
|
.op_bits0 = 0b1110'0001, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("loopz")},
|
||||||
[S86_InstructionType_LOOPNZ_LOOPNE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_LOOPNZ_LOOPNE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b1110'0000, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("loopnz")},
|
.op_bits0 = 0b1110'0000, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("loopnz")},
|
||||||
[S86_InstructionType_JCZX] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
[S86_InstructionType_JCXZ] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||||
.op_bits0 = 0b1110'0011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jczx")},
|
.op_bits0 = 0b1110'0011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jcxz")},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -590,10 +614,18 @@ S86_Instruction const S86_INSTRUCTIONS[S86_InstructionType_Count] = {
|
|||||||
if (instruction_type == S86_InstructionType_MOVImmediateToRegOrMem) {
|
if (instruction_type == S86_InstructionType_MOVImmediateToRegOrMem) {
|
||||||
S86_PrintLnFmt("%.*s %.*s, %s %u", S86_STR8_FMT(instruction->mnemonic), effective_address.size, effective_address.data, w ? "word" : "byte", data);
|
S86_PrintLnFmt("%.*s %.*s, %s %u", S86_STR8_FMT(instruction->mnemonic), effective_address.size, effective_address.data, w ? "word" : "byte", data);
|
||||||
} else {
|
} else {
|
||||||
if (sign_extend_8bit_data) {
|
if (effective_address.data[0] == '[') {
|
||||||
S86_PrintLnFmt("%.*s %.*s, %d", S86_STR8_FMT(instruction->mnemonic), effective_address.size, effective_address.data, (int16_t)data);
|
if (sign_extend_8bit_data) {
|
||||||
|
S86_PrintLnFmt("%.*s %s %.*s, %d", S86_STR8_FMT(instruction->mnemonic), w ? "word" : "byte", effective_address.size, effective_address.data, (int16_t)data);
|
||||||
|
} else {
|
||||||
|
S86_PrintLnFmt("%.*s %s %.*s, %u", S86_STR8_FMT(instruction->mnemonic), w ? "word" : "byte", effective_address.size, effective_address.data, data);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
S86_PrintLnFmt("%.*s %.*s, %u", S86_STR8_FMT(instruction->mnemonic), effective_address.size, effective_address.data, data);
|
if (sign_extend_8bit_data) {
|
||||||
|
S86_PrintLnFmt("%.*s %.*s, %d", S86_STR8_FMT(instruction->mnemonic), effective_address.size, effective_address.data, (int16_t)data);
|
||||||
|
} else {
|
||||||
|
S86_PrintLnFmt("%.*s %.*s, %u", S86_STR8_FMT(instruction->mnemonic), effective_address.size, effective_address.data, data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
@ -661,10 +693,17 @@ S86_Instruction const S86_INSTRUCTIONS[S86_InstructionType_Count] = {
|
|||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
if (instruction_type >= S86_InstructionType_JE_JZ && instruction_type <= S86_InstructionType_JCZX) {
|
if (instruction_type >= S86_InstructionType_JE_JZ && instruction_type <= S86_InstructionType_JCXZ) {
|
||||||
S86_ASSERT(op_code_size == 1);
|
S86_ASSERT(op_code_size == 1);
|
||||||
int8_t jump_offset = S86_CAST(int8_t)S86_BufferIteratorNextByte(&buffer_it);
|
int8_t jump_offset = S86_CAST(int8_t)S86_BufferIteratorNextByte(&buffer_it);
|
||||||
S86_PrintLnFmt("%.*s %d", S86_STR8_FMT(instruction->mnemonic), jump_offset);
|
char sign = 0;
|
||||||
|
if (jump_offset > 0) {
|
||||||
|
sign = '+';
|
||||||
|
} else {
|
||||||
|
jump_offset *= -1;
|
||||||
|
sign = '-';
|
||||||
|
}
|
||||||
|
S86_PrintLnFmt("%.*s $+2%c%d", S86_STR8_FMT(instruction->mnemonic), sign, jump_offset);
|
||||||
} else {
|
} else {
|
||||||
S86_ASSERT(!"Unhandled instruction");
|
S86_ASSERT(!"Unhandled instruction");
|
||||||
}
|
}
|
||||||
|
BIN
project.rdbg
BIN
project.rdbg
Binary file not shown.
Loading…
Reference in New Issue
Block a user