Completed homework for decoding add, sub, cmp and jump instructions

This commit is contained in:
Abdelrahman Said 2023-03-12 17:29:49 +00:00
parent 620f9e0daa
commit b3eb9b99c7
9 changed files with 907 additions and 0 deletions

7
8086_assembly_03/.gitignore vendored Normal file
View 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

View File

@ -0,0 +1,2 @@
all:
clang++ -g dasm.cpp -o dasm

557
8086_assembly_03/dasm.cpp Normal file
View 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);
}

View 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

View 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

View 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

View 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

View 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

View 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