diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-09-07 22:13:10 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-09-07 22:19:13 -0700 |
commit | e07a3f2886b117970b3cd58f7cd6806cbfe5cc4a (patch) | |
tree | 6fcddb741f3b15eaa7892b5ce0468a6f3695005a /subx/015immediate_addressing.cc | |
parent | 608a7fa8d0faf9a3e3d182d9eabe969804443aab (diff) | |
download | mu-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/015immediate_addressing.cc')
-rw-r--r-- | subx/015immediate_addressing.cc | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc index c75c419e..b1d97f1e 100644 --- a/subx/015immediate_addressing.cc +++ b/subx/015immediate_addressing.cc @@ -9,17 +9,19 @@ put(name, "81", "combine rm32 with imm32 based on subop"); # op ModR/M SIB displacement immediate 81 c3 0a 0b 0c 0d # add 0x0d0c0b0a to EBX # ModR/M in binary: 11 (direct mode) 000 (add imm32) 011 (dest EBX) -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: r/m32 is EBX ++run: imm32 is 0x0d0c0b0a +run: subop add +run: storing 0x0d0c0b0b :(before "End Single-Byte Opcodes") case 0x81: { // combine imm32 with r/m32 + trace(90, "run") << "combine imm32 with r/m32" << end(); uint8_t modrm = next(); - int32_t arg2 = imm32(); - trace(90, "run") << "combine imm32 0x" << HEXWORD << arg2 << " with r/m32" << end(); int32_t* arg1 = effective_address(modrm); + int32_t arg2 = imm32(); + trace(90, "run") << "imm32 is 0x" << HEXWORD << arg2 << end(); uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits switch (subop) { case 0: @@ -44,8 +46,9 @@ case 0x81: { // combine imm32 with r/m32 # ModR/M in binary: 00 (indirect mode) 000 (add imm32) 011 (dest EBX) == 0x60 # data segment 01 00 00 00 # 1 -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: effective address is 0x60 (EBX) ++run: imm32 is 0x0d0c0b0a +run: subop add +run: storing 0x0d0c0b0b @@ -80,8 +83,9 @@ case 0x2d: { // subtract imm32 from EAX # ModR/M in binary: 00 (indirect mode) 101 (subtract imm32) 011 (dest EBX) == 0x60 # data segment 0a 00 00 00 # 10 -+run: combine imm32 0x00000001 with r/m32 ++run: combine imm32 with r/m32 +run: effective address is 0x60 (EBX) ++run: imm32 is 0x00000001 +run: subop subtract +run: storing 0x00000009 @@ -100,8 +104,9 @@ case 5: { # op ModR/M SIB displacement immediate 81 eb 01 00 00 00 # subtract 1 from EBX # ModR/M in binary: 11 (direct mode) 101 (subtract imm32) 011 (dest EBX) -+run: combine imm32 0x00000001 with r/m32 ++run: combine imm32 with r/m32 +run: r/m32 is EBX ++run: imm32 is 0x00000001 +run: subop subtract +run: storing 0x00000009 @@ -136,8 +141,9 @@ case 0x25: { // and imm32 with EAX # ModR/M in binary: 00 (indirect mode) 100 (and imm32) 011 (dest EBX) == 0x60 # data segment ff 00 00 00 # 0xff -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: effective address is 0x60 (EBX) ++run: imm32 is 0x0d0c0b0a +run: subop and +run: storing 0x0000000a @@ -156,8 +162,9 @@ case 4: { # op ModR/M SIB displacement immediate 81 e3 0a 0b 0c 0d # and 0x0d0c0b0a with EBX # ModR/M in binary: 11 (direct mode) 100 (and imm32) 011 (dest EBX) -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: r/m32 is EBX ++run: imm32 is 0x0d0c0b0a +run: subop and +run: storing 0x0000000a @@ -192,8 +199,9 @@ case 0x0d: { // or imm32 with EAX # ModR/M in binary: 00 (indirect mode) 001 (or imm32) 011 (dest EBX) == 0x60 # data segment a0 b0 c0 d0 # 0xd0c0b0a0 -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: effective address is 0x60 (EBX) ++run: imm32 is 0x0d0c0b0a +run: subop or +run: storing 0xddccbbaa @@ -210,8 +218,9 @@ case 1: { # op ModR/M SIB displacement immediate 81 cb 0a 0b 0c 0d # or 0x0d0c0b0a with EBX # ModR/M in binary: 11 (direct mode) 001 (or imm32) 011 (dest EBX) -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: r/m32 is EBX ++run: imm32 is 0x0d0c0b0a +run: subop or +run: storing 0xddccbbaa @@ -246,8 +255,9 @@ case 0x35: { // xor imm32 with EAX # ModR/M in binary: 00 (indirect mode) 110 (xor imm32) 011 (dest EBX) == 0x60 # data segment a0 b0 c0 d0 # 0xd0c0b0a0 -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: effective address is 0x60 (EBX) ++run: imm32 is 0x0d0c0b0a +run: subop xor +run: storing 0xddccbbaa @@ -264,8 +274,9 @@ case 6: { # op ModR/M SIB displacement immediate 81 f3 0a 0b 0c 0d # xor 0x0d0c0b0a with EBX # ModR/M in binary: 11 (direct mode) 110 (xor imm32) 011 (dest EBX) -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: r/m32 is EBX ++run: imm32 is 0x0d0c0b0a +run: subop xor +run: storing 0xddccbbaa @@ -320,8 +331,9 @@ case 0x3d: { // subtract imm32 from EAX # op ModR/M SIB displacement immediate 81 fb 07 0b 0c 0d # compare 0x0d0c0b07 with EBX # ModR/M in binary: 11 (direct mode) 111 (compare imm32) 011 (dest EBX) -+run: combine imm32 0x0d0c0b07 with r/m32 ++run: combine imm32 with r/m32 +run: r/m32 is EBX ++run: imm32 is 0x0d0c0b07 +run: SF=0; ZF=0; OF=0 :(before "End Op 81 Subops") @@ -342,8 +354,9 @@ case 7: { # op ModR/M SIB displacement immediate 81 fb 0a 0b 0c 0d # compare 0x0d0c0b0a with EBX # ModR/M in binary: 11 (direct mode) 111 (compare imm32) 011 (dest EBX) -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: r/m32 is EBX ++run: imm32 is 0x0d0c0b0a +run: SF=1; ZF=0; OF=0 :(scenario compare_imm32_with_r32_equal) @@ -352,8 +365,9 @@ case 7: { # op ModR/M SIB displacement immediate 81 fb 0a 0b 0c 0d # compare 0x0d0c0b0a with EBX # ModR/M in binary: 11 (direct mode) 111 (compare imm32) 011 (dest EBX) -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: r/m32 is EBX ++run: imm32 is 0x0d0c0b0a +run: SF=0; ZF=1; OF=0 :(scenario compare_imm32_with_mem_at_r32_greater) @@ -364,8 +378,9 @@ case 7: { # ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX) == 0x60 # data segment 0a 0b 0c 0d # 0x0d0c0b0a -+run: combine imm32 0x0d0c0b07 with r/m32 ++run: combine imm32 with r/m32 +run: effective address is 0x60 (EBX) ++run: imm32 is 0x0d0c0b07 +run: SF=0; ZF=0; OF=0 :(scenario compare_imm32_with_mem_at_r32_lesser) @@ -376,8 +391,9 @@ case 7: { # ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX) == 0x60 # data segment 07 0b 0c 0d # 0x0d0c0b07 -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: effective address is 0x60 (EBX) ++run: imm32 is 0x0d0c0b0a +run: SF=1; ZF=0; OF=0 :(scenario compare_imm32_with_mem_at_r32_equal) @@ -389,8 +405,9 @@ case 7: { # ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX) == 0x60 # data segment 0a 0b 0c 0d # 0x0d0c0b0a -+run: combine imm32 0x0d0c0b0a with r/m32 ++run: combine imm32 with r/m32 +run: effective address is 0x60 (EBX) ++run: imm32 is 0x0d0c0b0a +run: SF=0; ZF=1; OF=0 //:: copy (mov) @@ -438,15 +455,17 @@ put(name, "c7", "copy imm32 to rm32"); # op ModR/M SIB displacement immediate c7 03 0a 0b 0c 0d # copy 0x0d0c0b0a to *EBX # ModR/M in binary: 00 (indirect mode) 000 (unused) 011 (dest EBX) -+run: copy imm32 0x0d0c0b0a to r/m32 ++run: copy imm32 to r/m32 +run: effective address is 0x60 (EBX) ++run: imm32 is 0x0d0c0b0a :(before "End Single-Byte Opcodes") case 0xc7: { // copy imm32 to r32 uint8_t modrm = next(); - int32_t arg2 = imm32(); - trace(90, "run") << "copy imm32 0x" << HEXWORD << arg2 << " to r/m32" << end(); + trace(90, "run") << "copy imm32 to r/m32" << end(); int32_t* arg1 = effective_address(modrm); + int32_t arg2 = imm32(); + trace(90, "run") << "imm32 is 0x" << HEXWORD << arg2 << end(); *arg1 = arg2; break; } |