mov_inst and add_inst procedures to avoid too much nesting

This commit is contained in:
Joseph Ferano 2024-01-15 20:16:01 +07:00
parent 08753ea330
commit 20d1aed742
4 changed files with 269 additions and 92 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/decode /decode
/.idea/ /.idea/
/asm_files/*.bin /asm_files/*.bin
/8086_family_Users_Manual_1_.pdf

109
asm_files/01-03-41.asm Normal file
View File

@ -0,0 +1,109 @@
; ========================================================================
; LISTING 41
; ========================================================================
bits 16
add bx, [bx + si]
add bx, [bp]
add si, 2
add bp, 2
add cx, 8
add bx, [bp + 0]
add cx, [bx + 2]
add bh, [bp + si + 4]
add di, [bp + di + 6]
add [bx + si], bx
add [bp], bx
add [bp + 0], bx
add [bx + 2], cx
add [bp + si + 4], bh
add [bp + di + 6], di
add byte [bx], 34
add word [bp + si + 1000], 29
add ax, [bp]
add al, [bx + si]
add ax, bx
add al, ah
add ax, 1000
add al, -30
add al, 9
sub bx, [bx + si]
sub bx, [bp]
sub si, 2
sub bp, 2
sub cx, 8
sub bx, [bp + 0]
sub cx, [bx + 2]
sub bh, [bp + si + 4]
sub di, [bp + di + 6]
sub [bx+si], bx
sub [bp], bx
sub [bp + 0], bx
sub [bx + 2], cx
sub [bp + si + 4], bh
sub [bp + di + 6], di
sub byte [bx], 34
sub word [bx + di], 29
sub ax, [bp]
sub al, [bx + si]
sub ax, bx
sub al, ah
sub ax, 1000
sub al, -30
sub al, 9
cmp bx, [bx + si]
cmp bx, [bp]
cmp si, 2
cmp bp, 2
cmp cx, 8
cmp bx, [bp + 0]
cmp cx, [bx + 2]
cmp bh, [bp + si + 4]
cmp di, [bp + di + 6]
cmp [bx + si], bx
cmp [bp], bx
cmp [bp + 0], bx
cmp [bx + 2], cx
cmp [bp + si + 4], bh
cmp [bp + di + 6], di
cmp byte [bx], 34
cmp word [4834], 29
cmp ax, [bp]
cmp al, [bx + si]
cmp ax, bx
cmp al, ah
cmp ax, 1000
cmp al, -30
cmp al, 9
test_label0:
jnz test_label1
jnz test_label0
test_label1:
jnz test_label0
jnz test_label1
label:
je label
jl label
jle label
jb label
jbe label
jp label
jo label
js label
jne label
jnl label
jg label
jnb label
ja label
jnp label
jno label
jns label
loop label
loopz label
loopnz label
jcxz label

155
decode.c
View File

@ -100,30 +100,9 @@ static inline i16 get_data(unsigned char* buf, char wide)
return wide == 1 ? (i16)buf[1] << 8 | buf[0] : (sbyte)buf[0]; return wide == 1 ? (i16)buf[1] << 8 | buf[0] : (sbyte)buf[0];
} }
int main(int argc, char** argv) bool mov_inst(FILE* f, unsigned char* buf, char inst)
{ {
if (argc < 2)
{
printf("Usage: Please provide assembled instructions as input\n");
exit(0);
}
unsigned char buf[256];
FILE *f = fopen(argv[1], "r");
if (!f)
{
perror("fopen\n");
return EXIT_FAILURE;
}
size_t bytes_read; size_t bytes_read;
printf("; Decoded 8086 Assembly Instructions\n\n");
printf("bits 16\n\n");
while ((bytes_read = fread(buf, sizeof(char), 1, f)) > 0)
{
char inst = buf[0];
// Instruction instruction = 0;
// Register/memory to/from register // Register/memory to/from register
if ((inst & ~0x3) == (char)0b10001000) if ((inst & ~0x3) == (char)0b10001000)
{ {
@ -135,12 +114,10 @@ int main(int argc, char** argv)
char mod = (next_byte & 0b11000000) >> 6; char mod = (next_byte & 0b11000000) >> 6;
char reg = (next_byte & 0b00111000) >> 3; char reg = (next_byte & 0b00111000) >> 3;
char rm = (next_byte & 0b00000111); char rm = (next_byte & 0b00000111);
size_t reg_idx = reg;
size_t rm_idx = rm;
if (mod == MODE_RGSTR_MODE) if (mod == MODE_RGSTR_MODE)
{ {
Register src_reg = d == 0 ? registers[reg_idx] : registers[rm_idx]; Register src_reg = d == 0 ? registers[(size_t)reg] : registers[(size_t)rm];
Register dst_reg = d == 0 ? registers[rm_idx] : registers[reg_idx]; Register dst_reg = d == 0 ? registers[(size_t)rm] : registers[(size_t)reg];
printf("mov %s, %s ;0", reg_name(dst_reg, w), reg_name(src_reg, w)); printf("mov %s, %s ;0", reg_name(dst_reg, w), reg_name(src_reg, w));
} }
else else
@ -158,7 +135,7 @@ int main(int argc, char** argv)
if (is_direct_addr) sprintf(disp_buf, "%d", abs(disp)); if (is_direct_addr) sprintf(disp_buf, "%d", abs(disp));
else sprintf(disp_buf, " %s %d", disp >= 0 ? "+" : "-", abs(disp)); else sprintf(disp_buf, " %s %d", disp >= 0 ? "+" : "-", abs(disp));
} }
Register rgstr = registers[reg_idx]; Register rgstr = registers[(size_t)reg];
if (d) printf("mov %s, [%s%s] ;1", reg_name(rgstr, w), eac_name, disp_buf); if (d) printf("mov %s, [%s%s] ;1", reg_name(rgstr, w), eac_name, disp_buf);
else printf("mov [%s%s], %s ;2", eac_name, disp_buf, reg_name(rgstr, w)); else printf("mov [%s%s], %s ;2", eac_name, disp_buf, reg_name(rgstr, w));
} }
@ -189,33 +166,123 @@ int main(int argc, char** argv)
Register reg = registers[(size_t)inst & 0b00000111]; Register reg = registers[(size_t)inst & 0b00000111];
char bytes_to_read = w == 1 ? 2 : 1; char bytes_to_read = w == 1 ? 2 : 1;
bytes_read = fread(buf, sizeof(char), bytes_to_read, f); bytes_read = fread(buf, sizeof(char), bytes_to_read, f);
printf("mov %s, %hd ;4", reg_name(reg, w), get_data(buf, w)); printf("mov %s, %d ;4", reg_name(reg, w), get_data(buf, w));
} }
// Memory to accumulator // Memory/accumulator to accumulator/memory
else if ((inst & ~0x1) == (char)0b10100000) else if ((inst & ~0x3) == (char)0b10100000)
{ {
printf("mov mem to acc"); // This instruction uses AX/AL register exclusively
Register ax_al = registers[0];
char w = (inst & 0b00000001);
// The manual doesn't refer to this as `d` but it acts similarly in that this bit
// swaps the accumulator's src/dst position
char d = (inst & 0b00000010) >> 1;
char bytes_to_read = w == 1 ? 2 : 1;
bytes_read = fread(buf, sizeof(char), bytes_to_read, f);
if (d) printf("mov [%d], %s ;5", get_data(buf, w), reg_name(ax_al, w));
else printf("mov %s, [%d] ;6", reg_name(ax_al, w), get_data(buf, w));
} }
// Accumulator to memory // Register/memory to segment register or segment register to register/memory
else if ((inst & ~0x1) == (char)0b10100010) else if ((inst & ~0x3) == (char)0b10001100)
{
printf("mov acc to mem");
}
// Register/memory to segment register
else if (inst == (char)0b10001110)
{ {
// Manual doesn't refer to this as `d` but swaps like in the previous instruction
char d = (inst & 0b00000010) >> 1;
(void)d;
printf("mov regmem to segreg"); printf("mov regmem to segreg");
} }
// Segment register to register/memory
else if (inst == (char)0b10001100)
{
printf("mov segreg to regmem");
}
else else
{ {
fprintf(stderr, "Unrecognized Instruction"); return false;
}
return bytes_read > 0;
}
bool add_inst(FILE* f, unsigned char* buf, char inst)
{
size_t bytes_read;
if ((inst & ~0x3) == (char)0b00000000)
{
bytes_read = fread(buf, sizeof(char), 1, f);
char next_byte = buf[0];
char w = inst & 0b00000001;
char d = (inst & 0b00000010) >> 1;
char mod = (next_byte & 0b11000000) >> 6;
char reg = (next_byte & 0b00111000) >> 3;
char rm = (next_byte & 0b00000111);
// Same trick from earlier, see comment
int bytes_to_read = mod % 3;
if (bytes_to_read > 0) bytes_read = fread(buf, sizeof(char), bytes_to_read, f);
Register rgstr = registers[(size_t)reg];
(void)rm;
if (mod == MODE_RGSTR_MODE)
{
if (d) printf("add %s, [%d] ;7", reg_name(rgstr, w), get_data(buf, w));
else printf("add [%d], %s ;8", get_data(buf, w), reg_name(rgstr, w));
}
else if (mod == MODE_MEM_NO_DIS)
{
if (d) printf("add %s, [%s] ;9", reg_name(rgstr, w), get_eac_registers(rm));
else printf("add [%s], %s ;10", get_eac_registers(rm), reg_name(rgstr, w));
}
else
{
if (d) printf("add %s, [%s] ;11", reg_name(rgstr, w), get_eac_registers(rm));
else printf("add [%s], %s ;12", get_eac_registers(rm), reg_name(rgstr, w));
}
}
else if ((inst & ~0x3) == (char)0b10000000)
{
bytes_read = fread(buf, sizeof(char), 1, f);
char w = inst & 0b00000001;
char mod = (buf[0] & 0b11000000) >> 6;
char rm = (buf[0] & 0b00000111);
int bytes_to_read = 1;
bytes_to_read += w == 0 ? 1 : 2;
// Same trick from earlier, see comment
bytes_to_read += mod % 3;
bytes_read = fread(buf, sizeof(char), bytes_to_read, f);
char *eac_name = get_eac_registers(rm);
i16 data = get_data(buf + (char)bytes_to_read - (w == 0 ? 1 : 2), w);
char *word_str = w == 0 ? "byte" : "word";
char disp_str[16] = {'\0'};
if (mod % 3 > 1) sprintf(disp_str, " + %d", get_data(buf, (mod % 3) - 1));
printf("add [%s%s], %s %d ;13", eac_name, disp_str, word_str, data);
}
else
{
return false;
}
return bytes_read > 0;
}
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("Usage: Please provide assembled instructions as input\n");
exit(0);
}
unsigned char buf[256];
FILE *f = fopen(argv[1], "r");
if (!f)
{
perror("fopen\n");
return EXIT_FAILURE;
} }
size_t bytes_read;
printf("; Decoded 8086 Assembly Instructions\n\n");
printf("bits 16\n\n");
while ((bytes_read = fread(buf, sizeof(char), 1, f)) > 0)
{
char inst = buf[0];
if (mov_inst(f, buf, inst)) goto handled;
if (add_inst(f, buf, inst)) goto handled;
fprintf(stderr, "___Unrecognized Instruction___");
handled:
printf("\n"); printf("\n");
} }
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB