diff --git a/8086_assembly_03/.gitignore b/8086_assembly_03/.gitignore new file mode 100644 index 0000000..335922a --- /dev/null +++ b/8086_assembly_03/.gitignore @@ -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 diff --git a/8086_assembly_03/Makefile b/8086_assembly_03/Makefile new file mode 100644 index 0000000..46770a1 --- /dev/null +++ b/8086_assembly_03/Makefile @@ -0,0 +1,2 @@ +all: + clang++ -g dasm.cpp -o dasm diff --git a/8086_assembly_03/dasm.cpp b/8086_assembly_03/dasm.cpp new file mode 100644 index 0000000..684a29f --- /dev/null +++ b/8086_assembly_03/dasm.cpp @@ -0,0 +1,557 @@ +#include +#include +#include +#include +#include +#include + +#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); +} diff --git a/8086_assembly_03/listing_0039_more_movs.asm b/8086_assembly_03/listing_0039_more_movs.asm new file mode 100644 index 0000000..854fcb4 --- /dev/null +++ b/8086_assembly_03/listing_0039_more_movs.asm @@ -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 diff --git a/8086_assembly_03/listing_0039_more_movs_out.asm b/8086_assembly_03/listing_0039_more_movs_out.asm new file mode 100644 index 0000000..dc57f26 --- /dev/null +++ b/8086_assembly_03/listing_0039_more_movs_out.asm @@ -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 diff --git a/8086_assembly_03/listing_0040_challenge_movs.asm b/8086_assembly_03/listing_0040_challenge_movs.asm new file mode 100644 index 0000000..966e47a --- /dev/null +++ b/8086_assembly_03/listing_0040_challenge_movs.asm @@ -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 diff --git a/8086_assembly_03/listing_0040_challenge_movs_out.asm b/8086_assembly_03/listing_0040_challenge_movs_out.asm new file mode 100644 index 0000000..69ff2bc --- /dev/null +++ b/8086_assembly_03/listing_0040_challenge_movs_out.asm @@ -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 diff --git a/8086_assembly_03/listing_0041_add_sub_cmp_jnz.asm b/8086_assembly_03/listing_0041_add_sub_cmp_jnz.asm new file mode 100644 index 0000000..f7cebf7 --- /dev/null +++ b/8086_assembly_03/listing_0041_add_sub_cmp_jnz.asm @@ -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 diff --git a/8086_assembly_03/listing_0041_add_sub_cmp_jnz_out.asm b/8086_assembly_03/listing_0041_add_sub_cmp_jnz_out.asm new file mode 100644 index 0000000..f99e5e7 --- /dev/null +++ b/8086_assembly_03/listing_0041_add_sub_cmp_jnz_out.asm @@ -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