perfaware/part1: Add support for CALL/JMP/RET
This commit is contained in:
parent
21d98ec223
commit
10f200de1b
@ -173,6 +173,22 @@ typedef enum S86_InstructionType {
|
||||
|
||||
S86_InstructionType_REP,
|
||||
|
||||
S86_InstructionType_CALLDirectWithinSeg,
|
||||
S86_InstructionType_CALLIndirectWithinSeg,
|
||||
S86_InstructionType_CALLDirectInterSeg,
|
||||
S86_InstructionType_CALLIndirectInterSeg,
|
||||
|
||||
S86_InstructionType_JMPDirectWithinSeg,
|
||||
S86_InstructionType_JMPDirectWithinSegShort,
|
||||
S86_InstructionType_JMPIndirectWithinSeg,
|
||||
S86_InstructionType_JMPDirectInterSeg,
|
||||
S86_InstructionType_JMPIndirectInterSeg,
|
||||
|
||||
S86_InstructionType_RETWithinSeg,
|
||||
S86_InstructionType_RETWithinSegAddImmediateToSP,
|
||||
S86_InstructionType_RETInterSeg,
|
||||
S86_InstructionType_RETInterSegAddImmediateToSP,
|
||||
|
||||
S86_InstructionType_JE_JZ,
|
||||
S86_InstructionType_JL_JNGE,
|
||||
S86_InstructionType_JLE_JNG,
|
||||
@ -679,6 +695,35 @@ int main(int argc, char **argv)
|
||||
[S86_InstructionType_REP] = {.op_mask0 = 0b1111'1110, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1111'0010, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("rep")},
|
||||
|
||||
[S86_InstructionType_CALLDirectWithinSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1110'1000, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("call")},
|
||||
[S86_InstructionType_CALLIndirectWithinSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0011'1000,
|
||||
.op_bits0 = 0b1111'1111, .op_bits1 = 0b0001'0000, .mnemonic = S86_STR8("call")},
|
||||
[S86_InstructionType_CALLDirectInterSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1001'1010, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("call")},
|
||||
[S86_InstructionType_CALLIndirectInterSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0011'1000,
|
||||
.op_bits0 = 0b1111'1111, .op_bits1 = 0b0001'1000, .mnemonic = S86_STR8("call")},
|
||||
|
||||
[S86_InstructionType_JMPDirectWithinSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1110'1001, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jmp")},
|
||||
[S86_InstructionType_JMPDirectWithinSegShort] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1110'1011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jmp")},
|
||||
[S86_InstructionType_JMPIndirectWithinSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0011'1000,
|
||||
.op_bits0 = 0b1111'1111, .op_bits1 = 0b0010'0000, .mnemonic = S86_STR8("jmp")},
|
||||
[S86_InstructionType_JMPDirectInterSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1110'1010, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("jmp")},
|
||||
[S86_InstructionType_JMPIndirectInterSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0011'1000,
|
||||
.op_bits0 = 0b1111'1111, .op_bits1 = 0b0010'1000, .mnemonic = S86_STR8("jmp")},
|
||||
|
||||
[S86_InstructionType_RETWithinSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1100'0011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("ret")},
|
||||
[S86_InstructionType_RETWithinSegAddImmediateToSP] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1100'0010, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("ret")},
|
||||
[S86_InstructionType_RETInterSeg] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1100'1011, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("ret")},
|
||||
[S86_InstructionType_RETInterSegAddImmediateToSP] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b1100'1010, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("ret")},
|
||||
|
||||
[S86_InstructionType_JE_JZ] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
.op_bits0 = 0b0111'0100, .op_bits1 = 0b0000'0000, .mnemonic = S86_STR8("je")},
|
||||
[S86_InstructionType_JL_JNGE] = {.op_mask0 = 0b1111'1111, .op_mask1 = 0b0000'0000,
|
||||
@ -782,6 +827,10 @@ int main(int argc, char **argv)
|
||||
S86_Print(instruction->mnemonic);
|
||||
switch (instruction_type) {
|
||||
|
||||
// NOTE: Instruction Pattern => [0b000'0000W | 0bAA00'0CCC | DISP-LO | DISP-HI]
|
||||
// Where, W: Optional, AA: mod, CCC: R/M
|
||||
case S86_InstructionType_JMPIndirectWithinSeg: /*FALLTHRU*/
|
||||
case S86_InstructionType_CALLIndirectWithinSeg: /*FALLTHRU*/
|
||||
case S86_InstructionType_NOT: /*FALLTHRU*/
|
||||
case S86_InstructionType_SHL_SAL: /*FALLTHRU*/
|
||||
case S86_InstructionType_SHR: /*FALLTHRU*/
|
||||
@ -1098,6 +1147,21 @@ int main(int argc, char **argv)
|
||||
S86_PrintLnFmt(" %.*s%c", S86_STR8_FMT(string_type), w ? 'w' : 'b');
|
||||
} break;
|
||||
|
||||
// NOTE: Instruction Pattern => [0b000'00000 | DATA-LO | DATA-HI]
|
||||
case S86_InstructionType_CALLDirectWithinSeg: /*FALLTHRU*/
|
||||
case S86_InstructionType_RETWithinSegAddImmediateToSP: {
|
||||
S86_ASSERT(op_code_size == 1);
|
||||
uint8_t data_lo = S86_BufferIteratorNextByte(&buffer_it);
|
||||
uint8_t data_hi = S86_BufferIteratorNextByte(&buffer_it);
|
||||
int16_t data = S86_CAST(int16_t)(S86_CAST(uint16_t)data_hi << 8 | (S86_CAST(uint16_t)data_lo));
|
||||
|
||||
if (instruction_type == S86_InstructionType_CALLDirectWithinSeg) {
|
||||
S86_PrintLnFmt(" [bp - %d]", data);
|
||||
} else {
|
||||
S86_PrintLnFmt(" %d", data);
|
||||
}
|
||||
} break;
|
||||
|
||||
default: {
|
||||
if (instruction_type >= S86_InstructionType_JE_JZ && instruction_type <= S86_InstructionType_JCXZ) {
|
||||
S86_ASSERT(op_code_size == 1);
|
||||
@ -1122,7 +1186,8 @@ int main(int argc, char **argv)
|
||||
instruction_type == S86_InstructionType_AAM ||
|
||||
instruction_type == S86_InstructionType_AAD ||
|
||||
instruction_type == S86_InstructionType_CBW ||
|
||||
instruction_type == S86_InstructionType_CWD) {
|
||||
instruction_type == S86_InstructionType_CWD ||
|
||||
instruction_type == S86_InstructionType_RETWithinSeg) {
|
||||
// NOTE: Mnemonic instruction only, already printed
|
||||
S86_Print(S86_STR8("\n"));
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user