Start using data segments in scenarios.
This commit is contained in:
Kartik Agaram 2018-07-10 22:38:28 -07:00
parent c8c5065869
commit 39c0d1b1d5
5 changed files with 123 additions and 41 deletions

View File

@ -290,8 +290,11 @@ void push(uint32_t val) {
:(scenario pop_r32)
% Reg[ESP].u = 0x60;
% write_mem_i32(0x60, 0x0000000a);
== 0x1 # code segment
# op ModR/M SIB displacement immediate
5b # pop stack to EBX
== 0x60 # data segment
0a 00 00 00 # 0x0a
+run: pop into EBX
+run: popping value 0x0000000a
+run: incrementing ESP to 0x00000064

View File

@ -30,10 +30,12 @@ case 0: // indirect addressing
:(scenario add_mem_at_r32_to_r32)
% Reg[EAX].i = 0x60;
% Reg[EBX].i = 0x10;
% write_mem_i32(0x60, 1);
== 0x01 # code segment
# 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)
== 0x60 # data segment
01 00 00 00 # 1
+run: add r/m32 to EBX
+run: effective address is 0x60 (EAX)
+run: storing 0x00000011
@ -52,11 +54,13 @@ case 0x03: { // add r/m32 to r32
:(scenario subtract_r32_from_mem_at_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 10);
% Reg[EBX].i = 1;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0a 00 00 00 # 10
+run: subtract EBX from r/m32
+run: effective address is 0x60 (EAX)
+run: storing 0x00000009
@ -65,11 +69,13 @@ case 0x03: { // add r/m32 to r32
:(scenario subtract_mem_at_r32_from_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 1);
% Reg[EBX].i = 10;
== 0x01 # code segment
# 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)
== 0x60 # data segment
01 00 00 00 # 1
+run: subtract r/m32 from EBX
+run: effective address is 0x60 (EAX)
+run: storing 0x00000009
@ -88,11 +94,13 @@ case 0x2b: { // subtract r/m32 from r32
:(scenario and_r32_with_mem_at_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c0d);
% Reg[EBX].i = 0xff;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0d 0c 0b 0a # 0x0a0b0c0d
+run: and EBX with r/m32
+run: effective address is 0x60 (EAX)
+run: storing 0x0000000d
@ -101,11 +109,13 @@ case 0x2b: { // subtract r/m32 from r32
:(scenario and_mem_at_r32_with_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x000000ff);
% Reg[EBX].i = 0x0a0b0c0d;
== 0x01 # code segment
# 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)
== 0x60 # data segment
ff 00 00 00 # 0xff
+run: and r/m32 with EBX
+run: effective address is 0x60 (EAX)
+run: storing 0x0000000d
@ -124,11 +134,13 @@ case 0x23: { // and r/m32 with r32
:(scenario or_r32_with_mem_at_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c0d);
% Reg[EBX].i = 0xa0b0c0d0;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0d 0c 0b 0a # 0x0a0b0c0d
+run: or EBX with r/m32
+run: effective address is 0x60 (EAX)
+run: storing 0xaabbccdd
@ -137,11 +149,13 @@ case 0x23: { // and r/m32 with r32
:(scenario or_mem_at_r32_with_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c0d);
% Reg[EBX].i = 0xa0b0c0d0;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0d 0c 0b 0a # 0x0a0b0c0d
+run: or r/m32 with EBX
+run: effective address is 0x60 (EAX)
+run: storing 0xaabbccdd
@ -160,11 +174,13 @@ case 0x0b: { // or r/m32 with r32
:(scenario xor_r32_with_mem_at_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0xaabb0c0d);
% Reg[EBX].i = 0xa0b0c0d0;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0d 0c bb aa # 0xaabb0c0d
+run: xor EBX with r/m32
+run: effective address is 0x60 (EAX)
+run: storing 0x0a0bccdd
@ -173,11 +189,13 @@ case 0x0b: { // or r/m32 with r32
:(scenario xor_mem_at_r32_with_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c0d);
% Reg[EBX].i = 0xa0b0c0d0;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0d 0c 0b 0a # 0x0a0b0c0d
+run: xor r/m32 with EBX
+run: effective address is 0x60 (EAX)
+run: storing 0xaabbccdd
@ -196,11 +214,12 @@ case 0x33: { // xor r/m32 with r32
:(scenario not_r32_with_mem_at_r32)
% Reg[EBX].i = 0x60;
# word at 0x60 is 0x0f0f00ff
% write_mem_i32(0x60, 0x0f0f00ff);
== 0x01 # code segment
# op ModR/M SIB displacement immediate
f7 03 # negate *EBX
# ModR/M in binary: 00 (indirect mode) 000 (unused) 011 (dest EBX)
== 0x60 # data segment
ff 00 0f 0f # 0x0f0f00ff
+run: 'not' of r/m32
+run: effective address is 0x60 (EBX)
+run: storing 0xf0f0ff00
@ -209,33 +228,39 @@ case 0x33: { // xor r/m32 with r32
:(scenario compare_mem_at_r32_with_r32_greater)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c0d);
% Reg[EBX].i = 0x0a0b0c07;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0d 0c 0b 0a # 0x0a0b0c0d
+run: compare EBX with r/m32
+run: effective address is 0x60 (EAX)
+run: SF=0; ZF=0; OF=0
:(scenario compare_mem_at_r32_with_r32_lesser)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c07);
% Reg[EBX].i = 0x0a0b0c0d;
== 0x01 # code segment
# 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)
== 0x60 # data segment
07 0c 0b 0a # 0x0a0b0c0d
+run: compare EBX with r/m32
+run: effective address is 0x60 (EAX)
+run: SF=1; ZF=0; OF=0
:(scenario compare_mem_at_r32_with_r32_equal)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c0d);
% Reg[EBX].i = 0x0a0b0c0d;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0d 0c 0b 0a # 0x0a0b0c0d
+run: compare EBX with r/m32
+run: effective address is 0x60 (EAX)
+run: SF=0; ZF=1; OF=0
@ -244,11 +269,13 @@ case 0x33: { // xor r/m32 with r32
:(scenario compare_r32_with_mem_at_r32_greater)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c07);
% Reg[EBX].i = 0x0a0b0c0d;
== 0x01 # code segment
# 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)
== 0x60 # data segment
07 0c 0b 0a # 0x0a0b0c0d
+run: compare r/m32 with EBX
+run: effective address is 0x60 (EAX)
+run: SF=0; ZF=0; OF=0
@ -271,22 +298,26 @@ case 0x3b: { // set SF if r32 < r/m32
:(scenario compare_r32_with_mem_at_r32_lesser)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c0d);
% Reg[EBX].i = 0x0a0b0c07;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0d 0c 0b 0a # 0x0a0b0c0d
+run: compare r/m32 with EBX
+run: effective address is 0x60 (EAX)
+run: SF=1; ZF=0; OF=0
:(scenario compare_r32_with_mem_at_r32_equal)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x0a0b0c0d);
% Reg[EBX].i = 0x0a0b0c0d;
== 0x01 # code segment
# 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)
== 0x60 # data segment
0d 0c 0b 0a # 0x0a0b0c0d
+run: compare r/m32 with EBX
+run: effective address is 0x60 (EAX)
+run: SF=0; ZF=1; OF=0
@ -307,10 +338,12 @@ case 0x3b: { // set SF if r32 < r/m32
:(scenario copy_mem_at_r32_to_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x000000af);
== 0x01 # code segment
# 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)
== 0x60 # data segment
af 00 00 00 # 0xaf
+run: copy r/m32 to EBX
+run: effective address is 0x60 (EAX)
+run: storing 0x000000af
@ -330,12 +363,14 @@ case 0x8b: { // copy r32 to r/m32
:(scenario jump_mem_at_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 8);
== 0x01 # code segment
# 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
== 0x60 # data segment
08 00 00 00 # 8
+run: inst: 0x00000001
+run: jump to r/m32
+run: effective address is 0x60 (EAX)
@ -364,11 +399,13 @@ case 0xff: {
:(scenario push_mem_at_r32)
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 0x000000af);
% Reg[ESP].u = 0x14;
== 0x01 # code segment
# 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)
== 0x60 # data segment
af 00 00 00 # 0xaf
+run: push r/m32
+run: effective address is 0x60 (EAX)
+run: decrementing ESP to 0x00000010
@ -387,10 +424,12 @@ case 6: { // push r/m32 to stack
:(scenario pop_mem_at_r32)
% Reg[EAX].i = 0x60;
% Reg[ESP].u = 0x10;
% write_mem_i32(0x10, 0x00000030);
== 0x01 # code segment
# 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)
== 0x10 # data segment
30 00 00 00 # 0x30
+run: pop into r/m32
+run: effective address is 0x60 (EAX)
+run: popping value 0x00000030
@ -415,10 +454,12 @@ case 0x8f: { // pop stack into r/m32
:(scenario add_r32_to_mem_at_displacement)
% Reg[EBX].i = 0x10; // source
% write_mem_i32(0x60, 1);
== 0x01 # code segment
# op ModR/M SIB displacement immediate
01 1d 60 00 00 00 # add EBX to *0x60
# ModR/M in binary: 00 (indirect mode) 011 (src EBX) 101 (dest in disp32)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is 0x60 (disp32)
+run: storing 0x00000011
@ -434,10 +475,12 @@ case 5: // exception: mod 0b00 rm 0b101 => incoming disp32
:(scenario add_r32_to_mem_at_r32_plus_disp8)
% Reg[EBX].i = 0x10; // source
% Reg[EAX].i = 0x5e; // dest
% write_mem_i32(0x60, 1);
== 0x01 # code segment
# op ModR/M SIB displacement immediate
01 58 02 # add EBX to *(EAX+2)
# ModR/M in binary: 01 (indirect+disp8 mode) 011 (src EBX) 000 (dest EAX)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is initially 0x5e (EAX)
+run: effective address is 0x60 (after adding disp8)
@ -461,10 +504,12 @@ case 1: // indirect + disp8 addressing
:(scenario add_r32_to_mem_at_r32_plus_negative_disp8)
% Reg[EBX].i = 0x10; // source
% Reg[EAX].i = 0x61; // dest
% write_mem_i32(0x60, 1);
== 0x01 # code segment
# op ModR/M SIB displacement immediate
01 58 ff # add EBX to *(EAX-1)
# ModR/M in binary: 01 (indirect+disp8 mode) 011 (src EBX) 000 (dest EAX)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is initially 0x61 (EAX)
+run: effective address is 0x60 (after adding disp8)
@ -475,10 +520,12 @@ case 1: // indirect + disp8 addressing
:(scenario add_r32_to_mem_at_r32_plus_disp32)
% Reg[EBX].i = 0x10; // source
% Reg[EAX].i = 0x5e; // dest
% write_mem_i32(0x60, 1);
== 0x01 # code segment
# op ModR/M SIB displacement immediate
01 98 02 00 00 00 # add EBX to *(EAX+2)
# ModR/M in binary: 10 (indirect+disp32 mode) 011 (src EBX) 000 (dest EAX)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is initially 0x5e (EAX)
+run: effective address is 0x60 (after adding disp32)
@ -502,10 +549,12 @@ case 2: // indirect + disp32 addressing
:(scenario add_r32_to_mem_at_r32_plus_negative_disp32)
% Reg[EBX].i = 0x10; // source
% Reg[EAX].i = 0x61; // dest
% write_mem_i32(0x60, 1);
== 0x01 # code segment
# op ModR/M SIB displacement immediate
01 98 ff ff ff ff # add EBX to *(EAX-1)
# ModR/M in binary: 10 (indirect+disp32 mode) 011 (src EBX) 000 (dest EAX)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is initially 0x61 (EAX)
+run: effective address is 0x60 (after adding disp32)

View File

@ -34,10 +34,12 @@ case 0x81: { // combine imm32 with r/m32
:(scenario add_imm32_to_mem_at_r32)
% Reg[EBX].i = 0x60;
% write_mem_i32(0x60, 1);
== 0x01 # code segment
# 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)
== 0x60 # data segment
01 00 00 00 # 1
+run: combine imm32 0x0d0c0b0a with r/m32
+run: effective address is 0x60 (EBX)
+run: subop add
@ -64,10 +66,12 @@ case 0x2d: { // subtract imm32 from EAX
:(scenario subtract_imm32_from_mem_at_r32)
% Reg[EBX].i = 0x60;
% write_mem_i32(0x60, 10);
== 0x01 # code segment
# 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)
== 0x60 # data segment
0a 00 00 00 # 10
+run: combine imm32 0x00000001 with r/m32
+run: effective address is 0x60 (EBX)
+run: subop subtract
@ -113,10 +117,12 @@ case 0x25: { // and imm32 with EAX
:(scenario and_imm32_with_mem_at_r32)
% Reg[EBX].i = 0x60;
% write_mem_i32(0x60, 0x000000ff);
== 0x01 # code segment
# 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)
== 0x60 # data segment
ff 00 00 00 # 0xff
+run: combine imm32 0x0d0c0b0a with r/m32
+run: effective address is 0x60 (EBX)
+run: subop and
@ -162,10 +168,12 @@ case 0x0d: { // or imm32 with EAX
:(scenario or_imm32_with_mem_at_r32)
% Reg[EBX].i = 0x60;
% write_mem_i32(0x60, 0xd0c0b0a0);
== 0x01 # code segment
# 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)
== 0x60 # data segment
a0 b0 c0 d0 # 0xd0c0b0a0
+run: combine imm32 0x0d0c0b0a with r/m32
+run: effective address is 0x60 (EBX)
+run: subop or
@ -209,10 +217,12 @@ case 0x35: { // xor imm32 with EAX
:(scenario xor_imm32_with_mem_at_r32)
% Reg[EBX].i = 0x60;
% write_mem_i32(0x60, 0xd0c0b0a0);
== 0x01 # code segment
# 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)
== 0x60 # data segment
a0 b0 c0 d0 # 0xd0c0b0a0
+run: combine imm32 0x0d0c0b0a with r/m32
+run: effective address is 0x60 (EBX)
+run: subop xor
@ -315,20 +325,24 @@ case 7: {
:(scenario compare_imm32_with_mem_at_r32_greater)
% Reg[EBX].i = 0x60;
% write_mem_i32(0x60, 0x0d0c0b0a);
== 0x01 # code segment
# 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)
== 0x60 # data segment
0a 0b 0c 0d # 0x0d0c0b0a
+run: combine imm32 0x0d0c0b07 with r/m32
+run: effective address is 0x60 (EBX)
+run: SF=0; ZF=0; OF=0
:(scenario compare_imm32_with_mem_at_r32_lesser)
% Reg[EBX].i = 0x60;
% write_mem_i32(0x60, 0x0d0c0b07);
== 0x01 # code segment
# 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)
== 0x60 # data segment
07 0b 0c 0d # 0x0d0c0b07
+run: combine imm32 0x0d0c0b0a with r/m32
+run: effective address is 0x60 (EBX)
+run: SF=1; ZF=0; OF=0
@ -336,10 +350,12 @@ case 7: {
:(scenario compare_imm32_with_mem_at_r32_equal)
% Reg[EBX].i = 0x0d0c0b0a;
% Reg[EBX].i = 0x60;
% write_mem_i32(0x60, 0x0d0c0b0a);
== 0x01 # code segment
# 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)
== 0x60 # data segment
0a 0b 0c 0d # 0x0d0c0b0a
+run: combine imm32 0x0d0c0b0a with r/m32
+run: effective address is 0x60 (EBX)
+run: SF=0; ZF=1; OF=0

View File

@ -3,11 +3,13 @@
:(scenario add_r32_to_mem_at_r32_with_sib)
% Reg[EBX].i = 0x10;
% Reg[EAX].i = 0x60;
% write_mem_i32(0x60, 1);
== 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)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is initially 0x60 (EAX)
+run: effective address is 0x60
@ -48,11 +50,13 @@ uint32_t effective_address_from_sib(uint8_t mod) {
% Reg[EBX].i = 0x10; // source
% Reg[EAX].i = 0x5e; // dest base
% Reg[ECX].i = 0x2; // dest index
% write_mem_i32(0x60, 1);
== 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)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is initially 0x5e (EAX)
+run: effective address is 0x60 (after adding ECX*1)
@ -60,11 +64,13 @@ uint32_t effective_address_from_sib(uint8_t mod) {
:(scenario add_r32_to_mem_at_displacement_using_sib)
% Reg[EBX].i = 0x10; // source
% write_mem_i32(0x60, 1);
== 0x1 # code segment
# op ModR/M SIB displacement immediate
01 1c 25 60 00 00 00 # add EBX to *0x60
# 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)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is initially 0x60 (disp32)
+run: effective address is 0x60
@ -76,11 +82,13 @@ uint32_t effective_address_from_sib(uint8_t mod) {
% Reg[EBX].i = 0x10; // source
% Reg[EAX].i = 0x59; // dest base
% Reg[ECX].i = 0x5; // dest index
% write_mem_i32(0x60, 1);
== 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)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is initially 0x59 (EAX)
+run: effective address is 0x5e (after adding ECX*1)
@ -98,11 +106,13 @@ case 4: // exception: mod 0b01 rm 0b100 => incoming SIB (scale-index-base) byte
% Reg[EBX].i = 0x10; // source
% Reg[EAX].i = 0x59; // dest base
% Reg[ECX].i = 0x5; // dest index
% write_mem_i32(0x60, 1);
== 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)
== 0x60 # data segment
01 00 00 00 # 1
+run: add EBX to r/m32
+run: effective address is initially 0x59 (EAX)
+run: effective address is 0x5e (after adding ECX*1)

View File

@ -47,10 +47,12 @@ case 2: { // call function pointer at r/m32
:(scenario call_mem_at_r32)
% Reg[ESP].u = 0x64;
% Reg[EBX].u = 0x10;
% write_mem_i32(0x10, 0x000000a0);
== 0x1 # code segment
# op ModR/M SIB displacement immediate
ff 13 # call function offset at *EBX
# next EIP is 3
== 0x10 # data segment
a0 00 00 00 # 0xa0
+run: call to r/m32
+run: effective address is 0x10 (EBX)
+run: decrementing ESP to 0x00000060
@ -61,9 +63,11 @@ case 2: { // call function pointer at r/m32
:(scenario ret)
% Reg[ESP].u = 0x60;
% write_mem_i32(0x60, 0x00000010);
== 0x1 # code segment
# op ModR/M SIB displacement immediate
c3
== 0x60 # data segment
10 00 00 00 # 0x10
+run: return
+run: popping value 0x00000010
+run: jumping to 0x00000010