about summary refs log tree commit diff stats
path: root/subx/016index_addressing.cc
diff options
context:
space:
mode:
Diffstat (limited to 'subx/016index_addressing.cc')
-rw-r--r--subx/016index_addressing.cc178
1 files changed, 104 insertions, 74 deletions
diff --git a/subx/016index_addressing.cc b/subx/016index_addressing.cc
index 9fb3e9bb..ef72f710 100644
--- a/subx/016index_addressing.cc
+++ b/subx/016index_addressing.cc
@@ -1,19 +1,25 @@
 //: operating on memory at the address provided by some register plus optional scale and offset
 
-:(scenario add_r32_to_mem_at_r32_with_sib)
-% Reg[EBX].i = 0x10;
-% Reg[EAX].i = 0x2000;
-== 0x1  # code segment
-# op  ModR/M  SIB   displacement  immediate
-  01  1c      20                             # add EBX to *EAX
-# ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB)
-# SIB in binary: 00 (scale 1) 100 (no index) 000 (base EAX)
-== 0x2000  # data segment
-01 00 00 00  # 1
-+run: add EBX to r/m32
-+run: effective address is initially 0x00002000 (EAX)
-+run: effective address is 0x00002000
-+run: storing 0x00000011
+:(code)
+void test_add_r32_to_mem_at_r32_with_sib() {
+  Reg[EBX].i = 0x10;
+  Reg[EAX].i = 0x2000;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  01     1c      20                              \n"  // add EBX to *EAX
+      // ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB)
+      // SIB in binary: 00 (scale 1) 100 (no index) 000 (base EAX)
+      "== 0x2000\n"  // data segment
+      "01 00 00 00\n"  // 0x00000001
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: add EBX to r/m32\n"
+      "run: effective address is initially 0x00002000 (EAX)\n"
+      "run: effective address is 0x00002000\n"
+      "run: storing 0x00000011\n"
+  );
+}
 
 :(before "End Mod 0 Special-cases(addr)")
 case 4:  // exception: mod 0b00 rm 0b100 => incoming SIB (scale-index-base) byte
@@ -46,54 +52,72 @@ uint32_t effective_address_from_sib(uint8_t mod) {
   return addr;
 }
 
-:(scenario add_r32_to_mem_at_base_r32_index_r32)
-% Reg[EBX].i = 0x10;  // source
-% Reg[EAX].i = 0x1ffe;  // dest base
-% Reg[ECX].i = 0x2;  // dest index
-== 0x1  # code segment
-# op  ModR/M  SIB   displacement  immediate
-  01  1c      08                             # add EBX to *(EAX+ECX)
-# ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB)
-# SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX)
-== 0x2000  # data segment
-01 00 00 00  # 1
-+run: add EBX to r/m32
-+run: effective address is initially 0x00001ffe (EAX)
-+run: effective address is 0x00002000 (after adding ECX*1)
-+run: storing 0x00000011
+:(code)
+void test_add_r32_to_mem_at_base_r32_index_r32() {
+  Reg[EBX].i = 0x10;  // source
+  Reg[EAX].i = 0x1ffe;  // dest base
+  Reg[ECX].i = 0x2;  // dest index
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  01     1c      08                              \n"  // add EBX to *(EAX+ECX)
+      // ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB)
+      // SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX)
+      "== 0x2000\n"  // data segment
+      "01 00 00 00\n"  // 0x00000001
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: add EBX to r/m32\n"
+      "run: effective address is initially 0x00001ffe (EAX)\n"
+      "run: effective address is 0x00002000 (after adding ECX*1)\n"
+      "run: storing 0x00000011\n"
+  );
+}
 
-:(scenario add_r32_to_mem_at_displacement_using_sib)
-% Reg[EBX].i = 0x10;  // source
-== 0x1  # code segment
-# op  ModR/M  SIB   displacement  immediate
-  01  1c      25    00 20 00 00              # add EBX to *0x2000
-# ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB)
-# SIB in binary: 00 (scale 1) 100 (no index) 101 (not EBP but disp32)
-== 0x2000  # data segment
-01 00 00 00  # 1
-+run: add EBX to r/m32
-+run: effective address is initially 0x00002000 (disp32)
-+run: effective address is 0x00002000
-+run: storing 0x00000011
+:(code)
+void test_add_r32_to_mem_at_displacement_using_sib() {
+  Reg[EBX].i = 0x10;  // source
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  01     1c      25    00 20 00 00               \n"  // add EBX to *0x2000
+      // ModR/M in binary: 00 (indirect mode) 011 (src EBX) 100 (dest in SIB)
+      // SIB in binary: 00 (scale 1) 100 (no index) 101 (not EBP but disp32)
+      "== 0x2000\n"  // data segment
+      "01 00 00 00\n"  // 0x00000001
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: add EBX to r/m32\n"
+      "run: effective address is initially 0x00002000 (disp32)\n"
+      "run: effective address is 0x00002000\n"
+      "run: storing 0x00000011\n"
+  );
+}
 
 //:
 
-:(scenario add_r32_to_mem_at_base_r32_index_r32_plus_disp8)
-% Reg[EBX].i = 0x10;  // source
-% Reg[EAX].i = 0x1ff9;  // dest base
-% Reg[ECX].i = 0x5;  // dest index
-== 0x1  # code segment
-# op  ModR/M  SIB   displacement  immediate
-  01  5c      08    02                       # add EBX to *(EAX+ECX+2)
-# ModR/M in binary: 01 (indirect+disp8 mode) 011 (src EBX) 100 (dest in SIB)
-# SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX)
-== 0x2000  # data segment
-01 00 00 00  # 1
-+run: add EBX to r/m32
-+run: effective address is initially 0x00001ff9 (EAX)
-+run: effective address is 0x00001ffe (after adding ECX*1)
-+run: effective address is 0x00002000 (after adding disp8)
-+run: storing 0x00000011
+:(code)
+void test_add_r32_to_mem_at_base_r32_index_r32_plus_disp8() {
+  Reg[EBX].i = 0x10;  // source
+  Reg[EAX].i = 0x1ff9;  // dest base
+  Reg[ECX].i = 0x5;  // dest index
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  01     5c      08    02                        \n"  // add EBX to *(EAX+ECX+2)
+      // ModR/M in binary: 01 (indirect+disp8 mode) 011 (src EBX) 100 (dest in SIB)
+      // SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX)
+      "== 0x2000\n"  // data segment
+      "01 00 00 00\n"  // 0x00000001
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: add EBX to r/m32\n"
+      "run: effective address is initially 0x00001ff9 (EAX)\n"
+      "run: effective address is 0x00001ffe (after adding ECX*1)\n"
+      "run: effective address is 0x00002000 (after adding disp8)\n"
+      "run: storing 0x00000011\n"
+  );
+}
 
 :(before "End Mod 1 Special-cases(addr)")
 case 4:  // exception: mod 0b01 rm 0b100 => incoming SIB (scale-index-base) byte
@@ -102,22 +126,28 @@ case 4:  // exception: mod 0b01 rm 0b100 => incoming SIB (scale-index-base) byte
 
 //:
 
-:(scenario add_r32_to_mem_at_base_r32_index_r32_plus_disp32)
-% Reg[EBX].i = 0x10;  // source
-% Reg[EAX].i = 0x1ff9;  // dest base
-% Reg[ECX].i = 0x5;  // dest index
-== 0x1  # code segment
-# op  ModR/M  SIB   displacement  immediate
-  01  9c      08    02 00 00 00              # add EBX to *(EAX+ECX+2)
-# ModR/M in binary: 10 (indirect+disp32 mode) 011 (src EBX) 100 (dest in SIB)
-# SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX)
-== 0x2000  # data segment
-01 00 00 00  # 1
-+run: add EBX to r/m32
-+run: effective address is initially 0x00001ff9 (EAX)
-+run: effective address is 0x00001ffe (after adding ECX*1)
-+run: effective address is 0x00002000 (after adding disp32)
-+run: storing 0x00000011
+:(code)
+void test_add_r32_to_mem_at_base_r32_index_r32_plus_disp32() {
+  Reg[EBX].i = 0x10;  // source
+  Reg[EAX].i = 0x1ff9;  // dest base
+  Reg[ECX].i = 0x5;  // dest index
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  01     9c      08    02 00 00 00               \n"  // add EBX to *(EAX+ECX+2)
+      // ModR/M in binary: 10 (indirect+disp32 mode) 011 (src EBX) 100 (dest in SIB)
+      // SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX)
+      "== 0x2000\n"  // data segment
+      "01 00 00 00\n"  // 0x00000001
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: add EBX to r/m32\n"
+      "run: effective address is initially 0x00001ff9 (EAX)\n"
+      "run: effective address is 0x00001ffe (after adding ECX*1)\n"
+      "run: effective address is 0x00002000 (after adding disp32)\n"
+      "run: storing 0x00000011\n"
+  );
+}
 
 :(before "End Mod 2 Special-cases(addr)")
 case 4:  // exception: mod 0b10 rm 0b100 => incoming SIB (scale-index-base) byte