mov_inst and add_inst procedures to avoid too much nesting
This commit is contained in:
parent
08753ea330
commit
20d1aed742
1
.gitignore
vendored
1
.gitignore
vendored
@ -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
109
asm_files/01-03-41.asm
Normal 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
155
decode.c
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
implicit_use_general_registers.png
Normal file
BIN
implicit_use_general_registers.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
Loading…
x
Reference in New Issue
Block a user