Completed homework for decoding add, sub, cmp and jump instructions
This commit is contained in:
parent
620f9e0daa
commit
b3eb9b99c7
7
8086_assembly_03/.gitignore
vendored
Normal file
7
8086_assembly_03/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
dasm
|
||||
listing_0039_more_movs
|
||||
listing_0039_more_movs_out
|
||||
listing_0040_challenge_movs
|
||||
listing_0040_challenge_movs_out
|
||||
listing_0041_add_sub_cmp_jnz
|
||||
listing_0041_add_sub_cmp_jnz_out
|
2
8086_assembly_03/Makefile
Normal file
2
8086_assembly_03/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
all:
|
||||
clang++ -g dasm.cpp -o dasm
|
557
8086_assembly_03/dasm.cpp
Normal file
557
8086_assembly_03/dasm.cpp
Normal file
@ -0,0 +1,557 @@
|
||||
#include <bits/types/FILE.h>
|
||||
#include <math.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ARRAY_LEN(ARR) (sizeof(ARR) / sizeof(*ARR))
|
||||
|
||||
enum class INST_BITS {
|
||||
ADD_REG_MEM_REG = 0x00,
|
||||
SUB_REG_MEM_REG = 0x28,
|
||||
CMP_REG_MEM_REG = 0x38,
|
||||
MOV_REG_MEM_REG = 0x88,
|
||||
ADD_IMM_TO_ACC = 0x04,
|
||||
SUB_IMM_FROM_ACC = 0x2c,
|
||||
CMP_IMM_WITH_ACC = 0x3c,
|
||||
MOV_MEM_TO_ACC = 0xa0,
|
||||
MOV_ACC_TO_MEM = 0xa2,
|
||||
MOV_IMM_TO_REG = 0xb0,
|
||||
MOV_IMM_TO_REG_MEM = 0xc6,
|
||||
ARITHMETIC_IMM_TO_REG_MEM = 0x80,
|
||||
JE = 0x74,
|
||||
JL = 0x7c,
|
||||
JLE = 0x7e,
|
||||
JB = 0x72,
|
||||
JBE = 0x76,
|
||||
JP = 0x7a,
|
||||
JO = 0x70,
|
||||
JS = 0x78,
|
||||
JNE_JNZ = 0x75,
|
||||
JNL = 0x7d,
|
||||
JG = 0x7f,
|
||||
JNB = 0x73,
|
||||
JA = 0x77,
|
||||
JNP = 0x7b,
|
||||
JNO = 0x71,
|
||||
JNS = 0x79,
|
||||
LOOP = 0xe2,
|
||||
LOOPZ = 0xe1,
|
||||
LOOPNZ = 0xe0,
|
||||
JCXZ = 0xe3,
|
||||
};
|
||||
|
||||
uint8_t reg_mem_reg_insts[] = {
|
||||
(uint8_t)INST_BITS::ADD_REG_MEM_REG,
|
||||
(uint8_t)INST_BITS::SUB_REG_MEM_REG,
|
||||
(uint8_t)INST_BITS::CMP_REG_MEM_REG,
|
||||
(uint8_t)INST_BITS::MOV_REG_MEM_REG,
|
||||
};
|
||||
|
||||
uint8_t to_accumulator_insts[] = {
|
||||
(uint8_t)INST_BITS::MOV_MEM_TO_ACC,
|
||||
(uint8_t)INST_BITS::ADD_IMM_TO_ACC,
|
||||
(uint8_t)INST_BITS::SUB_IMM_FROM_ACC,
|
||||
(uint8_t)INST_BITS::CMP_IMM_WITH_ACC,
|
||||
};
|
||||
|
||||
uint8_t jump_insts[] = {
|
||||
(uint8_t)INST_BITS::JE, (uint8_t)INST_BITS::JL,
|
||||
(uint8_t)INST_BITS::JLE, (uint8_t)INST_BITS::JB,
|
||||
(uint8_t)INST_BITS::JBE, (uint8_t)INST_BITS::JP,
|
||||
(uint8_t)INST_BITS::JO, (uint8_t)INST_BITS::JS,
|
||||
(uint8_t)INST_BITS::JNE_JNZ, (uint8_t)INST_BITS::JNL,
|
||||
(uint8_t)INST_BITS::JG, (uint8_t)INST_BITS::JNB,
|
||||
(uint8_t)INST_BITS::JA, (uint8_t)INST_BITS::JNP,
|
||||
(uint8_t)INST_BITS::JNO, (uint8_t)INST_BITS::JNS,
|
||||
(uint8_t)INST_BITS::LOOP, (uint8_t)INST_BITS::LOOPZ,
|
||||
(uint8_t)INST_BITS::LOOPNZ, (uint8_t)INST_BITS::JCXZ,
|
||||
};
|
||||
|
||||
enum class ARITHMETIC {
|
||||
ADD = 0x00,
|
||||
SUB = 0x28,
|
||||
CMP = 0x38,
|
||||
};
|
||||
|
||||
enum class INST_MASKS {
|
||||
REG_MEM_REG = 0xfc,
|
||||
IMM_TO_REG = 0xf0,
|
||||
MOV_IMM_TO_REG_MEM = 0xfe,
|
||||
ARITHMETIC_IMM_TO_REG_MEM = 0xfc,
|
||||
ACCUMULATOR = 0xfe,
|
||||
ARITHMETIC = 0x38,
|
||||
JUMPS = 0xff,
|
||||
};
|
||||
|
||||
enum class MODE {
|
||||
MEM = 0x00,
|
||||
MEM8 = 0x40,
|
||||
MEM16 = 0x80,
|
||||
REG = 0xc0,
|
||||
};
|
||||
|
||||
bool mask_instruction(uint8_t instruction, uint8_t inst_bits, uint8_t mask);
|
||||
bool instruction_in_array(uint8_t inst, uint8_t *instructions, size_t arr_size,
|
||||
uint8_t mask);
|
||||
uint8_t get_instruction_from_array(uint8_t inst, uint8_t *instructions,
|
||||
size_t arr_size, uint8_t mask);
|
||||
void decode_register(uint8_t instruction, bool word, char *dest);
|
||||
void decode_rm(uint8_t instruction, char *dest);
|
||||
void stringify_rm_and_disp(FILE *fp, uint8_t operands, char *rm,
|
||||
uint32_t buff_size);
|
||||
void handle_accumulator_mov_instructions(FILE *fp, uint8_t inst, bool reg_dest,
|
||||
char *dest);
|
||||
void handle_accumulator_arithmetic_instructions(FILE *fp, uint8_t inst,
|
||||
char *dest);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Please provide a file to disassemble\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *filename = argv[1];
|
||||
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
|
||||
if (fp) {
|
||||
uint8_t inst = 0;
|
||||
const char *op = "";
|
||||
|
||||
char out_filename[4096] = {0};
|
||||
sprintf(out_filename, "%s_out.asm", filename);
|
||||
|
||||
FILE *out = fopen(out_filename, "w");
|
||||
|
||||
if (out) {
|
||||
fprintf(out, "; Disassembled by DASM\n\nbits 16\n\n");
|
||||
|
||||
while (fread(&inst, sizeof(inst), 1, fp)) {
|
||||
if (instruction_in_array(inst, reg_mem_reg_insts,
|
||||
ARRAY_LEN(reg_mem_reg_insts),
|
||||
(uint8_t)INST_MASKS::REG_MEM_REG)) {
|
||||
switch (get_instruction_from_array(
|
||||
inst, reg_mem_reg_insts, ARRAY_LEN(reg_mem_reg_insts),
|
||||
(uint8_t)INST_MASKS::REG_MEM_REG)) {
|
||||
case (uint8_t)INST_BITS::MOV_REG_MEM_REG:
|
||||
op = "mov";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::ADD_REG_MEM_REG:
|
||||
op = "add";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::SUB_REG_MEM_REG:
|
||||
op = "sub";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::CMP_REG_MEM_REG:
|
||||
op = "cmp";
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t operands = 0;
|
||||
fread(&operands, sizeof(operands), 1, fp);
|
||||
|
||||
bool reg_dest = mask_instruction(inst, 0x02, 0x02);
|
||||
|
||||
bool word = mask_instruction(inst, 0x01, 0x01);
|
||||
|
||||
char reg[3] = {0};
|
||||
decode_register(operands >> 3, word, reg);
|
||||
|
||||
if (mask_instruction(operands, (uint8_t)MODE::REG,
|
||||
(uint8_t)MODE::REG)) {
|
||||
char rm[3] = {0};
|
||||
decode_register(operands, word, rm);
|
||||
|
||||
fprintf(out, "%s %s, %s\n", op, reg_dest ? reg : rm,
|
||||
reg_dest ? rm : reg);
|
||||
} else {
|
||||
char rm[20] = {0};
|
||||
stringify_rm_and_disp(fp, operands, rm, 20);
|
||||
|
||||
fprintf(out, reg_dest ? "%s %s, [%s]\n" : "%s [%s], %s\n", op,
|
||||
reg_dest ? reg : rm, reg_dest ? rm : reg);
|
||||
}
|
||||
} else if (mask_instruction(inst, (uint8_t)INST_BITS::MOV_IMM_TO_REG,
|
||||
(uint8_t)INST_MASKS::IMM_TO_REG)) {
|
||||
op = "mov";
|
||||
|
||||
// Bit pattern is:
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// -------------------------------
|
||||
// | 1 | 0 | 1 | 1 | w | reg |
|
||||
// -------------------------------
|
||||
//
|
||||
// So, we need to mask the fourth bit to check the w flag
|
||||
bool word = mask_instruction(inst, 0x08, 0x08);
|
||||
|
||||
uint8_t next_bytes = word ? 2 : 1;
|
||||
|
||||
char reg[3] = {0};
|
||||
|
||||
decode_register(inst, word, reg);
|
||||
|
||||
int16_t data = 0;
|
||||
|
||||
fread(&data, sizeof(next_bytes), next_bytes, fp);
|
||||
|
||||
fprintf(out, "%s %s, %d\n", op, reg, word ? data : (int8_t)data);
|
||||
} else if (mask_instruction(inst,
|
||||
(uint8_t)INST_BITS::MOV_IMM_TO_REG_MEM,
|
||||
(uint8_t)INST_MASKS::MOV_IMM_TO_REG_MEM)) {
|
||||
op = "mov";
|
||||
|
||||
uint8_t operands = 0;
|
||||
fread(&operands, sizeof(operands), 1, fp);
|
||||
|
||||
// Instruction bit pattern is:
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// -------------------------------
|
||||
// | 1 | 1 | 0 | 0 | 0 | 1 | 1 | w |
|
||||
// -------------------------------
|
||||
//
|
||||
// Operands bit pattern is:
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// -------------------------------
|
||||
// | mod | 000 | r/m |
|
||||
// -------------------------------
|
||||
|
||||
bool word = mask_instruction(inst, 0x01, 0x01);
|
||||
|
||||
char rm[20] = {0};
|
||||
stringify_rm_and_disp(fp, operands, rm, 20);
|
||||
|
||||
uint8_t next_bytes = word ? 2 : 1;
|
||||
|
||||
int16_t data = 0;
|
||||
fread(&data, sizeof(next_bytes), next_bytes, fp);
|
||||
|
||||
fprintf(out, "%s [%s], %s %d\n", op, rm, word ? "word" : "byte",
|
||||
word ? data : (int8_t)data);
|
||||
} else if (mask_instruction(
|
||||
inst, (uint8_t)INST_BITS::ARITHMETIC_IMM_TO_REG_MEM,
|
||||
(uint8_t)INST_MASKS::ARITHMETIC_IMM_TO_REG_MEM)) {
|
||||
uint8_t operands = 0;
|
||||
fread(&operands, sizeof(operands), 1, fp);
|
||||
|
||||
if (mask_instruction(operands, (uint8_t)ARITHMETIC::ADD,
|
||||
(uint8_t)INST_MASKS::ARITHMETIC)) {
|
||||
op = "add";
|
||||
} else if (mask_instruction(operands, (uint8_t)ARITHMETIC::SUB,
|
||||
(uint8_t)INST_MASKS::ARITHMETIC)) {
|
||||
op = "sub";
|
||||
} else if (mask_instruction(operands, (uint8_t)ARITHMETIC::CMP,
|
||||
(uint8_t)INST_MASKS::ARITHMETIC)) {
|
||||
op = "cmp";
|
||||
}
|
||||
|
||||
bool word = mask_instruction(inst, 0x01, 0x01);
|
||||
bool sign = mask_instruction(inst, 0x02, 0x02);
|
||||
|
||||
if (mask_instruction(operands, (uint8_t)MODE::REG,
|
||||
(uint8_t)MODE::REG)) {
|
||||
char rm[3] = {0};
|
||||
decode_register(operands, word, rm);
|
||||
|
||||
uint8_t next_bytes = 0;
|
||||
|
||||
if ((!word && !sign) || (word && sign)) {
|
||||
next_bytes = 1;
|
||||
} else if (word && !sign) {
|
||||
next_bytes = 2;
|
||||
}
|
||||
|
||||
int16_t data = 0;
|
||||
fread(&data, sizeof(next_bytes), next_bytes, fp);
|
||||
|
||||
fprintf(out, "%s %s, %d\n", op, rm,
|
||||
next_bytes == 1 ? (int8_t)data : data);
|
||||
} else {
|
||||
char rm[20] = {0};
|
||||
stringify_rm_and_disp(fp, operands, rm, 20);
|
||||
|
||||
uint8_t next_bytes = 0;
|
||||
|
||||
if ((!word && !sign) || (word && sign)) {
|
||||
next_bytes = 1;
|
||||
} else if (word && !sign) {
|
||||
next_bytes = 2;
|
||||
}
|
||||
|
||||
int16_t data = 0;
|
||||
fread(&data, sizeof(next_bytes), next_bytes, fp);
|
||||
|
||||
fprintf(out, "%s %s [%s], %d\n", op, word ? "word" : "byte", rm,
|
||||
next_bytes == 1 ? (int8_t)data : data);
|
||||
}
|
||||
} else if (instruction_in_array(inst, to_accumulator_insts,
|
||||
ARRAY_LEN(to_accumulator_insts),
|
||||
(uint8_t)INST_MASKS::ACCUMULATOR)) {
|
||||
char inst_out[256] = {0};
|
||||
|
||||
switch (get_instruction_from_array(
|
||||
inst, to_accumulator_insts, ARRAY_LEN(to_accumulator_insts),
|
||||
(uint8_t)INST_MASKS::ACCUMULATOR)) {
|
||||
case (uint8_t)INST_BITS::MOV_MEM_TO_ACC:
|
||||
handle_accumulator_mov_instructions(fp, inst, true, inst_out);
|
||||
break;
|
||||
case (uint8_t)INST_BITS::ADD_IMM_TO_ACC:
|
||||
handle_accumulator_arithmetic_instructions(fp, inst, inst_out);
|
||||
break;
|
||||
case (uint8_t)INST_BITS::SUB_IMM_FROM_ACC:
|
||||
handle_accumulator_arithmetic_instructions(fp, inst, inst_out);
|
||||
break;
|
||||
case (uint8_t)INST_BITS::CMP_IMM_WITH_ACC:
|
||||
handle_accumulator_arithmetic_instructions(fp, inst, inst_out);
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(out, "%s\n", inst_out);
|
||||
} else if (mask_instruction(inst, (uint8_t)INST_BITS::MOV_ACC_TO_MEM,
|
||||
(uint8_t)INST_MASKS::ACCUMULATOR)) {
|
||||
char inst_out[256] = {0};
|
||||
handle_accumulator_mov_instructions(fp, inst, false, inst_out);
|
||||
|
||||
fprintf(out, "%s\n", inst_out);
|
||||
} else if (instruction_in_array(inst, jump_insts, ARRAY_LEN(jump_insts),
|
||||
(uint8_t)INST_MASKS::JUMPS)) {
|
||||
switch (get_instruction_from_array(inst, jump_insts,
|
||||
ARRAY_LEN(jump_insts),
|
||||
(uint8_t)INST_MASKS::JUMPS)) {
|
||||
case (uint8_t)INST_BITS::JE:
|
||||
op = "je";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JL:
|
||||
op = "jl";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JLE:
|
||||
op = "jle";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JB:
|
||||
op = "jb";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JBE:
|
||||
op = "jbe";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JP:
|
||||
op = "jp";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JO:
|
||||
op = "jo";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JS:
|
||||
op = "js";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JNE_JNZ:
|
||||
op = "jnz";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JNL:
|
||||
op = "jnl";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JG:
|
||||
op = "jg";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JNB:
|
||||
op = "jnb";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JA:
|
||||
op = "ja";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JNP:
|
||||
op = "jnp";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JNO:
|
||||
op = "jno";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JNS:
|
||||
op = "jns";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::LOOP:
|
||||
op = "loop";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::LOOPZ:
|
||||
op = "loopz";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::LOOPNZ:
|
||||
op = "loopnz";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::JCXZ:
|
||||
op = "jcxz";
|
||||
break;
|
||||
}
|
||||
|
||||
int8_t inc = 0;
|
||||
fread(&inc, sizeof(int8_t), 1, fp);
|
||||
|
||||
fprintf(out, "%s %d\n", op, inc);
|
||||
} else {
|
||||
printf("Invalid instruction\n");
|
||||
}
|
||||
}
|
||||
|
||||
fclose(out);
|
||||
} else {
|
||||
printf("Failed to open output file\n");
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
} else {
|
||||
printf("Failed to open the selected file\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool mask_instruction(uint8_t instruction, uint8_t inst_bits, uint8_t mask) {
|
||||
return (instruction & mask) == inst_bits;
|
||||
}
|
||||
|
||||
bool instruction_in_array(uint8_t inst, uint8_t *instructions, size_t arr_size,
|
||||
uint8_t mask) {
|
||||
for (size_t i = 0; i < arr_size; ++i) {
|
||||
if (mask_instruction(inst, instructions[i], mask)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t get_instruction_from_array(uint8_t inst, uint8_t *instructions,
|
||||
size_t arr_size, uint8_t mask) {
|
||||
for (size_t i = 0; i < arr_size; ++i) {
|
||||
if (mask_instruction(inst, instructions[i], mask)) {
|
||||
return instructions[i];
|
||||
}
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
void decode_register(uint8_t instruction, bool word, char *dest) {
|
||||
static uint8_t reg_mask = 0x07;
|
||||
|
||||
// clang-format off
|
||||
static const char *table[16] = {
|
||||
"al", "ax",
|
||||
"cl", "cx",
|
||||
"dl", "dx",
|
||||
"bl", "bx",
|
||||
"ah", "sp",
|
||||
"ch", "bp",
|
||||
"dh", "si",
|
||||
"bh", "di"
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static const uint8_t ROW_WIDTH = 2;
|
||||
|
||||
uint8_t offset = instruction & reg_mask;
|
||||
|
||||
// Multiply offset by 2 since each row has 2 columns
|
||||
strcpy(dest, table[offset * ROW_WIDTH + (uint8_t)word]);
|
||||
}
|
||||
|
||||
void decode_rm(uint8_t instruction, char *dest) {
|
||||
static uint8_t rm_mask = 0x07;
|
||||
|
||||
// clang-format off
|
||||
static const char *table[8] = {
|
||||
"bx + si",
|
||||
"bx + di",
|
||||
"bp + si",
|
||||
"bp + di",
|
||||
"si",
|
||||
"di",
|
||||
"bp",
|
||||
"bx"
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
uint8_t index = instruction & rm_mask;
|
||||
|
||||
strcpy(dest, table[index]);
|
||||
}
|
||||
|
||||
void stringify_rm_and_disp(FILE *fp, uint8_t operands, char *rm,
|
||||
uint32_t buff_size) {
|
||||
decode_rm(operands, rm);
|
||||
|
||||
bool direct_address = false;
|
||||
|
||||
uint8_t next_bytes = operands >> 6;
|
||||
|
||||
if (next_bytes == 0 && mask_instruction(operands, 0x06, 0x07)) {
|
||||
// Handle case when MOD == 00 and R/M == 110
|
||||
next_bytes = 2;
|
||||
|
||||
direct_address = true;
|
||||
}
|
||||
|
||||
int16_t disp = 0;
|
||||
fread(&disp, sizeof(next_bytes), next_bytes, fp);
|
||||
|
||||
if (disp != 0) {
|
||||
if (direct_address) {
|
||||
memset(rm, 0, buff_size);
|
||||
|
||||
sprintf(rm, "%d", disp);
|
||||
} else {
|
||||
bool positive = next_bytes > 1 ? disp > 0 : (int8_t)disp > 0;
|
||||
|
||||
char disp_out[buff_size];
|
||||
memset(disp_out, 0, buff_size);
|
||||
|
||||
sprintf(disp_out, " %c %d", positive ? '+' : '-',
|
||||
next_bytes > 1 ? abs(disp) : abs((int8_t)disp));
|
||||
|
||||
strcat(rm, disp_out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handle_accumulator_mov_instructions(FILE *fp, uint8_t inst, bool reg_dest,
|
||||
char *dest) {
|
||||
bool word = mask_instruction(inst, 0x01, 0x01);
|
||||
|
||||
uint8_t next_bytes = word ? 2 : 1;
|
||||
|
||||
uint16_t addr = 0;
|
||||
fread(&addr, sizeof(next_bytes), next_bytes, fp);
|
||||
|
||||
char addr_out[64] = {0};
|
||||
sprintf(addr_out, "[%d]", word ? addr : (uint8_t)addr);
|
||||
|
||||
sprintf(dest, "mov %s, %s", reg_dest ? "ax" : addr_out,
|
||||
reg_dest ? addr_out : "ax");
|
||||
}
|
||||
|
||||
void handle_accumulator_arithmetic_instructions(FILE *fp, uint8_t inst,
|
||||
char *dest) {
|
||||
const char *op = "";
|
||||
|
||||
switch (get_instruction_from_array(inst, to_accumulator_insts,
|
||||
ARRAY_LEN(to_accumulator_insts),
|
||||
(uint8_t)INST_MASKS::ACCUMULATOR)) {
|
||||
case (uint8_t)INST_BITS::ADD_IMM_TO_ACC:
|
||||
op = "add";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::SUB_IMM_FROM_ACC:
|
||||
op = "sub";
|
||||
break;
|
||||
case (uint8_t)INST_BITS::CMP_IMM_WITH_ACC:
|
||||
op = "cmp";
|
||||
break;
|
||||
}
|
||||
|
||||
bool word = mask_instruction(inst, 0x01, 0x01);
|
||||
|
||||
uint8_t next_bytes = word ? 2 : 1;
|
||||
|
||||
uint16_t data = 0;
|
||||
fread(&data, sizeof(next_bytes), next_bytes, fp);
|
||||
|
||||
sprintf(dest, "%s %s, %d", op, word ? "ax" : "al",
|
||||
word ? data : (int8_t)data);
|
||||
}
|
47
8086_assembly_03/listing_0039_more_movs.asm
Normal file
47
8086_assembly_03/listing_0039_more_movs.asm
Normal file
@ -0,0 +1,47 @@
|
||||
; ========================================================================
|
||||
;
|
||||
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
|
||||
;
|
||||
; This software is provided 'as-is', without any express or implied
|
||||
; warranty. In no event will the authors be held liable for any damages
|
||||
; arising from the use of this software.
|
||||
;
|
||||
; Please see https://computerenhance.com for further information
|
||||
;
|
||||
; ========================================================================
|
||||
|
||||
; ========================================================================
|
||||
; 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
|
20
8086_assembly_03/listing_0039_more_movs_out.asm
Normal file
20
8086_assembly_03/listing_0039_more_movs_out.asm
Normal file
@ -0,0 +1,20 @@
|
||||
; Disassembled by DASM
|
||||
|
||||
bits 16
|
||||
|
||||
mov si, bx
|
||||
mov dh, al
|
||||
mov cl, 12
|
||||
mov ch, -12
|
||||
mov cx, 12
|
||||
mov cx, -12
|
||||
mov dx, 3948
|
||||
mov dx, -3948
|
||||
mov al, [bx + si]
|
||||
mov bx, [bp + di]
|
||||
mov dx, [bp]
|
||||
mov ah, [bx + si + 4]
|
||||
mov al, [bx + si + 4999]
|
||||
mov [bx + di], cx
|
||||
mov [bp + si], cl
|
||||
mov [bp], ch
|
38
8086_assembly_03/listing_0040_challenge_movs.asm
Normal file
38
8086_assembly_03/listing_0040_challenge_movs.asm
Normal file
@ -0,0 +1,38 @@
|
||||
; ========================================================================
|
||||
;
|
||||
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
|
||||
;
|
||||
; This software is provided 'as-is', without any express or implied
|
||||
; warranty. In no event will the authors be held liable for any damages
|
||||
; arising from the use of this software.
|
||||
;
|
||||
; Please see https://computerenhance.com for further information
|
||||
;
|
||||
; ========================================================================
|
||||
|
||||
; ========================================================================
|
||||
; 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
|
13
8086_assembly_03/listing_0040_challenge_movs_out.asm
Normal file
13
8086_assembly_03/listing_0040_challenge_movs_out.asm
Normal file
@ -0,0 +1,13 @@
|
||||
bits 16
|
||||
|
||||
mov ax, [bx + di - 37]
|
||||
mov [si - 300], cx
|
||||
mov dx, [bx - 32]
|
||||
mov [bp + di], byte 7
|
||||
mov [di + 901], word 347
|
||||
mov bp, [5]
|
||||
mov bx, [3458]
|
||||
mov ax, [2555]
|
||||
mov ax, [16]
|
||||
mov [2554], ax
|
||||
mov [15], ax
|
122
8086_assembly_03/listing_0041_add_sub_cmp_jnz.asm
Normal file
122
8086_assembly_03/listing_0041_add_sub_cmp_jnz.asm
Normal file
@ -0,0 +1,122 @@
|
||||
; ========================================================================
|
||||
;
|
||||
; (C) Copyright 2023 by Molly Rocket, Inc., All Rights Reserved.
|
||||
;
|
||||
; This software is provided 'as-is', without any express or implied
|
||||
; warranty. In no event will the authors be held liable for any damages
|
||||
; arising from the use of this software.
|
||||
;
|
||||
; Please see https://computerenhance.com for further information
|
||||
;
|
||||
; ========================================================================
|
||||
|
||||
; ========================================================================
|
||||
; 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 word [bp + si + 1000], 520
|
||||
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
|
101
8086_assembly_03/listing_0041_add_sub_cmp_jnz_out.asm
Normal file
101
8086_assembly_03/listing_0041_add_sub_cmp_jnz_out.asm
Normal file
@ -0,0 +1,101 @@
|
||||
; Disassembled by DASM
|
||||
|
||||
bits 16
|
||||
|
||||
add bx, [bx + si]
|
||||
add bx, [bp]
|
||||
add si, 2
|
||||
add bp, 2
|
||||
add cx, 8
|
||||
add bx, [bp]
|
||||
add cx, [bx + 2]
|
||||
add bh, [bp + si + 4]
|
||||
add di, [bp + di + 6]
|
||||
add [bx + si], bx
|
||||
add [bp], bx
|
||||
add [bp], 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 word [bp + si + 1000], 520
|
||||
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]
|
||||
sub cx, [bx + 2]
|
||||
sub bh, [bp + si + 4]
|
||||
sub di, [bp + di + 6]
|
||||
sub [bx + si], bx
|
||||
sub [bp], bx
|
||||
sub [bp], 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]
|
||||
cmp cx, [bx + 2]
|
||||
cmp bh, [bp + si + 4]
|
||||
cmp di, [bp + di + 6]
|
||||
cmp [bx + si], bx
|
||||
cmp [bp], bx
|
||||
cmp [bp], 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
|
||||
jnz 2
|
||||
jnz -4
|
||||
jnz -6
|
||||
jnz -4
|
||||
je -2
|
||||
jl -4
|
||||
jle -6
|
||||
jb -8
|
||||
jbe -10
|
||||
jp -12
|
||||
jo -14
|
||||
js -16
|
||||
jnz -18
|
||||
jnl -20
|
||||
jg -22
|
||||
jnb -24
|
||||
ja -26
|
||||
jnp -28
|
||||
jno -30
|
||||
jns -32
|
||||
loop -34
|
||||
loopz -36
|
||||
loopnz -38
|
||||
jcxz -40
|
Loading…
Reference in New Issue
Block a user