parent
c8c5065869
commit
39c0d1b1d5
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue