about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--subx/015immediate_addressing.cc51
-rw-r--r--subx/034compute_segment_address.cc2
2 files changed, 51 insertions, 2 deletions
diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc
index 30f96523..eedf81a3 100644
--- a/subx/015immediate_addressing.cc
+++ b/subx/015immediate_addressing.cc
@@ -6,7 +6,7 @@ put_new(Name, "05", "add imm32 to EAX (add)");
 :(before "End Single-Byte Opcodes")
 case 0x05: {  // add imm32 to EAX
   int32_t signed_arg2 = next32();
-  trace(Callstack_depth+1, "run") << "add imm32 0x" << HEXWORD << signed_arg2 << " to reg EAX" << end();
+  trace(Callstack_depth+1, "run") << "add imm32 0x" << HEXWORD << signed_arg2 << " to EAX" << end();
   int32_t signed_result = Reg[EAX].i + signed_arg2;
   SF = (signed_result < 0);
   ZF = (signed_result == 0);
@@ -23,6 +23,55 @@ case 0x05: {  // add imm32 to EAX
   break;
 }
 
+:(code)
+void test_add_imm32_to_EAX_signed_overflow() {
+  Reg[EAX].i = 0x7fffffff;  // largest positive signed integer
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  05                                 01 00 00 00 \n" // add 1 to EAX
+      // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX)
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: add imm32 0x00000001 to EAX\n"
+      "run: SF=1; ZF=0; CF=0; OF=1\n"
+      "run: storing 0x80000000\n"
+  );
+}
+
+void test_add_imm32_to_EAX_unsigned_overflow() {
+  Reg[EAX].u = 0xffffffff;  // largest unsigned number
+  Reg[EBX].u = 1;
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  05                                 01 00 00 00 \n" // add 1 to EAX
+      // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX)
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: add imm32 0x00000001 to EAX\n"
+      "run: SF=0; ZF=1; CF=1; OF=0\n"
+      "run: storing 0x00000000\n"
+  );
+}
+
+void test_add_imm32_to_EAX_unsigned_and_signed_overflow() {
+  Reg[EAX].u = 0x80000000;  // smallest negative signed integer
+  run(
+      "== 0x1\n"  // code segment
+      // op     ModR/M  SIB   displacement  immediate
+      "  05                                 00 00 00 80 \n" // add 0x80000000 to EAX
+      // ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX)
+  );
+  CHECK_TRACE_CONTENTS(
+      "run: add imm32 0x80000000 to EAX\n"
+      "run: SF=0; ZF=1; CF=1; OF=1\n"
+      "run: storing 0x00000000\n"
+  );
+}
+
+//:
+
 :(before "End Initialize Op Names")
 put_new(Name, "81", "combine rm32 with imm32 based on subop (add/sub/and/or/xor/cmp)");
 
diff --git a/subx/034compute_segment_address.cc b/subx/034compute_segment_address.cc
index a1b7482d..47311219 100644
--- a/subx/034compute_segment_address.cc
+++ b/subx/034compute_segment_address.cc
@@ -14,7 +14,7 @@ void test_segment_name() {
       "load: 0x09000056 -> 0b\n"
       "load: 0x09000057 -> 0c\n"
       "load: 0x09000058 -> 0d\n"
-      "run: add imm32 0x0d0c0b0a to reg EAX\n"
+      "run: add imm32 0x0d0c0b0a to EAX\n"
       "run: storing 0x0d0c0b0a\n"
   );
 }