]> git.leonardobizzoni.com Git - 8086-decoder/commitdiff
more instructions master
authorLeonardoBizzoni <leo2002714@gmail.com>
Tue, 20 Jan 2026 21:05:56 +0000 (22:05 +0100)
committerLeonardoBizzoni <leo2002714@gmail.com>
Tue, 20 Jan 2026 21:05:56 +0000 (22:05 +0100)
asm/add_sub_cmp_jnz.asm [new file with mode: 0644]
asm/challenge_movs.asm [new file with mode: 0644]
asm/many_register_mov.asm [new file with mode: 0644]
asm/mine.asm [new file with mode: 0644]
asm/more_movs.asm [new file with mode: 0644]
asm/single_register_mov.asm [new file with mode: 0644]
build.sh
src/base
src/main.c

diff --git a/asm/add_sub_cmp_jnz.asm b/asm/add_sub_cmp_jnz.asm
new file mode 100644 (file)
index 0000000..cece354
--- /dev/null
@@ -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 (file)
index 0000000..bd8aa5f
--- /dev/null
@@ -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 (file)
index 0000000..f26dd57
--- /dev/null
@@ -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 (file)
index 0000000..d8f6a37
--- /dev/null
@@ -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 (file)
index 0000000..113e7f1
--- /dev/null
@@ -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 (file)
index 0000000..4df9261
--- /dev/null
@@ -0,0 +1,7 @@
+; ========================================================================
+; LISTING 37
+; ========================================================================
+
+bits 16
+
+mov cx, bx
index 8aff95a7ac7932f0cf02b6298961cfb299294094..398817c80316953707a315933b38d6b761c644ca 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -2,7 +2,7 @@
 cd "$(dirname "$0")"
 set -eu
 
 cd "$(dirname "$0")"
 set -eu
 
-file="main.c"
+file="src/main.c"
 
 for arg in "$@"; do
     if [[ $arg == *=* ]]; then
 
 for arg in "$@"; do
     if [[ $arg == *=* ]]; then
@@ -14,8 +14,8 @@ for arg in "$@"; do
     fi
 done
 
     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"
 
 common_cpp="-std=c++23 -fno-exceptions"
 common_gui="-DOS_GUI=1"
 
index 176c61f2d310b18f4f1719d494c6cb3eccc26555..7c53e4af1a9393f764d1399d742f70d46b6b272a 160000 (submodule)
--- a/src/base
+++ b/src/base
@@ -1 +1 @@
-Subproject commit 176c61f2d310b18f4f1719d494c6cb3eccc26555
+Subproject commit 7c53e4af1a9393f764d1399d742f70d46b6b272a
index 0596888ffdac6c0ebd506a33f1910b685923d493..856649632984d4aef4b4bdb01ea2ebb318fbd795 100644 (file)
 #include <base/base_inc.c>
 #include <OS/os_inc.c>
 
 #include <base/base_inc.c>
 #include <OS/os_inc.c>
 
+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) {
 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"); }
+  }
 }
 }