perfaware/part1: Add support for push and pop
This commit is contained in:
parent
f11c6d0b7f
commit
05d4558a23
@ -12,6 +12,7 @@ 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_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_0042_completionist_decode %build_dir% 1>NUL
|
||||
|
||||
REM Build
|
||||
REM ===========================================================================
|
||||
@ -45,3 +46,8 @@ 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
|
||||
|
||||
set listing_0042=%build_dir%\listing_0042_completionist_decode
|
||||
%build_dir%\sim8086.exe %listing_0042% > %listing_0042%_disassembled.asm
|
||||
nasm %listing_0042%_disassembled.asm
|
||||
fc /B %listing_0042% %listing_0042%_disassembled || exit /b 1
|
||||
|
@ -77,6 +77,14 @@ typedef enum S86_InstructionType {
|
||||
S86_InstructionType_MOVRegOrMemToSegReg,
|
||||
S86_InstructionType_MOVSegRegToRegOrMem,
|
||||
|
||||
S86_InstructionType_PUSHRegOrMem,
|
||||
S86_InstructionType_PUSHReg,
|
||||
S86_InstructionType_PUSHSegReg,
|
||||
|
||||
S86_InstructionType_POPRegOrMem,
|
||||
S86_InstructionType_POPReg,
|
||||
S86_InstructionType_POPSegReg,
|
||||
|
||||
S86_InstructionType_ADDRegOrMemToOrFromReg,
|
||||
S86_InstructionType_ADDImmediateToRegOrMem,
|
||||
S86_InstructionType_ADDImmediateToAccum,
|
||||
@ -265,12 +273,6 @@ void S86_Print(S86_Str8 string)
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@ -291,6 +293,12 @@ void S86_PrintFmt(char const *fmt, ...)
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void S86_PrintLn(S86_Str8 string)
|
||||
{
|
||||
S86_Print(string);
|
||||
S86_Print(S86_STR8("\n"));
|
||||
}
|
||||
|
||||
void S86_PrintLnFmt(char const *fmt, ...)
|
||||
{
|
||||
va_list args, args_copy;
|
||||
@ -425,6 +433,22 @@ S86_Instruction const S86_INSTRUCTIONS[S86_InstructionType_Count] = {
|
||||
.op_bits0 = 0b1000'1110, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("mov")},
|
||||
[S86_InstructionType_MOVSegRegToRegOrMem] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0010'0000,
|
||||
.op_bits0 = 0b1000'1100, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("mov")},
|
||||
|
||||
[S86_InstructionType_PUSHRegOrMem] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0011'1000,
|
||||
.op_bits0 = 0b1111'1111, .op_bits1 = 0b0011'0000, .mnemonic = S86_STR8("push")},
|
||||
[S86_InstructionType_PUSHReg] = {.op_mask0 = 0b1111'1000, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b0101'0000, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("push")},
|
||||
[S86_InstructionType_PUSHSegReg] = {.op_mask0 = 0b1110'0111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b0000'0110, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("push")},
|
||||
|
||||
[S86_InstructionType_POPRegOrMem] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0011'1000,
|
||||
.op_bits0 = 0b1000'1111, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("pop")},
|
||||
[S86_InstructionType_POPReg] = {.op_mask0 = 0b1111'1000, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b0101'1000, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("pop")},
|
||||
[S86_InstructionType_POPSegReg] = {.op_mask0 = 0b1110'0111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b0000'0111, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("pop")},
|
||||
|
||||
|
||||
[S86_InstructionType_ADDRegOrMemToOrFromReg] = {.op_mask0 = 0b1111'1100, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b0000'0000, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("add")},
|
||||
[S86_InstructionType_ADDImmediateToRegOrMem] = {.op_mask0 = 0b1111'1100, .op_mask1 = 0b0011'1000,
|
||||
@ -485,6 +509,12 @@ S86_Instruction const S86_INSTRUCTIONS[S86_InstructionType_Count] = {
|
||||
.op_bits0 = 0b1110'0011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jcxz")},
|
||||
};
|
||||
|
||||
S86_Str8 SEGMENT_REGISTER_NAME[] = {
|
||||
[0b00] = S86_STR8("es"),
|
||||
[0b01] = S86_STR8("cs"),
|
||||
[0b10] = S86_STR8("ss"),
|
||||
[0b11] = S86_STR8("ds"),
|
||||
};
|
||||
|
||||
// NOTE: Decode assembly
|
||||
// =========================================================================
|
||||
@ -539,6 +569,35 @@ S86_Instruction const S86_INSTRUCTIONS[S86_InstructionType_Count] = {
|
||||
|
||||
switch (instruction_type) {
|
||||
|
||||
case S86_InstructionType_POPRegOrMem: /*FALLTHRU*/
|
||||
case S86_InstructionType_PUSHRegOrMem: {
|
||||
S86_ASSERT(op_code_size == 2);
|
||||
uint8_t mod = (op_code_bytes[1] & 0b1100'0000) >> 6;
|
||||
uint8_t rm = (op_code_bytes[1] & 0b0000'0111) >> 0;
|
||||
S86_ASSERT(mod < 4); S86_ASSERT(rm < 8);
|
||||
S86_EffectiveAddressStr8 effective_address = S86_EffectiveAddressCalc(&buffer_it, rm, mod, 0 /*w*/);
|
||||
S86_PrintLnFmt("%.*s word %.*s", S86_STR8_FMT(instruction->mnemonic), S86_STR8_FMT(effective_address));
|
||||
} break;
|
||||
|
||||
case S86_InstructionType_PUSHReg: /*FALLTHRU*/
|
||||
case S86_InstructionType_POPReg: /*FALLTHRU*/
|
||||
case S86_InstructionType_PUSHSegReg: /*FALLTHRU*/
|
||||
case S86_InstructionType_POPSegReg: {
|
||||
S86_ASSERT(op_code_size == 1);
|
||||
S86_Str8 reg_name = {0};
|
||||
if (instruction_type == S86_InstructionType_PUSHReg ||
|
||||
instruction_type == S86_InstructionType_POPReg) {
|
||||
uint8_t reg = (op_code_bytes[0] & 0b0000'0111) >> 0;
|
||||
reg_name = REGISTER_FIELD_ENCODING[/*w*/1][reg];
|
||||
} else {
|
||||
S86_ASSERT(instruction_type == S86_InstructionType_PUSHSegReg ||
|
||||
instruction_type == S86_InstructionType_POPSegReg);
|
||||
uint8_t sr = (op_code_bytes[0] & 0b0001'1000) >> 3;
|
||||
reg_name = SEGMENT_REGISTER_NAME[sr];
|
||||
}
|
||||
S86_PrintLnFmt("%.*s %.*s", S86_STR8_FMT(instruction->mnemonic), S86_STR8_FMT(reg_name));
|
||||
} break;
|
||||
|
||||
case S86_InstructionType_CMPRegOrMemAndReg: /*FALLTHRU*/
|
||||
case S86_InstructionType_SUBRegOrMemToOrFromReg: /*FALLTHRU*/
|
||||
case S86_InstructionType_ADDRegOrMemToOrFromReg: /*FALLTHRU*/
|
||||
|
Loading…
Reference in New Issue
Block a user