diff options
Diffstat (limited to 'subx/016index_addressing.cc')
-rw-r--r-- | subx/016index_addressing.cc | 178 |
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 |