mirror of
https://github.com/zoriya/dasm.git
synced 2025-12-06 06:36:31 +00:00
Implement the int instruction
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@ setuptools
|
||||
._setuptools
|
||||
*.o
|
||||
dasm
|
||||
.vgcore*
|
||||
|
||||
3
Makefile
3
Makefile
@@ -23,3 +23,6 @@ fclean: clean
|
||||
$(RM) $(NAME)
|
||||
|
||||
re: fclean all
|
||||
|
||||
dbg: $(CFLAGS += -g)
|
||||
dbg: re
|
||||
|
||||
@@ -3,5 +3,6 @@ pkgs.mkShell {
|
||||
packages = with pkgs; [
|
||||
gcc
|
||||
gnumake
|
||||
valgrind
|
||||
];
|
||||
}
|
||||
|
||||
@@ -210,7 +210,7 @@ const instruction_t instructions[] = {
|
||||
{.opcode = 0xCA, .extended = -1, .name = "retf", .mode = {IMM16, END}, .exec = NULL},
|
||||
{.opcode = 0xCB, .extended = -1, .name = "retf", .mode = {END}, .exec = NULL},
|
||||
{.opcode = 0xCC, .extended = -1, .name = "int3", .mode = {END}, .exec = NULL},
|
||||
{.opcode = 0xCD, .extended = -1, .name = "int", .mode = {IMM8, END}, .exec = NULL},
|
||||
{.opcode = 0xCD, .extended = -1, .name = "int", .mode = {IMM8, END}, .exec = &int_inst},
|
||||
{.opcode = 0xCE, .extended = -1, .name = "into", .mode = {END}, .exec = NULL},
|
||||
{.opcode = 0xCF, .extended = -1, .name = "iret", .mode = {END}, .exec = NULL},
|
||||
{.opcode = 0xD0, .extended = 7, .name = "EXTENDED", .mode = {END}, .exec = NULL},
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
#include "interpretor.h"
|
||||
|
||||
void mov(const instruction_t *self, state_t *state);
|
||||
void int_inst(const instruction_t *self, state_t *state);
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include "../dasm.h"
|
||||
#include "../interpretor.h"
|
||||
#include "sys/types.h"
|
||||
|
||||
void mov(const instruction_t *self, state_t *state)
|
||||
{
|
||||
@@ -14,3 +17,38 @@ void mov(const instruction_t *self, state_t *state)
|
||||
else
|
||||
*(uint8_t *)from = *(uint8_t *)to;
|
||||
}
|
||||
|
||||
void int_inst(const instruction_t *self, state_t *state)
|
||||
{
|
||||
// I have no clue what the use of type is.
|
||||
// uint8_t type = *(uint8_t *)get_operand(self, 0, state);
|
||||
syscall_t *syscall = (syscall_t *)(state->memory + state->bx);
|
||||
uint8_t *args = state->memory + state->bx + sizeof(*syscall);
|
||||
|
||||
(void)self;
|
||||
|
||||
switch (syscall->type) {
|
||||
case 0x1:
|
||||
printf("<exit(%d)>\n", *args);
|
||||
exit(state->bx);
|
||||
case 0x2:
|
||||
printf("<fork() => %d>\n", 0);
|
||||
printf("Not implemented\n");
|
||||
break;
|
||||
case 0x4: {
|
||||
uint16_t fd = *(uint16_t *)args;
|
||||
uint16_t len = *((uint16_t *)args + 1);
|
||||
// the 2 args (a number is skiped.)
|
||||
uint16_t addr = *((uint16_t *)args + 3);
|
||||
printf("<write(%d, 0x%04x, %d)", fd, addr, len);
|
||||
fflush(stdout);
|
||||
int ret = write(fd, &state->memory[addr], len);
|
||||
printf(" => %d>\n", ret);
|
||||
state->ax = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf("Unimplemented syscall %02X\n", syscall->type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include "dasm.h"
|
||||
@@ -54,21 +55,21 @@ void *get_rm_operand(state_t *state, unsigned *imm_idx, bool is16bit)
|
||||
|
||||
switch (rm) {
|
||||
case 0x00:
|
||||
return state->binary + state->bx + state->si + disp;
|
||||
return state->memory + state->bx + state->si + disp;
|
||||
case 0x01:
|
||||
return state->binary + state->bx + state->di + disp;
|
||||
return state->memory + state->bx + state->di + disp;
|
||||
case 0x02:
|
||||
return state->binary + state->bp + state->si + disp;
|
||||
return state->memory + state->bp + state->si + disp;
|
||||
case 0x03:
|
||||
return state->binary + state->bp + state->di + disp;
|
||||
return state->memory + state->bp + state->di + disp;
|
||||
case 0x04:
|
||||
return state->binary + state->si + disp;
|
||||
return state->memory + state->si + disp;
|
||||
case 0x05:
|
||||
return state->binary + state->di + disp;
|
||||
return state->memory + state->di + disp;
|
||||
case 0x06:
|
||||
return state->binary + state->bp + disp;
|
||||
return state->memory + state->bp + disp;
|
||||
case 0x07:
|
||||
return state->binary + state->bx + disp;
|
||||
return state->memory + state->bx + disp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -169,19 +170,26 @@ int interpret(u_int8_t *binary, unsigned long size)
|
||||
{
|
||||
state_t *state = calloc(sizeof(*state), 1);
|
||||
int header_size = 0;
|
||||
int dsize= 0;
|
||||
|
||||
state->sp = 0xFFDC;
|
||||
|
||||
if (binary[0] == 0xEB && binary[1] == 0x0E) {
|
||||
header_size = 16;
|
||||
size = binary[2] | (binary[3] << 8);
|
||||
dsize = binary[4] | (binary[5] << 8);
|
||||
} else if (binary[0] == 0x01 && binary[1] == 0x03) {
|
||||
header_size = binary[4];
|
||||
size = binary[8] | (binary[9] << 8) | (binary[10] << 16) | (binary[11] << 24);
|
||||
dsize = binary[12] | (binary[13] << 8) | (binary[14] << 16) | (binary[15] << 24);
|
||||
}
|
||||
|
||||
binary += header_size;
|
||||
state->binary = binary;
|
||||
state->binary_size = size;
|
||||
|
||||
memcpy(state->memory, binary + size, dsize);
|
||||
|
||||
printf(" AX BX CX DX SP BP SI DI FLAGS IP\n");
|
||||
while (state->pc < size) {
|
||||
instruction_t inst = parse_inst(binary, size - state->pc);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define MEMORY_SIZE 65536
|
||||
|
||||
typedef struct state {
|
||||
union {
|
||||
struct {
|
||||
@@ -57,6 +59,8 @@ typedef struct state {
|
||||
uint8_t *binary;
|
||||
unsigned binary_size;
|
||||
|
||||
uint8_t memory[MEMORY_SIZE];
|
||||
|
||||
struct {
|
||||
unsigned imm_idx;
|
||||
// A bunch of unsigneds to store temporary operands and return them as pointers.
|
||||
@@ -64,3 +68,8 @@ typedef struct state {
|
||||
unsigned operand_holder[5];
|
||||
} parse_data;
|
||||
} state_t;
|
||||
|
||||
typedef struct {
|
||||
uint16_t source;
|
||||
uint16_t type;
|
||||
} syscall_t;
|
||||
|
||||
Reference in New Issue
Block a user