1-3 complete

This commit is contained in:
Hane 2026-01-28 17:19:32 +01:00
commit 53b4945844
5 changed files with 167 additions and 80 deletions

View file

@ -17,6 +17,48 @@
/* CMP = 0b111, */
/* } ARITHMETIC_OP; */
typedef enum COND_JMP_OPC
{
JX = 0b0111,
LOOPX = 0b1110'00,
} JMP_OPC;
typedef enum LOOPX_INST
{
LOOP = 0b10,
LOOPZ = 0b01,
LOOPNZ = 0b00,
JCXZ = 0b11
} LOOPX_INST;
#define LOOPX_INST_TXT_LEN 7
char LOOPX_INST_TXT[0b100][LOOPX_INST_TXT_LEN] = { "loopnz", "loopz", "loop", "jcxz" };
typedef enum JX_INST
{
JZ = 0b0100,
JL = 0b1100,
JLE = 0b1110,
JB = 0b0010,
JBE = 0b0110,
JP = 0b1010,
JO = 0b0000,
JS = 0b1000,
JNE = 0b0101,
JNL = 0b1101,
JNLE = 0b1111,
JNB = 0b0011,
JNBE = 0b0111,
JNP = 0b1011,
JNO = 0b0001,
JNS = 0b1001,
} JX_INST;
#define JX_INST_TXT_LEN 5
char JX_INST_TXT[0b10000][JX_INST_TXT_LEN] = { "jo", "jno", "jb", "jnb", "jz", "jne", "jbe", "jnbe",
"js", "jns", "jp", "jnp", "jl", "jnl", "jle", "jnle" };
typedef enum ARITHMETIC_OP
{
ADD = 0b000,
@ -351,7 +393,7 @@ int16_t calc_effective_disp(uint8_t high_order, uint8_t low_order, bool lo_only)
const uint8_t low_order_neg_mask = 0b1000'0000;
int16_t effective_disp = 0;
if (lo_only & ((low_order & low_order_neg_mask) >> 7))
if (lo_only && ((low_order & low_order_neg_mask) >> 7))
high_order = high_order | 0b1111'1111;
int8_t *effective_disp_high_order =(int8_t*) &(effective_disp) + 1;
memcpy(&(effective_disp), &low_order, 1);
@ -682,14 +724,14 @@ int ASC_I_RM_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_
effective_disp = calc_effective_disp(high_disp, low_disp, false);
low_data = payload[2];
if (is_wide)
if (is_wide && !is_sign)
{
high_data = payload[3];
effective_data = calc_effective_disp(high_data, low_data, false);
}
else
{
effective_data = calc_effective_disp(0, low_disp, true);
effective_data = calc_effective_disp(0, low_data, true);
}
fill_ea_string(&mem_data, EA_ENCODING_TXT[ea_table_value], effective_disp);
@ -828,6 +870,23 @@ int ASC_REGM_R_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int byte
return extra_bytes_read;
}
void JMP_parse(uint8_t byte1, uint8_t byte2, binary_data *binary, int bytes_read, JMP_OPC op)
{
const uint8_t loopx_mask = 0b0000'0011;
const uint8_t jx_mask = 0b0000'1111;
int8_t disp = 0;
memcpy(&disp, &byte2, sizeof(uint8_t));
uint8_t jump_op = (op == LOOPX) ? (byte1 & loopx_mask) : (byte1 & jx_mask);
char nasm_offset[4] = { "\0" };
if (!disp) strcpy(nasm_offset, "$+");
else strcpy(nasm_offset, "$+2");
//We have to add +2 to displacement so that NASM can parse displacements correctly
printf("%s %s%+d \n", (op == LOOPX) ? LOOPX_INST_TXT[jump_op] : JX_INST_TXT[jump_op], nasm_offset, disp);
fprintf(output, "%s %s%+d \n", (op == LOOPX) ? LOOPX_INST_TXT[jump_op] : JX_INST_TXT[jump_op], nasm_offset, disp);
}
int main(int argc, char** argv)
{
if (argc != 2) return -1;
@ -848,8 +907,9 @@ int main(int argc, char** argv)
fread(byte, sizeof(byte), 1, bin.binary);
uint8_t manip_inst = (uint8_t)byte[0];
uint8_t inst = (uint8_t)byte[0];
//First, we check for ASC.
//First, we check for ASC or JMPs.
manip_inst = (manip_inst >> 1);
if ((manip_inst & ASC_I_A_M) == ASC_I_A)
{
if (bytes_read >= bin.size) break;
@ -860,6 +920,15 @@ int main(int argc, char** argv)
continue;
}
manip_inst = (inst >> 2);
if (manip_inst == LOOPX)
{
if (bytes_read >= bin.size) break;
fread(byte, sizeof(byte), 1, bin.binary);
bytes_read++;
inst_byte2 = (uint8_t)byte[0];
JMP_parse(inst, inst_byte2, 0, 0, LOOPX);
continue;
}
if ((manip_inst & ASC_REGM_R_M) == ASC_REGM_R)
{
if (bytes_read >= bin.size) break;
@ -877,7 +946,17 @@ int main(int argc, char** argv)
inst_byte2 = (uint8_t)byte[0];
bytes_read += ASC_I_RM_parse(inst, inst_byte2, 0, 0);
continue;
}
}
manip_inst = (inst >> 4);
if (manip_inst == JX)
{
if (bytes_read >= bin.size) break;
fread(byte, sizeof(byte), 1, bin.binary);
bytes_read++;
inst_byte2 = (uint8_t)byte[0];
JMP_parse(inst, inst_byte2, 0, 0, JX);
continue;
}
//Then, we're checking for all MOV except segment registers
manip_inst = (inst >> 1);
switch (manip_inst)