Setup the inital stack

This commit is contained in:
2023-07-09 00:05:02 +09:00
parent f46715f4c1
commit a82d55c4ce
6 changed files with 95 additions and 19 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
#define FALLTHROUGHT __attribute__((fallthrough));
int dasm(u_int8_t *binary, unsigned long size);
int interpret(u_int8_t *binary, unsigned long size);
int interpret(u_int8_t *binary, unsigned long size, int argc, char **argv);
// typedef enum addressing_mode {
// /// Param is the data (MOV AL, ~68FE~)
+8 -8
View File
@@ -72,12 +72,12 @@ const instruction_t instructions[] = {
{.opcode = 0x2D, .extended = -1, .name = "sub", .mode = {OPREG16, IMM16, END}, .exec = &sub},
{.opcode = 0x2F, .extended = -1, .name = "das", .mode = {END}, .exec = NULL},
{.opcode = 0x30, .extended = -1, .name = "xor", .mode = {R_M8, REG8, END}, .exec = NULL},
{.opcode = 0x31, .extended = -1, .name = "xor", .mode = {R_M16, REG16, END}, .exec = NULL},
{.opcode = 0x32, .extended = -1, .name = "xor", .mode = {REG8, R_M8, END}, .exec = NULL},
{.opcode = 0x33, .extended = -1, .name = "xor", .mode = {REG16, R_M16, END}, .exec = NULL},
{.opcode = 0x34, .extended = -1, .name = "xor", .mode = {OPREG8, IMM8, END}, .exec = NULL},
{.opcode = 0x35, .extended = -1, .name = "xor", .mode = {OPREG16, IMM16, END}, .exec = NULL},
{.opcode = 0x30, .extended = -1, .name = "xor", .mode = {R_M8, REG8, END}, .exec = &xor_inst},
{.opcode = 0x31, .extended = -1, .name = "xor", .mode = {R_M16, REG16, END}, .exec = &xor_inst},
{.opcode = 0x32, .extended = -1, .name = "xor", .mode = {REG8, R_M8, END}, .exec = &xor_inst},
{.opcode = 0x33, .extended = -1, .name = "xor", .mode = {REG16, R_M16, END}, .exec = &xor_inst},
{.opcode = 0x34, .extended = -1, .name = "xor", .mode = {OPREG8, IMM8, END}, .exec = &xor_inst},
{.opcode = 0x35, .extended = -1, .name = "xor", .mode = {OPREG16, IMM16, END}, .exec = &xor_inst},
{.opcode = 0x37, .extended = -1, .name = "aaa", .mode = {END}, .exec = NULL},
{.opcode = 0x38, .extended = -1, .name = "cmp", .mode = {R_M8, REG8, END}, .exec = NULL},
@@ -264,7 +264,7 @@ const instruction_t extended[][8] = {
{.opcode = 0x03, .extended = -2, .name = "sbb", .mode = {R_M8, IMM8, END}, .exec = NULL},
{.opcode = 0x04, .extended = -2, .name = "and", .mode = {R_M8, IMM8, END}, .exec = NULL},
{.opcode = 0x05, .extended = -2, .name = "sub", .mode = {R_M8, IMM8, END}, .exec = &sub},
{.opcode = 0x06, .extended = -2, .name = "xor", .mode = {R_M8, IMM8, END}, .exec = NULL},
{.opcode = 0x06, .extended = -2, .name = "xor", .mode = {R_M8, IMM8, END}, .exec = &xor_inst},
{.opcode = 0x07, .extended = -2, .name = "cmp", .mode = {R_M8, IMM8, END}, .exec = NULL},
},
// 0x81 extended
@@ -275,7 +275,7 @@ const instruction_t extended[][8] = {
{.opcode = 0x03, .extended = -2, .name = "sbb", .mode = {R_M16, IMM16, END}, .exec = NULL},
{.opcode = 0x04, .extended = -2, .name = "and", .mode = {R_M16, IMM16, END}, .exec = NULL},
{.opcode = 0x05, .extended = -2, .name = "sub", .mode = {R_M16, IMM16, END}, .exec = &sub},
{.opcode = 0x06, .extended = -2, .name = "xor", .mode = {R_M16, IMM16, END}, .exec = NULL},
{.opcode = 0x06, .extended = -2, .name = "xor", .mode = {R_M16, IMM16, END}, .exec = &xor_inst},
{.opcode = 0x07, .extended = -2, .name = "cmp", .mode = {R_M16, IMM16, END}, .exec = NULL},
},
// 0x83 extended
+2
View File
@@ -8,4 +8,6 @@ void push(const instruction_t *self, state_t *state);
void call(const instruction_t *self, state_t *state);
void jmp(const instruction_t *self, state_t *state);
void int_inst(const instruction_t *self, state_t *state);
void sub(const instruction_t *self, state_t *state);
void xor_inst(const instruction_t *self, state_t *state);
+18
View File
@@ -18,3 +18,21 @@ void sub(const instruction_t *self, state_t *state)
state->zf = value == 0;
// TODO: Set AF and PF
}
void xor_inst(const instruction_t *self, state_t *state)
{
operand_t from = get_operand(self, 0, state);
operand_t to = get_operand(self, 1, state);
unsigned old = read_op(from);
unsigned minus = read_op(to);
unsigned value = old ^ minus;
write_op(from, value);
state->of = 0;
state->cf = 0;
state->sf = value & (is_operand_wide(self, 0) ? 0x8000 : 0x80);
state->zf = value == 0;
// TODO: Set PF
}
+64 -8
View File
@@ -68,6 +68,7 @@ operand_t get_rm_operand(state_t *state, unsigned *imm_idx, bool is16bit)
{
unsigned mod = state->binary[state->pc + 1] >> 6;
unsigned rm = state->binary[state->pc + 1] & 0b111;
unsigned disp = 0;
if (mod == 0b11)
return get_reg_operand(state, is16bit, rm);
@@ -79,11 +80,13 @@ operand_t get_rm_operand(state_t *state, unsigned *imm_idx, bool is16bit)
.type = is16bit ? BIT16 : BIT8
};
}
unsigned disp = read_op((operand_t){
.ptr = &state->binary[state->pc + state->parse_data.imm_idx],
.type = mod == 0b10 ? BIT16 : BIT8}
);
state->parse_data.imm_idx += mod == 0b10 ? 2 : 1;
if (mod == 0b10 || mod == 0b01) {
disp = read_op((operand_t){
.ptr = &state->binary[state->pc + state->parse_data.imm_idx],
.type = mod == 0b10 ? BIT16 : BIT8}
);
state->parse_data.imm_idx += mod == 0b10 ? 2 : 1;
}
operand_t ret = {.ptr = NULL, .type = is16bit ? BIT16 : BIT8};
switch (rm) {
@@ -228,14 +231,66 @@ void print_rm_value(state_t *state, instruction_t *inst)
printf("\n");
}
int interpret(u_int8_t *binary, unsigned long size)
void setup_env(state_t *state, int argc, char **args)
{
char *env = "PATH=/usr:/usr/bin";
uint16_t env_head;
uint16_t args_size = argc;
uint16_t addr[args_size];
uint16_t len = strlen(env);
len++;
for (int i = 0; i < args_size; ++i) {
len += strlen(args[i]);
len++;
}
if (len % 2) state->memory[--state->sp] = 0;
state->memory[--state->sp] = '\0';
for (int i = (strlen(env) - 1); i >= 0; --i) {
state->memory[--state->sp] = env[i];
}
env_head = state->sp;
int addr_i = 0;
for (int i = args_size - 1; i >= 0; --i) {
state->memory[--state->sp] = '\0';
for (int j = strlen(args[i]) - 1; j >= 0; --j) {
state->memory[--state->sp] = args[i][j];
}
addr[addr_i++] = state->sp;
}
// Delimiter between char and env pointer
state->memory[--state->sp] = 0;
state->memory[--state->sp] = 0;
// add env address
state->memory[--state->sp] = env_head >> 8;
state->memory[--state->sp] = env_head;
// Delimiter between char and env pointer
state->memory[--state->sp] = 0;
state->memory[--state->sp] = 0;
// add args address
for (int i = 0; i < args_size; ++i) {
state->memory[--state->sp] = addr[i] >> 8;
state->memory[--state->sp] = addr[i];
}
state->memory[--state->sp] = args_size >> 8;
state->memory[--state->sp] = args_size;
}
int interpret(u_int8_t *binary, unsigned long size, int argc, char **argv)
{
state_t *state = calloc(sizeof(*state), 1);
int header_size = 0;
int dsize= 0;
state->sp = 0xFFC0;
if (binary[0] == 0xEB && binary[1] == 0x0E) {
header_size = 16;
size = binary[2] | (binary[3] << 8);
@@ -251,6 +306,7 @@ int interpret(u_int8_t *binary, unsigned long size)
state->binary_size = size;
memcpy(state->memory, binary + size, dsize);
setup_env(state, argc, argv);
printf(" AX BX CX DX SP BP SI DI FLAGS IP\n");
while (state->pc < size) {
+2 -2
View File
@@ -33,7 +33,7 @@ unsigned long open_and_read(char *path, u_int8_t **out)
int main(int argc, char **argv)
{
if (argc != 3 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-i"))) {
if (argc < 3 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-i"))) {
printf("Usage:\n\tTo disassemble: %s -d <binary>\n\tTo interpret: %s -i <binary>\n", argv[0], argv[0]);
return 2;
}
@@ -50,7 +50,7 @@ int main(int argc, char **argv)
return 2;
}
int ret = strcmp(argv[1], "-i") ? dasm(binary, size) : interpret(binary, size);
int ret = strcmp(argv[1], "-i") ? dasm(binary, size) : interpret(binary, size, argc - 2, argv + 2);
free(binary);
return ret;
}