about summary refs log tree commit diff stats
path: root/subx/014indirect_addressing.cc
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-09-07 22:13:10 -0700
committerKartik Agaram <vc@akkartik.com>2018-09-07 22:19:13 -0700
commite07a3f2886b117970b3cd58f7cd6806cbfe5cc4a (patch)
tree6fcddb741f3b15eaa7892b5ce0468a6f3695005a /subx/014indirect_addressing.cc
parent608a7fa8d0faf9a3e3d182d9eabe969804443aab (diff)
downloadmu-e07a3f2886b117970b3cd58f7cd6806cbfe5cc4a.tar.gz
4537
Streamline the factorial function; we don't need to save a stack variable
into a register before operating on it. All instructions can take a stack
variable directly.

In the process we found two bugs:

a) Opcode f7 was not implemented correctly. It was internally consistent
but I'd never validated it against a natively running program. Turns out
it encodes multiple instructions, not just 'not'.

b) The way we look up imm32 operands was sometimes reading them before
disp8/disp32 operands.
Diffstat (limited to 'subx/014indirect_addressing.cc')
-rw-r--r--subx/014indirect_addressing.cc9
1 files changed, 5 insertions, 4 deletions
diff --git a/subx/014indirect_addressing.cc b/subx/014indirect_addressing.cc
index 344da8de..22a3c179 100644
--- a/subx/014indirect_addressing.cc
+++ b/subx/014indirect_addressing.cc
@@ -227,16 +227,17 @@ case 0x33: {  // xor r/m32 with r32
 
 //:: not
 
-:(scenario not_r32_with_mem_at_r32)
+:(scenario not_of_mem_at_r32)
 % Reg[EBX].i = 0x60;
 == 0x1  # code segment
 # op  ModR/M  SIB   displacement  immediate
-  f7  03                                      # negate *EBX
-# ModR/M in binary: 00 (indirect mode) 000 (unused) 011 (dest EBX)
+  f7  13                                      # negate *EBX
+# ModR/M in binary: 00 (indirect mode) 010 (subop not) 011 (dest EBX)
 == 0x60  # data segment
 ff 00 0f 0f  # 0x0f0f00ff
-+run: 'not' of r/m32
++run: operate on r/m32
 +run: effective address is 0x60 (EBX)
++run: subop: not
 +run: storing 0xf0f0ff00
 
 //:: compare (cmp)