From 0cb988d0aed78773fe2c5eec3bc923794f629363 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 24 Jan 2018 12:59:14 -0800 Subject: 4185 --- subx/011direct_addressing.cc | 24 +++++++---- subx/012indirect_addressing.cc | 65 +++++++++++++++++++---------- subx/013immediate_addressing.cc | 90 +++++++++++++++++++++++++---------------- subx/014index_addressing.cc | 17 +++++--- subx/015jump_relative.cc | 28 ++++++------- subx/016jump_relative.cc | 28 ++++++------- subx/017functions.cc | 8 ++-- 7 files changed, 158 insertions(+), 102 deletions(-) diff --git a/subx/011direct_addressing.cc b/subx/011direct_addressing.cc index 46c24828..2a948626 100644 --- a/subx/011direct_addressing.cc +++ b/subx/011direct_addressing.cc @@ -50,6 +50,7 @@ int32_t* effective_address(uint8_t modrm) { % Reg[3].i = 1; # op ModR/M SIB displacement immediate 29 d8 # subtract EBX from EAX +# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) +run: subtract EBX from effective address +run: effective address is EAX +run: storing 0x00000009 @@ -71,6 +72,7 @@ case 0x29: { // subtract r32 from r/m32 % Reg[3].i = 0x000000ff; # op ModR/M SIB displacement immediate 21 d8 # and EBX with destination EAX +# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) +run: and EBX with effective address +run: effective address is EAX +run: storing 0x0000000d @@ -92,6 +94,7 @@ case 0x21: { // and r32 with r/m32 % Reg[3].i = 0xa0b0c0d0; # op ModR/M SIB displacement immediate 09 d8 # or EBX with destination EAX +# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) +run: or EBX with effective address +run: effective address is EAX +run: storing 0xaabbccdd @@ -113,6 +116,7 @@ case 0x09: { // or r32 with r/m32 % Reg[3].i = 0xaabbc0d0; # op ModR/M SIB displacement immediate 31 d8 # xor EBX with destination EAX +# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) +run: xor EBX with effective address +run: effective address is EAX +run: storing 0xa0b0ccdd @@ -133,6 +137,7 @@ case 0x31: { // xor r32 with r/m32 % Reg[3].i = 0x0f0f00ff; # op ModR/M SIB displacement immediate f7 c3 # not EBX +# ModR/M in binary: 11 (direct mode) 000 (unused) 011 (dest EBX) +run: 'not' of effective address +run: effective address is EBX +run: storing 0xf0f0ff00 @@ -155,8 +160,9 @@ case 0xf7: { // xor r32 with r/m32 :(scenario compare_r32_with_r32_greater) % Reg[0].i = 0x0a0b0c0d; % Reg[3].i = 0x0a0b0c07; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 39 d8 # compare EBX with EAX +# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) +run: compare EBX with effective address +run: effective address is EAX +run: SF=0; ZF=0; OF=0 @@ -180,8 +186,9 @@ case 0x39: { // set SF if r/m32 < r32 :(scenario compare_r32_with_r32_lesser) % Reg[0].i = 0x0a0b0c07; % Reg[3].i = 0x0a0b0c0d; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 39 d8 # compare EBX with EAX +# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) +run: compare EBX with effective address +run: effective address is EAX +run: SF=1; ZF=0; OF=0 @@ -189,8 +196,9 @@ case 0x39: { // set SF if r/m32 < r32 :(scenario compare_r32_with_r32_equal) % Reg[0].i = 0x0a0b0c0d; % Reg[3].i = 0x0a0b0c0d; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 39 d8 # compare EBX with EAX +# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) +run: compare EBX with effective address +run: effective address is EAX +run: SF=0; ZF=1; OF=0 @@ -199,8 +207,9 @@ case 0x39: { // set SF if r/m32 < r32 :(scenario copy_r32_to_r32) % Reg[3].i = 0xaf; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 89 d8 # copy EBX to EAX +# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) +run: copy EBX to effective address +run: effective address is EAX +run: storing 0x000000af @@ -221,8 +230,9 @@ case 0x89: { // copy r32 to r/m32 :(scenario xchg_r32_with_r32) % Reg[3].i = 0xaf; % Reg[0].i = 0x2e; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 87 d8 # exchange EBX with EAX +# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX) +run: exchange EBX with effective address +run: effective address is EAX +run: storing 0x000000af in effective address @@ -247,7 +257,7 @@ case 0x87: { // exchange r32 with r/m32 :(scenario push_r32) % Reg[ESP].u = 0x64; % Reg[EBX].i = 0x0000000a; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 53 # push EBX to stack +run: push EBX +run: decrementing ESP to 0x00000060 @@ -280,7 +290,7 @@ void push(uint32_t val) { :(scenario pop_r32) % Reg[ESP].u = 0x60; % SET_WORD_IN_MEM(0x60, 0x0000000a); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 5b # pop stack to EBX +run: pop into EBX +run: popping value 0x0000000a diff --git a/subx/012indirect_addressing.cc b/subx/012indirect_addressing.cc index f41bdfef..ca6843d4 100644 --- a/subx/012indirect_addressing.cc +++ b/subx/012indirect_addressing.cc @@ -6,15 +6,15 @@ % SET_WORD_IN_MEM(0x60, 1); # op ModR/M SIB displacement immediate 01 18 # add EBX to *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: add EBX to effective address +run: effective address is mem at address 0x60 (EAX) +run: storing 0x00000011 :(before "End Mod Special-cases") case 0: - // mod 0 is usually indirect addressing switch (rm) { - default: + default: // mod 0 is usually indirect addressing trace(2, "run") << "effective address is mem at address 0x" << std::hex << Reg[rm].u << " (" << rname(rm) << ")" << end(); assert(Reg[rm].u + sizeof(int32_t) <= Mem.size()); result = reinterpret_cast(&Mem.at(Reg[rm].u)); // rely on the host itself being in little-endian order @@ -31,6 +31,7 @@ case 0: % SET_WORD_IN_MEM(0x60, 1); # op ModR/M SIB displacement immediate 03 18 # add *EAX to EBX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: add effective address to EBX +run: effective address is mem at address 0x60 (EAX) +run: storing 0x00000011 @@ -51,8 +52,9 @@ case 0x03: { // add r/m32 to r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 10); % Reg[3].i = 1; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 29 18 # subtract EBX from *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: subtract EBX from effective address +run: effective address is mem at address 0x60 (EAX) +run: storing 0x00000009 @@ -63,8 +65,9 @@ case 0x03: { // add r/m32 to r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 1); % Reg[3].i = 10; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 2b 18 # subtract *EAX from EBX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: subtract effective address from EBX +run: effective address is mem at address 0x60 (EAX) +run: storing 0x00000009 @@ -85,8 +88,9 @@ case 0x2b: { // subtract r/m32 from r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); % Reg[3].i = 0xff; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 21 18 # and EBX with *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: and EBX with effective address +run: effective address is mem at address 0x60 (EAX) +run: storing 0x0000000d @@ -97,8 +101,9 @@ case 0x2b: { // subtract r/m32 from r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x000000ff); % Reg[3].i = 0x0a0b0c0d; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 23 18 # and *EAX with EBX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: and effective address with EBX +run: effective address is mem at address 0x60 (EAX) +run: storing 0x0000000d @@ -119,8 +124,9 @@ case 0x23: { // and r/m32 with r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); % Reg[3].i = 0xa0b0c0d0; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 09 18 # or EBX with *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: or EBX with effective address +run: effective address is mem at address 0x60 (EAX) +run: storing 0xaabbccdd @@ -131,8 +137,9 @@ case 0x23: { // and r/m32 with r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); % Reg[3].i = 0xa0b0c0d0; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0b 18 # or *EAX with EBX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: or effective address with EBX +run: effective address is mem at address 0x60 (EAX) +run: storing 0xaabbccdd @@ -153,8 +160,9 @@ case 0x0b: { // or r/m32 with r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0xaabb0c0d); % Reg[3].i = 0xa0b0c0d0; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 31 18 # xor EBX with *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: xor EBX with effective address +run: effective address is mem at address 0x60 (EAX) +run: storing 0x0a0bccdd @@ -165,8 +173,9 @@ case 0x0b: { // or r/m32 with r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); % Reg[3].i = 0xa0b0c0d0; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 33 18 # xor *EAX with EBX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: xor effective address with EBX +run: effective address is mem at address 0x60 (EAX) +run: storing 0xaabbccdd @@ -187,8 +196,9 @@ case 0x33: { // xor r/m32 with r32 % Reg[3].i = 0x60; # word at 0x60 is 0x0f0f00ff % SET_WORD_IN_MEM(0x60, 0x0f0f00ff); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate f7 03 # negate *EBX +# ModR/M in binary: 00 (indirect mode) 000 (unused) 011 (dest EBX) +run: 'not' of effective address +run: effective address is mem at address 0x60 (EBX) +run: storing 0xf0f0ff00 @@ -199,8 +209,9 @@ case 0x33: { // xor r/m32 with r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); % Reg[3].i = 0x0a0b0c07; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 39 18 # compare EBX with *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: compare EBX with effective address +run: effective address is mem at address 0x60 (EAX) +run: SF=0; ZF=0; OF=0 @@ -209,8 +220,9 @@ case 0x33: { // xor r/m32 with r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c07); % Reg[3].i = 0x0a0b0c0d; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 39 18 # compare EBX with *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: compare EBX with effective address +run: effective address is mem at address 0x60 (EAX) +run: SF=1; ZF=0; OF=0 @@ -219,8 +231,9 @@ case 0x33: { // xor r/m32 with r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); % Reg[3].i = 0x0a0b0c0d; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 39 18 # compare EBX with *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: compare EBX with effective address +run: effective address is mem at address 0x60 (EAX) +run: SF=0; ZF=1; OF=0 @@ -231,8 +244,9 @@ case 0x33: { // xor r/m32 with r32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c07); % Reg[3].i = 0x0a0b0c0d; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 3b 18 # compare *EAX with EBX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: compare effective address with EBX +run: effective address is mem at address 0x60 (EAX) +run: SF=0; ZF=0; OF=0 @@ -257,8 +271,9 @@ case 0x3b: { // set SF if r32 < r/m32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); % Reg[3].i = 0x0a0b0c07; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 3b 18 # compare *EAX with EBX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: compare effective address with EBX +run: effective address is mem at address 0x60 (EAX) +run: SF=1; ZF=0; OF=0 @@ -267,8 +282,9 @@ case 0x3b: { // set SF if r32 < r/m32 % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0a0b0c0d); % Reg[3].i = 0x0a0b0c0d; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 3b 18 # compare *EAX with EBX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: compare effective address with EBX +run: effective address is mem at address 0x60 (EAX) +run: SF=0; ZF=1; OF=0 @@ -278,8 +294,9 @@ case 0x3b: { // set SF if r32 < r/m32 :(scenario copy_r32_to_mem_at_r32) % Reg[3].i = 0xaf; % Reg[0].i = 0x60; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 89 18 # copy EBX to *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: copy EBX to effective address +run: effective address is mem at address 0x60 (EAX) +run: storing 0x000000af @@ -289,8 +306,9 @@ case 0x3b: { // set SF if r32 < r/m32 :(scenario copy_mem_at_r32_to_r32) % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x000000af); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 8b 18 # copy *EAX to EBX +# ModR/M in binary: 00 (indirect mode) 011 (src EAX) 000 (dest EAX) +run: copy effective address to EBX +run: effective address is mem at address 0x60 (EAX) +run: storing 0x000000af @@ -311,8 +329,9 @@ case 0x8b: { // copy r32 to r/m32 :(scenario jump_mem_at_r32) % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 8); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate ff 20 # jump to *EAX +# ModR/M in binary: 00 (indirect mode) 100 (jump to r/m32) 000 (src EAX) 05 00 00 00 01 05 00 00 00 02 +run: inst: 0x00000001 @@ -345,8 +364,9 @@ case 0xff: { % Reg[0].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x000000af); % Reg[ESP].u = 0x14; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate ff 30 # push *EAX to stack +# ModR/M in binary: 00 (indirect mode) 110 (push r/m32) 000 (src EAX) +run: push effective address +run: effective address is mem at address 0x60 (EAX) +run: decrementing ESP to 0x00000010 @@ -366,8 +386,9 @@ case 6: { // push r/m32 to stack % Reg[0].i = 0x60; % Reg[ESP].u = 0x10; % SET_WORD_IN_MEM(0x10, 0x00000030); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 8f 00 # pop stack into *EAX +# ModR/M in binary: 00 (indirect mode) 000 (pop r/m32) 000 (dest EAX) +run: pop into effective address +run: effective address is mem at address 0x60 (EAX) +run: popping value 0x00000030 diff --git a/subx/013immediate_addressing.cc b/subx/013immediate_addressing.cc index 3021617f..14099fee 100644 --- a/subx/013immediate_addressing.cc +++ b/subx/013immediate_addressing.cc @@ -2,8 +2,9 @@ :(scenario add_imm32_to_r32) % Reg[3].i = 1; -# op ModRM SIB displacement immediate +# 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 effective address +run: effective address is EBX +run: subop add @@ -36,6 +37,7 @@ case 0x81: { // combine imm32 with r/m32 % SET_WORD_IN_MEM(0x60, 1); # op ModR/M SIB displacement immediate 81 03 0a 0b 0c 0d # add 0x0d0c0b0a to *EBX +# ModR/M in binary: 00 (indirect mode) 000 (add imm32) 011 (dest EBX) +run: combine imm32 0x0d0c0b0a with effective address +run: effective address is mem at address 0x60 (EBX) +run: subop add @@ -63,31 +65,33 @@ case 0x2d: { // subtract imm32 from EAX :(scenario subtract_imm32_from_mem_at_r32) % Reg[3].i = 0x60; % SET_WORD_IN_MEM(0x60, 10); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 81 2b 01 00 00 00 # subtract 1 from *EBX +# ModR/M in binary: 00 (indirect mode) 101 (subtract imm32) 011 (dest EBX) +run: combine imm32 0x00000001 with effective address +run: effective address is mem at address 0x60 (EBX) +run: subop subtract +run: storing 0x00000009 +:(before "End Op 81 Subops") +case 5: { + trace(2, "run") << "subop subtract" << end(); + BINARY_ARITHMETIC_OP(-, *arg1, arg2); + break; +} + //: :(scenario subtract_imm32_from_r32) % Reg[3].i = 10; -# op ModRM SIB displacement immediate +# 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 effective address +run: effective address is EBX +run: subop subtract +run: storing 0x00000009 -:(before "End Op 81 Subops") -case 5: { - trace(2, "run") << "subop subtract" << end(); - BINARY_ARITHMETIC_OP(-, *arg1, arg2); - break; -} - //:: and :(scenario and_imm32_with_eax) @@ -110,31 +114,33 @@ case 0x25: { // and imm32 with EAX :(scenario and_imm32_with_mem_at_r32) % Reg[3].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x000000ff); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 81 23 0a 0b 0c 0d # and 0x0d0c0b0a with *EBX +# ModR/M in binary: 00 (indirect mode) 100 (and imm32) 011 (dest EBX) +run: combine imm32 0x0d0c0b0a with effective address +run: effective address is mem at address 0x60 (EBX) +run: subop and +run: storing 0x0000000a +:(before "End Op 81 Subops") +case 4: { + trace(2, "run") << "subop and" << end(); + BINARY_BITWISE_OP(&, *arg1, arg2); + break; +} + //: :(scenario and_imm32_with_r32) % Reg[3].i = 0xff; -# op ModRM SIB displacement immediate +# 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 effective address +run: effective address is EBX +run: subop and +run: storing 0x0000000a -:(before "End Op 81 Subops") -case 4: { - trace(2, "run") << "subop and" << end(); - BINARY_BITWISE_OP(&, *arg1, arg2); - break; -} - //:: or :(scenario or_imm32_with_eax) @@ -157,8 +163,9 @@ case 0x0d: { // or imm32 with EAX :(scenario or_imm32_with_mem_at_r32) % Reg[3].i = 0x60; % SET_WORD_IN_MEM(0x60, 0xd0c0b0a0); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 81 0b 0a 0b 0c 0d # or 0x0d0c0b0a with *EBX +# ModR/M in binary: 00 (indirect mode) 001 (or imm32) 011 (dest EBX) +run: combine imm32 0x0d0c0b0a with effective address +run: effective address is mem at address 0x60 (EBX) +run: subop or @@ -173,8 +180,9 @@ case 1: { :(scenario or_imm32_with_r32) % Reg[3].i = 0xd0c0b0a0; -# op ModRM SIB displacement immediate +# 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 effective address +run: effective address is EBX +run: subop or @@ -202,8 +210,9 @@ case 0x35: { // xor imm32 with EAX :(scenario xor_imm32_with_mem_at_r32) % Reg[3].i = 0x60; % SET_WORD_IN_MEM(0x60, 0xd0c0b0a0); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 81 33 0a 0b 0c 0d # xor 0x0d0c0b0a with *EBX +# ModR/M in binary: 00 (indirect mode) 110 (xor imm32) 011 (dest EBX) +run: combine imm32 0x0d0c0b0a with effective address +run: effective address is mem at address 0x60 (EBX) +run: subop xor @@ -218,8 +227,9 @@ case 6: { :(scenario xor_imm32_with_r32) % Reg[3].i = 0xd0c0b0a0; -# op ModRM SIB displacement immediate +# 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 effective address +run: effective address is EBX +run: subop xor @@ -229,7 +239,7 @@ case 6: { :(scenario compare_imm32_with_eax_greater) % Reg[0].i = 0x0d0c0b0a; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 3d 07 0b 0c 0d # compare 0x0d0c0b07 with EAX +run: compare EAX and imm32 0x0d0c0b07 +run: SF=0; ZF=0; OF=0 @@ -250,14 +260,14 @@ case 0x3d: { // subtract imm32 from EAX :(scenario compare_imm32_with_eax_lesser) % Reg[0].i = 0x0d0c0b07; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 3d 0a 0b 0c 0d # compare 0x0d0c0b0a with EAX +run: compare EAX and imm32 0x0d0c0b0a +run: SF=1; ZF=0; OF=0 :(scenario compare_imm32_with_eax_equal) % Reg[0].i = 0x0d0c0b0a; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 3d 0a 0b 0c 0d # compare 0x0d0c0b0a with EAX +run: compare EAX and imm32 0x0d0c0b0a +run: SF=0; ZF=1; OF=0 @@ -266,8 +276,9 @@ case 0x3d: { // subtract imm32 from EAX :(scenario compare_imm32_with_r32_greater) % Reg[3].i = 0x0d0c0b0a; -# op ModRM SIB displacement immediate +# 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 effective address +run: effective address is EBX +run: SF=0; ZF=0; OF=0 @@ -286,16 +297,20 @@ case 7: { :(scenario compare_imm32_with_r32_lesser) % Reg[3].i = 0x0d0c0b07; -# op ModRM SIB displacement immediate +# 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 0x0d0c0b07 with effective address +run: combine imm32 0x0d0c0b0a with effective address +run: effective address is EBX +run: SF=1; ZF=0; OF=0 :(scenario compare_imm32_with_r32_equal) % Reg[3].i = 0x0d0c0b0a; -# op ModRM SIB displacement immediate +# 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 0x0d0c0b07 with effective address +run: combine imm32 0x0d0c0b0a with effective address +run: effective address is EBX +run: SF=0; ZF=1; OF=0 @@ -303,8 +318,10 @@ case 7: { :(scenario compare_imm32_with_mem_at_r32_greater) % Reg[3].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0d0c0b0a); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 81 3b 07 0b 0c 0d # compare 0x0d0c0b07 with *EBX +# ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX) ++run: combine imm32 0x0d0c0b07 with effective address +run: combine imm32 0x0d0c0b07 with effective address +run: effective address is mem at address 0x60 (EBX) +run: SF=0; ZF=0; OF=0 @@ -312,8 +329,9 @@ case 7: { :(scenario compare_imm32_with_mem_at_r32_lesser) % Reg[3].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0d0c0b07); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 81 3b 0a 0b 0c 0d # compare 0x0d0c0b0a with *EBX +# ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX) +run: combine imm32 0x0d0c0b0a with effective address +run: effective address is mem at address 0x60 (EBX) +run: SF=1; ZF=0; OF=0 @@ -322,8 +340,9 @@ case 7: { % Reg[3].i = 0x0d0c0b0a; % Reg[3].i = 0x60; % SET_WORD_IN_MEM(0x60, 0x0d0c0b0a); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 81 3b 0a 0b 0c 0d # compare 0x0d0c0b0a with *EBX +# ModR/M in binary: 00 (indirect mode) 111 (compare imm32) 011 (dest EBX) +run: combine imm32 0x0d0c0b0a with effective address +run: effective address is mem at address 0x60 (EBX) +run: SF=0; ZF=1; OF=0 @@ -331,7 +350,7 @@ case 7: { //:: copy (mov) :(scenario copy_imm32_to_r32) -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate bb 0a 0b 0c 0d # copy 0x0d0c0b0a to EBX +run: copy imm32 0x0d0c0b0a to EBX @@ -355,8 +374,9 @@ case 0xbf: { // copy imm32 to r32 :(scenario copy_imm32_to_mem_at_r32) % Reg[3].i = 0x60; -# op ModRM SIB displacement immediate +# 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 effective address +run: effective address is mem at address 0x60 (EBX) @@ -374,7 +394,7 @@ case 0xc7: { // copy imm32 to r32 :(scenario push_imm32) % Reg[ESP].u = 0x14; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 68 af 00 00 00 # push *EAX to stack +run: push imm32 0x000000af +run: ESP is now 0x00000010 diff --git a/subx/014index_addressing.cc b/subx/014index_addressing.cc index 389808d1..4deff72a 100644 --- a/subx/014index_addressing.cc +++ b/subx/014index_addressing.cc @@ -6,22 +6,27 @@ % SET_WORD_IN_MEM(0x60, 1); # op ModR/M SIB displacement immediate 01 1c 20 # add EBX to *EAX +# ModR/M in binary: 00 (indirect mode) 011 (src EBX) 000 (dest EAX) # SIB in binary: 00 (scale 1) 100 (no index) 000 (base EAX) -# See Table 2-3 of the Intel programming manual. +run: add EBX to effective address +run: effective address is mem at address 0x60 (EAX) +run: storing 0x00000011 :(before "End Mod 0 Special-cases") -case 4: - // exception: SIB addressing +case 4: // exception: mod 0b00 rm 0b100 => incoming SIB (scale-index-base) byte uint8_t sib = next(); uint8_t base = sib&0x7; if (base == EBP) { - // This gets complicated. In the example below, do the two disp8's accumulate? multiply? cancel out?! + // Need to sometimes use a displacement either in addition to or in place + // of EBP. This gets complicated, and I don't understand interactions with + // displacement mode in Mod/RM. For example: + // // op (hex) ModR/M (binary) SIB (binary) displacement (hex) // 0x01 01 100 /*SIB+disp8*/ 000 /*EAX*/ 00 /*scale*/ 100 /*no index*/ 101 /*EBP+disp8*/ 0xf0 // + // Do the two disp8's accumulate (so the instruction has *two* disp8's)? + // multiply? cancel out?! + // // Maybe this is the answer: // "When the ModR/M or SIB tables state that a disp value is required.. // then the displacement bytes are required." @@ -43,15 +48,15 @@ case 4: } break; -:(scenario add_r32_to_mem_at_base_plus_index) +:(scenario add_r32_to_mem_at_base_r32_index_r32) % Reg[3].i = 0x10; // source % Reg[0].i = 0x5e; // dest base % Reg[1].i = 0x2; // dest index % SET_WORD_IN_MEM(0x60, 1); # op ModR/M SIB displacement immediate 01 1c 08 # add EBX to *(EAX+ECX) +# ModR/M in binary: 00 (indirect mode) 011 (src EBX) 000 (dest EAX) # SIB in binary: 00 (scale 1) 001 (index ECX) 000 (base EAX) -# See Table 2-3 of the Intel programming manual. +run: add EBX to effective address +run: effective address is mem at address 0x60 (EAX + ECX*1) +run: storing 0x00000011 diff --git a/subx/015jump_relative.cc b/subx/015jump_relative.cc index c9cdcd1b..2d3bbb2b 100644 --- a/subx/015jump_relative.cc +++ b/subx/015jump_relative.cc @@ -3,7 +3,7 @@ //:: jump :(scenario jump_rel8) -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate eb 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -24,7 +24,7 @@ case 0xeb: { // jump rel8 :(scenario je_rel8_success) % ZF = true; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 74 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -45,7 +45,7 @@ case 0x74: { // jump rel8 if ZF :(scenario je_rel8_fail) % ZF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 74 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -58,7 +58,7 @@ case 0x74: { // jump rel8 if ZF :(scenario jne_rel8_success) % ZF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 75 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -79,7 +79,7 @@ case 0x75: { // jump rel8 unless ZF :(scenario jne_rel8_fail) % ZF = true; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 75 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -94,7 +94,7 @@ case 0x75: { // jump rel8 unless ZF % ZF = false; % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 7f 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -117,7 +117,7 @@ case 0x7f: { // jump rel8 if !SF and !ZF % ZF = false; % SF = true; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 7f 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -131,7 +131,7 @@ case 0x7f: { // jump rel8 if !SF and !ZF :(scenario jge_rel8_success) % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 7d 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -153,7 +153,7 @@ case 0x7d: { // jump rel8 if !SF :(scenario jge_rel8_fail) % SF = true; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 7d 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -168,7 +168,7 @@ case 0x7d: { // jump rel8 if !SF % ZF = false; % SF = true; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 7c 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -191,7 +191,7 @@ case 0x7c: { // jump rel8 if SF and !ZF % ZF = false; % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 7c 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -206,7 +206,7 @@ case 0x7c: { // jump rel8 if SF and !ZF % ZF = true; % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 7e 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -219,7 +219,7 @@ case 0x7c: { // jump rel8 if SF and !ZF % ZF = false; % SF = true; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 7e 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -242,7 +242,7 @@ case 0x7e: { // jump rel8 if SF or ZF % ZF = false; % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 7e 05 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 diff --git a/subx/016jump_relative.cc b/subx/016jump_relative.cc index c4d92030..8b8452bb 100644 --- a/subx/016jump_relative.cc +++ b/subx/016jump_relative.cc @@ -3,7 +3,7 @@ //:: jump :(scenario jump_rel16) -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate e9 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -30,7 +30,7 @@ int16_t imm16() { :(scenario je_rel16_success) % ZF = true; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 84 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -51,7 +51,7 @@ case 0x84: { // jump rel16 if ZF :(scenario je_rel16_fail) % ZF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 84 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -64,7 +64,7 @@ case 0x84: { // jump rel16 if ZF :(scenario jne_rel16_success) % ZF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 85 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -85,7 +85,7 @@ case 0x85: { // jump rel16 unless ZF :(scenario jne_rel16_fail) % ZF = true; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 85 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -100,7 +100,7 @@ case 0x85: { // jump rel16 unless ZF % ZF = false; % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 8f 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -123,7 +123,7 @@ case 0x8f: { // jump rel16 if !SF and !ZF % ZF = false; % SF = true; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 8f 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -137,7 +137,7 @@ case 0x8f: { // jump rel16 if !SF and !ZF :(scenario jge_rel16_success) % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 8d 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -159,7 +159,7 @@ case 0x8d: { // jump rel16 if !SF :(scenario jge_rel16_fail) % SF = true; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 8d 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -174,7 +174,7 @@ case 0x8d: { // jump rel16 if !SF % ZF = false; % SF = true; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 8c 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -197,7 +197,7 @@ case 0x8c: { // jump rel16 if SF and !ZF % ZF = false; % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 8c 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -212,7 +212,7 @@ case 0x8c: { // jump rel16 if SF and !ZF % ZF = true; % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 8e 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -225,7 +225,7 @@ case 0x8c: { // jump rel16 if SF and !ZF % ZF = false; % SF = true; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 8e 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 @@ -248,7 +248,7 @@ case 0x8e: { // jump rel16 if SF or ZF % ZF = false; % SF = false; % OF = false; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate 0f 8e 05 00 # skip 1 instruction 05 00 00 00 01 05 00 00 00 02 diff --git a/subx/017functions.cc b/subx/017functions.cc index 774bbf42..cee11fc0 100644 --- a/subx/017functions.cc +++ b/subx/017functions.cc @@ -2,7 +2,7 @@ :(scenario call_imm32) % Reg[ESP].u = 0x64; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate e8 a0 00 00 00 # call function offset at 0x000000a0 # next EIP is 6 +run: call imm32 0x000000a0 @@ -25,7 +25,7 @@ case 0xe8: { // call imm32 relative to next EIP :(scenario call_r32) % Reg[ESP].u = 0x64; % Reg[EBX].u = 0x000000a0; -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate ff d3 # call function offset at EBX # next EIP is 3 +run: call to effective address @@ -48,7 +48,7 @@ case 2: { // call function pointer at r/m32 % Reg[ESP].u = 0x64; % Reg[EBX].u = 0x10; % SET_WORD_IN_MEM(0x10, 0x000000a0); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate ff 13 # call function offset at *EBX # next EIP is 3 +run: call to effective address @@ -62,7 +62,7 @@ case 2: { // call function pointer at r/m32 :(scenario ret) % Reg[ESP].u = 0x60; % SET_WORD_IN_MEM(0x60, 0x00000010); -# op ModRM SIB displacement immediate +# op ModR/M SIB displacement immediate c3 +run: return +run: popping value 0x00000010 -- cgit 1.4.1-2-gfad0