Part01-02: More mov instructions being handled
This commit is contained in:
parent
6066e930db
commit
3b6381f981
35
asm_files/01-02-39.asm
Normal file
35
asm_files/01-02-39.asm
Normal file
@ -0,0 +1,35 @@
|
||||
; ========================================================================
|
||||
; LISTING 39
|
||||
; ========================================================================
|
||||
|
||||
bits 16
|
||||
|
||||
; Register-to-register
|
||||
mov si, bx
|
||||
mov dh, al
|
||||
|
||||
; 8-bit immediate-to-register
|
||||
mov cl, 12
|
||||
mov ch, -12
|
||||
|
||||
; 16-bit immediate-to-register
|
||||
mov cx, 12
|
||||
mov cx, -12
|
||||
mov dx, 3948
|
||||
mov dx, -3948
|
||||
|
||||
; Source address calculation
|
||||
mov al, [bx + si]
|
||||
mov bx, [bp + di]
|
||||
mov dx, [bp]
|
||||
|
||||
; Source address calculation plus 8-bit displacement
|
||||
mov ah, [bx + si + 4]
|
||||
|
||||
; Source address calculation plus 16-bit displacement
|
||||
mov al, [bx + si + 4999]
|
||||
|
||||
; Dest address calculation
|
||||
mov [bx + di], cx
|
||||
mov [bp + si], cl
|
||||
mov [bp], ch
|
26
asm_files/01-02-40.asm
Normal file
26
asm_files/01-02-40.asm
Normal file
@ -0,0 +1,26 @@
|
||||
; ========================================================================
|
||||
; LISTING 40
|
||||
; ========================================================================
|
||||
|
||||
bits 16
|
||||
|
||||
; Signed displacements
|
||||
mov ax, [bx + di - 37]
|
||||
mov [si - 300], cx
|
||||
mov dx, [bx - 32]
|
||||
|
||||
; Explicit sizes
|
||||
mov [bp + di], byte 7
|
||||
mov [di + 901], word 347
|
||||
|
||||
; Direct address
|
||||
mov bp, [5]
|
||||
mov bx, [3458]
|
||||
|
||||
; Memory-to-accumulator test
|
||||
mov ax, [2555]
|
||||
mov ax, [16]
|
||||
|
||||
; Accumulator-to-memory test
|
||||
mov [2554], ax
|
||||
mov [15], ax
|
215
decode.c
215
decode.c
@ -6,43 +6,53 @@
|
||||
|
||||
enum Instruction
|
||||
{
|
||||
INST_MOV = 0b10001000
|
||||
INST_MOV_REG_REG = 0b10001000,
|
||||
// INST_MOV_REG_REG = 0b10001000,
|
||||
// INST_MOV_REG_REG = 0b10001000,
|
||||
};
|
||||
|
||||
enum Mode
|
||||
{
|
||||
MODE_MEM_NOD = 0b00,
|
||||
MODE_MEM_08D = 0b01,
|
||||
MODE_MEM_16D = 0b10,
|
||||
MODE_REGMODE = 0b11,
|
||||
MODE_MEM_NO_DIS = 0b00,
|
||||
MODE_MEM_DIS_08 = 0b01,
|
||||
MODE_MEM_DIS_16 = 0b10,
|
||||
MODE_RGSTR_MODE = 0b11,
|
||||
};
|
||||
|
||||
typedef struct Register
|
||||
{
|
||||
char code;
|
||||
char *fullname;
|
||||
char *bytename;
|
||||
union {
|
||||
struct {
|
||||
char* fullname;
|
||||
char* bytename;
|
||||
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
char low;
|
||||
char high;
|
||||
};
|
||||
|
||||
u16 full;
|
||||
} value;
|
||||
} Register;
|
||||
|
||||
Register registers[8] = {
|
||||
{.code = 0b000, .fullname = "ax", .bytename = "al" },
|
||||
{.code = 0b001, .fullname = "cx", .bytename = "cl" },
|
||||
{.code = 0b010, .fullname = "dx", .bytename = "dl" },
|
||||
{.code = 0b011, .fullname = "bx", .bytename = "bl" },
|
||||
{.code = 0b100, .fullname = "sp", .bytename = "ah" },
|
||||
{.code = 0b101, .fullname = "bp", .bytename = "ch" },
|
||||
{.code = 0b110, .fullname = "si", .bytename = "dh" },
|
||||
{.code = 0b111, .fullname = "di", .bytename = "bh" },
|
||||
{.code = 0b000, .fullname = "ax", .bytename = "al"},
|
||||
{.code = 0b001, .fullname = "cx", .bytename = "cl"},
|
||||
{.code = 0b010, .fullname = "dx", .bytename = "dl"},
|
||||
{.code = 0b011, .fullname = "bx", .bytename = "bl"},
|
||||
{.code = 0b100, .fullname = "sp", .bytename = "ah"},
|
||||
{.code = 0b101, .fullname = "bp", .bytename = "ch"},
|
||||
{.code = 0b110, .fullname = "si", .bytename = "dh"},
|
||||
{.code = 0b111, .fullname = "di", .bytename = "bh"},
|
||||
};
|
||||
|
||||
int main(int argc, char **argv)
|
||||
char* memory[65536];
|
||||
|
||||
// void inst_mov_rgmm_reg()
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
@ -56,41 +66,166 @@ int main(int argc, char **argv)
|
||||
perror("fopen\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
size_t bytes_read = fread(buf, sizeof(*buf), ARRAY_SIZE(buf), f);
|
||||
size_t bytes_read;
|
||||
|
||||
printf("; Decoded 8086 Assembly Instructions\n\n");
|
||||
printf("bits 16\n\n");
|
||||
for (int i = 0; i < (int)bytes_read; i += 2)
|
||||
|
||||
while ((bytes_read = fread(buf, sizeof(char), 1, f)) > 0)
|
||||
{
|
||||
char low_byte = buf[i];
|
||||
char high_byte = buf[i+1];
|
||||
char w = low_byte & 0b00000001;
|
||||
char d = low_byte & 0b00000010;
|
||||
char mod = (high_byte & 0b11000000) >> 6;
|
||||
char reg = (high_byte & 0b00111000) >> 3;
|
||||
char r_m = (high_byte & 0b00000111);
|
||||
size_t reg_idx = reg;
|
||||
size_t r_m_idx = r_m;
|
||||
Register src_reg = d == 0 ? registers[reg_idx] : registers[r_m_idx];
|
||||
Register dst_reg = d == 0 ? registers[r_m_idx] : registers[reg_idx];
|
||||
switch (low_byte & 0b11111100)
|
||||
char inst = buf[0];
|
||||
// Instruction instruction = 0;
|
||||
// Register/memory to/from register
|
||||
if ((inst & ~0x3) == (char)0b10001000)
|
||||
{
|
||||
case INST_MOV:
|
||||
if (mod == MODE_REGMODE)
|
||||
// TODO: We should add some form of error handling here
|
||||
bytes_read = fread(buf, sizeof(char), 1, f);
|
||||
char next_byte = buf[0];
|
||||
char w = inst & 0b00000001;
|
||||
char d = inst & 0b00000010;
|
||||
char mod = (next_byte & 0b11000000) >> 6;
|
||||
char reg = (next_byte & 0b00111000) >> 3;
|
||||
char rm = (next_byte & 0b00000111);
|
||||
size_t reg_idx = reg;
|
||||
size_t rm_idx = rm;
|
||||
Register src_reg = d == 0 ? registers[reg_idx] : registers[rm_idx];
|
||||
Register dst_reg = d == 0 ? registers[rm_idx] : registers[reg_idx];
|
||||
if (mod == MODE_RGSTR_MODE)
|
||||
{
|
||||
if (w == 1)
|
||||
char* src_name = w == 1 ? src_reg.fullname : src_reg.bytename;
|
||||
char* dst_name = w == 1 ? dst_reg.fullname : dst_reg.bytename;
|
||||
printf("mov %s, %s", dst_name, src_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
// char* src_name = w == 1 ? src_reg.fullname : src_reg.bytename;
|
||||
char *dst_name;
|
||||
if (d)
|
||||
{
|
||||
printf("mov %s, %s", dst_reg.fullname, src_reg.fullname);
|
||||
dst_name = w == 1 ? dst_reg.fullname : dst_reg.bytename;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("mov %s, %s", dst_reg.bytename, src_reg.bytename);
|
||||
dst_name = w == 1 ? src_reg.fullname : src_reg.bytename;
|
||||
}
|
||||
char* src_name;
|
||||
switch (rm)
|
||||
{
|
||||
case 0b000:
|
||||
src_name = "bx + si";
|
||||
break;
|
||||
case 0b001:
|
||||
src_name = "bx + di";
|
||||
break;
|
||||
case 0b010:
|
||||
src_name = "bp + si";
|
||||
break;
|
||||
case 0b011:
|
||||
src_name = "bp + di";
|
||||
break;
|
||||
case 0b100:
|
||||
src_name = "si";
|
||||
break;
|
||||
case 0b101:
|
||||
src_name = "di";
|
||||
break;
|
||||
case 0b110:
|
||||
src_name = "bp";
|
||||
break;
|
||||
case 0b111:
|
||||
src_name = "bx";
|
||||
break;
|
||||
}
|
||||
if (mod == MODE_MEM_DIS_16)
|
||||
{
|
||||
bytes_read = fread(buf, sizeof(char), 2, f);
|
||||
i16 data = (i16)buf[1] << 8 | buf[0];
|
||||
if (d)
|
||||
{
|
||||
printf("mov %s, [%s + %d] ;(mod %d, w %d, d %d)", dst_name, src_name, data, mod, d, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("mov [%s], %s ;(mod %d, w %d, d %d)", src_name, dst_name, mod, d, w);
|
||||
}
|
||||
char disp_lo = buf[0];
|
||||
char disp_hi = buf[1];
|
||||
(void)disp_lo;
|
||||
(void)disp_hi;
|
||||
}
|
||||
else if (mod == MODE_MEM_DIS_08)
|
||||
{
|
||||
bytes_read = fread(buf, sizeof(char), 1, f);
|
||||
if (d)
|
||||
{
|
||||
printf("mov %s, [%s + %d] ;(mod %d, w %d, d %d)", dst_name, src_name, buf[0], mod, d, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("mov [%s], %s ;(mod %d, w %d, d %d)", src_name, dst_name, mod, d, w);
|
||||
}
|
||||
}
|
||||
else if (mod == MODE_MEM_NO_DIS)
|
||||
{
|
||||
if (d)
|
||||
{
|
||||
printf("mov %s, [%s] ;(mod %d, w %d, d %d)", dst_name, src_name, mod, d, w);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("mov [%s], %s ;(mod %d, w %d, d %d)", src_name, dst_name, mod, d, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
perror("Unrecognized Instruction\n");
|
||||
}
|
||||
// Immediate to register/memory
|
||||
else if ((inst & ~0x1) == (char)0b11000110)
|
||||
{
|
||||
printf("mov imm to reg/mem");
|
||||
}
|
||||
// Immediate to register
|
||||
else if ((inst & ~0xF) == (char)0b10110000)
|
||||
{
|
||||
char w = inst & 0b00001000;
|
||||
Register reg = registers[(size_t)inst & 0b00000111];
|
||||
char *reg_name = w == 0 ? reg.bytename : reg.fullname;
|
||||
if (w)
|
||||
{
|
||||
bytes_read = fread(buf, sizeof(char), 2, f);
|
||||
i16 data = (i16)buf[1] << 8 | buf[0];
|
||||
printf("mov %s, %hd ; Immediate to register", reg_name, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
bytes_read = fread(buf, sizeof(char), 1, f);
|
||||
printf("mov %s, %d ; Immediate to register", reg_name, (sbyte)buf[0]);
|
||||
}
|
||||
}
|
||||
// Memory to accumulator
|
||||
else if ((inst & ~0x1) == (char)0b10100000)
|
||||
{
|
||||
printf("mov mem to acc");
|
||||
}
|
||||
// Accumulator to memory
|
||||
else if ((inst & ~0x1) == (char)0b10100010)
|
||||
{
|
||||
printf("mov acc to mem");
|
||||
}
|
||||
// Register/memory to segment register
|
||||
else if (inst == (char)0b10001110)
|
||||
{
|
||||
printf("mov regmem to segreg");
|
||||
}
|
||||
// Segment register to register/memory
|
||||
else if (inst == (char)0b10001100)
|
||||
{
|
||||
printf("mov segreg to regmem");
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Unrecognized Instruction");
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user