From: LeonardoBizzoni Date: Tue, 20 Jan 2026 21:05:56 +0000 (+0100) Subject: more instructions X-Git-Url: http://git.leonardobizzoni.com/?a=commitdiff_plain;ds=sidebyside;p=8086-decoder more instructions --- diff --git a/asm/add_sub_cmp_jnz.asm b/asm/add_sub_cmp_jnz.asm new file mode 100644 index 0000000..cece354 --- /dev/null +++ b/asm/add_sub_cmp_jnz.asm @@ -0,0 +1,121 @@ +; ======================================================================== +; +; (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 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/asm/challenge_movs.asm b/asm/challenge_movs.asm new file mode 100644 index 0000000..bd8aa5f --- /dev/null +++ b/asm/challenge_movs.asm @@ -0,0 +1,22 @@ +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/asm/many_register_mov.asm b/asm/many_register_mov.asm new file mode 100644 index 0000000..f26dd57 --- /dev/null +++ b/asm/many_register_mov.asm @@ -0,0 +1,17 @@ +; ======================================================================== +; LISTING 38 +; ======================================================================== + +bits 16 + +mov cx, bx +mov ch, ah +mov dx, bx +mov si, bx +mov bx, di +mov al, cl +mov ch, ch +mov bx, ax +mov bx, si +mov sp, di +mov bp, ax diff --git a/asm/mine.asm b/asm/mine.asm new file mode 100644 index 0000000..d8f6a37 --- /dev/null +++ b/asm/mine.asm @@ -0,0 +1,11 @@ +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/asm/more_movs.asm b/asm/more_movs.asm new file mode 100644 index 0000000..113e7f1 --- /dev/null +++ b/asm/more_movs.asm @@ -0,0 +1,35 @@ +; ======================================================================== +; 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/asm/single_register_mov.asm b/asm/single_register_mov.asm new file mode 100644 index 0000000..4df9261 --- /dev/null +++ b/asm/single_register_mov.asm @@ -0,0 +1,7 @@ +; ======================================================================== +; LISTING 37 +; ======================================================================== + +bits 16 + +mov cx, bx diff --git a/build.sh b/build.sh index 8aff95a..398817c 100755 --- a/build.sh +++ b/build.sh @@ -2,7 +2,7 @@ cd "$(dirname "$0")" set -eu -file="main.c" +file="src/main.c" for arg in "$@"; do if [[ $arg == *=* ]]; then @@ -14,8 +14,8 @@ for arg in "$@"; do fi done -common_link="-lpthread -lm" -common_flags="-pedantic -Wall -Wno-unused-function -Wno-gnu-anonymous-struct -Wno-nested-anon-types" +common_link="-lpthread -lm -I src/base" +common_flags="-pedantic -Wall -Wno-unused-function -Wno-gnu-anonymous-struct -Wno-nested-anon-types -Wno-gnu-zero-variadic-macro-arguments -Wno-initializer-overrides -Wno-c23-extensions" common_cpp="-std=c++23 -fno-exceptions" common_gui="-DOS_GUI=1" diff --git a/src/base b/src/base index 176c61f..7c53e4a 160000 --- a/src/base +++ b/src/base @@ -1 +1 @@ -Subproject commit 176c61f2d310b18f4f1719d494c6cb3eccc26555 +Subproject commit 7c53e4af1a9393f764d1399d742f70d46b6b272a diff --git a/src/main.c b/src/main.c index 0596888..8566496 100644 --- a/src/main.c +++ b/src/main.c @@ -6,21 +6,311 @@ #include #include +global char* registers[] = { + "al", "cl", "dl", "bl", + "ah", "ch", "dh", "bh", + "ax", "cx", "dx", "bx", + "sp", "bp", "si", "di", +}; + +global char* eac[] = { + "bx + si", + "bx + di", + "bp + si", + "bp + di", + "si", + "di", + "bp", + "bx", +}; + +global u8 *code = 0; + +fn usize inst_move_regmem_tofrom_reg(void) { + u8 *lcode = code; + u8 d = (*lcode & 0b10) >> 1; + u8 w = *lcode & 0b1; + lcode += 1; + u8 mod = *lcode >> 6; + u8 reg = (*lcode >> 3) & (0b111); + u8 rm = *lcode & (0b111); + lcode += 1; + + printf("mov "); + switch (mod) { + case 0b00: { + char *dest = registers[(w << 3) | reg]; + if (rm == 0b110) { + if (d) { + if (w) { + printf("%s, [%u]\n", dest, (*lcode) | (*(lcode + 1) << 8)); + lcode += 2; + } else { + printf("%s, [%u]\n", dest, *lcode); + lcode += 1; + } + } else { + if (w) { + printf("[%u], %s\n", (*lcode) | (*(lcode + 1) << 8), dest); + lcode += 2; + } else { + printf("[%u], %s\n", *lcode, dest); + lcode += 1; + } + } + } else { + if (d) { + printf("%s, [%s]\n", dest, eac[rm]); + } else { + printf("[%s], %s\n", eac[rm], dest); + } + } + } break; + case 0b01: { + char *dest = registers[(w << 3) | reg]; + i8 disp = *lcode; // in displacement calculations values are signed + char sign = (disp < 0 ? '-' : '+'); + disp = Abs(disp); + if (d) { + printf("%s, [%s %c %d]\n", dest, eac[rm], sign, disp); + } else { + printf("[%s %c %d], %s\n", eac[rm], sign, disp, dest); + } + lcode += 1; + } break; + case 0b10: { + char *dest = registers[(w << 3) | reg]; + // in displacement calculations values are signed + i16 disp = *lcode | ((*(lcode + 1)) << 8); + char sign = (disp < 0 ? '-' : '+'); + disp = Abs(disp); + if (d) { + printf("%s, [%s %c %u]\n", dest, eac[rm], sign, disp); + } else { + printf("[%s %c %u], %s\n", eac[rm], sign, disp, dest); + } + lcode += 2; + } break; + case 0b11: { + char *dest = d ? registers[(w << 3) | reg] : registers[(w << 3) | rm]; + char *source = d ? registers[(w << 3) | rm] : registers[(w << 3) | reg]; + printf("%s, %s\n", dest, source); + } break; + } + + usize res = lcode - code; + code = lcode; + return res; +} + +fn usize inst_move_imm_to_reg(void) { + u8 *lcode = code; + u8 w = (*lcode >> 3) & 0b1; + u8 reg = *lcode & 0b111; + lcode += 1; + printf("mov %s, ", registers[(w << 3) | reg]); + if (w) { + printf("%u\n", lcode[0] | (lcode[1] << 8)); + lcode += 2; + } else { + printf("%u\n", *lcode++); + } + usize res = lcode - code; + code = lcode; + return res; +} + +fn usize inst_move_imm_to_regmem(void) { + u8 *lcode = code; + u8 w = *lcode & 0b1; + lcode += 1; + u8 mod = *lcode >> 6; + u8 rm = *lcode & 0b111; + lcode += 1; + + printf("mov "); + switch (mod) { + case 0b00: { + if (rm == 0b110) { + u8 *ofos_fset = lcode; + if (w) { + lcode += 1; + printf("[%u], word %u\n", *ofos_fset, *lcode | ((*(lcode + 1)) << 8)); + } else { + printf("[%u], byte %u\n", *ofos_fset, *lcode); + } + } else { + if (w) { + printf("[%s], word %u\n", eac[rm], *lcode | ((*(lcode + 1)) << 8)); + lcode += 2; + } else { + printf("[%s], byte %u\n", eac[rm], *lcode); + lcode += 1; + } + } + } break; + case 0b01: { + i8 disp = *lcode; // in displacement calculations values are signed + char sign = (disp < 0 ? '-' : '+'); + disp = Abs(disp); + if (w) { + printf("[%s %c %d], word %d\n", eac[rm], sign, disp, + *lcode | ((*(lcode + 1)) << 8)); + lcode += 2; + } else { + printf("[%s %c %d], byte %d\n", eac[rm], sign, disp, *lcode); + lcode += 1; + } + } break; + case 0b10: { + // in displacement calculations values are signed + i16 disp = *lcode | ((*(lcode + 1)) << 8); + lcode += 2; + char sign = (disp < 0 ? '-' : '+'); + disp = Abs(disp); + if (w) { + printf("[%s %c %u], word %d\n", eac[rm], sign, disp, + *lcode | ((*(lcode + 1)) << 8)); + lcode += 2; + } else { + printf("[%s %c %u], byte %d\n", eac[rm], sign, disp, *lcode); + lcode += 1; + } + } break; + case 0b11: { + if (w) { + printf("%s, %d\n", registers[(w << 3) | rm], + *lcode | ((*(lcode + 1)) << 8)); + lcode += 2; + } else { + printf("%s, %d\n", registers[(w << 3) | rm], *lcode); + lcode += 1; + } + } break; + } + usize res = lcode - code; + code = lcode; + return res; +} + +fn usize inst_move_mem_to_accum(u8 d) { + u8 *lcode = code; + u8 w = *lcode & 0b1; + lcode += 1; + if (d) { + if (w) { + printf("mov ax, [%u]\n", *lcode | (*(lcode + 1) << 8)); + lcode += 2; + } else { + printf("mov al, [%u]\n", *lcode); + lcode += 1; + } + } else { + if (w) { + printf("mov [%u], ax\n", *lcode | (*(lcode + 1) << 8)); + lcode += 2; + } else { + printf("mov [%u], al\n", *lcode); + lcode += 1; + } + } + usize res = lcode - code; + code = lcode; + return res; +} + +inline fn i8 get_byte_displacement(void) { + code += 1; + i8 res = *code; + code += 1; + return res; +} + fn void start(CmdLine *cli) { -#if 1 - printf("Compiler GCC: %d\n", COMPILER_GCC); - printf("Compiler CL: %d\n", COMPILER_CL); - printf("Compiler CLANG: %d\n", COMPILER_CLANG); - - printf("OS GNU/Linux: %d\n", OS_LINUX); - printf("OS BSD: %d\n", OS_BSD); - printf("OS MAC: %d\n", OS_MAC); - printf("OS Windows: %d\n", OS_WINDOWS); - - printf("Architecture x86 32bit: %d\n", ARCH_X86); - printf("Architecture x64 64bit: %d\n", ARCH_X64); - printf("Architecture ARM 32bit: %d\n", ARCH_ARM); - printf("Architecture ARM 64bit: %d\n", ARCH_ARM64); -#endif + Arena *arena = arena_build(); + OS_Handle binary_file = os_fs_open(Strlit("asm/add_sub_cmp_jnz"), OS_AccessFlag_Read); + /* OS_Handle binary_file = os_fs_open(Strlit("asm/challenge_movs"), OS_AccessFlag_Read); */ + /* OS_Handle binary_file = os_fs_open(Strlit("asm/more_movs"), OS_AccessFlag_Read); */ + /* OS_Handle binary_file = os_fs_open(Strlit("asm/many_register_mov"), OS_AccessFlag_Read); */ + /* OS_Handle binary_file = os_fs_open(Strlit("asm/single_register_mov"), OS_AccessFlag_Read); */ + String8 content = os_fs_read(arena, binary_file); + code = content.str; + os_fs_close(binary_file); + for (usize i = 0; i < content.size;) { + if ((*code >> 2) == 0b100010) { + i += inst_move_regmem_tofrom_reg(); + } else if ((*code >> 1) == 0b1100011) { + i += inst_move_imm_to_regmem(); + } else if ((*code >> 4) == 0b1011) { + i += inst_move_imm_to_reg(); + } else if ((*code >> 1) == 0b1010000) { + i += inst_move_mem_to_accum(1); + } else if ((*code >> 1) == 0b1010001) { + i += inst_move_mem_to_accum(0); + } else if (*code == 0b01110101) { + i += 2; + printf("jnz %d\n", get_byte_displacement()); + } else if (*code == 0b01110100) { + i += 2; + printf("je %d\n", get_byte_displacement()); + } else if (*code == 0b01111100) { + i += 2; + printf("jl %d\n", get_byte_displacement()); + } else if (*code == 0b01111110) { + i += 2; + printf("jle %d\n", get_byte_displacement()); + } else if (*code == 0b01110010) { + i += 2; + printf("jb %d\n", get_byte_displacement()); + } else if (*code == 0b01110110) { + i += 2; + printf("jbe %d\n", get_byte_displacement()); + } else if (*code == 0b01111010) { + i += 2; + printf("jp %d\n", get_byte_displacement()); + } else if (*code == 0b01110000) { + i += 2; + printf("jo %d\n", get_byte_displacement()); + } else if (*code == 0b01111000) { + i += 2; + printf("js %d\n", get_byte_displacement()); + } else if (*code == 0b01110101) { + i += 2; + printf("jne %d\n", get_byte_displacement()); + } else if (*code == 0b01111101) { + i += 2; + printf("jnl %d\n", get_byte_displacement()); + } else if (*code == 0b01111111) { + i += 2; + printf("jg %d\n", get_byte_displacement()); + } else if (*code == 0b01110011) { + i += 2; + printf("jnb %d\n", get_byte_displacement()); + } else if (*code == 0b01110111) { + i += 2; + printf("ja %d\n", get_byte_displacement()); + } else if (*code == 0b01111011) { + i += 2; + printf("jnp %d\n", get_byte_displacement()); + } else if (*code == 0b01110001) { + i += 2; + printf("jno %d\n", get_byte_displacement()); + } else if (*code == 0b01111001) { + i += 2; + printf("jns %d\n", get_byte_displacement()); + } else if (*code == 0b11100010) { + i += 2; + printf("loop %d\n", get_byte_displacement()); + } else if (*code == 0b11100001) { + i += 2; + printf("loopz %d\n", get_byte_displacement()); + } else if (*code == 0b11100000) { + i += 2; + printf("loopnz %d\n", get_byte_displacement()); + } else if (*code == 0b11100011) { + i += 2; + printf("jcxz %d\n", get_byte_displacement()); + } else { Assert(false && "Invalid instruction"); } + } }