4189
This commit is contained in:
parent
631de5d981
commit
871ea368d1
|
@ -6,15 +6,15 @@
|
|||
# op ModR/M SIB displacement immediate
|
||||
01 d8 # add EBX to EAX
|
||||
# ModR/M in binary: 11 (direct mode) 011 (src EBX) 000 (dest EAX)
|
||||
+run: add EBX to effective address
|
||||
+run: effective address is EAX
|
||||
+run: add EBX to r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: storing 0x00000011
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x01: { // add r32 to r/m32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg2 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "add " << rname(arg2) << " to effective address" << end();
|
||||
trace(2, "run") << "add " << rname(arg2) << " to r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
BINARY_ARITHMETIC_OP(+, *arg1, Reg[arg2].i);
|
||||
break;
|
||||
|
@ -32,7 +32,7 @@ int32_t* effective_address(uint8_t modrm) {
|
|||
switch (mod) {
|
||||
case 3:
|
||||
// mod 3 is just register direct addressing
|
||||
trace(2, "run") << "effective address is " << rname(rm) << end();
|
||||
trace(2, "run") << "r/m32 is " << rname(rm) << end();
|
||||
result = &Reg[rm].i;
|
||||
break;
|
||||
// End Mod Special-cases
|
||||
|
@ -51,15 +51,15 @@ int32_t* effective_address(uint8_t modrm) {
|
|||
# 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: subtract EBX from r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: storing 0x00000009
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x29: { // subtract r32 from r/m32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg2 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "subtract " << rname(arg2) << " from effective address" << end();
|
||||
trace(2, "run") << "subtract " << rname(arg2) << " from r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
BINARY_ARITHMETIC_OP(-, *arg1, Reg[arg2].i);
|
||||
break;
|
||||
|
@ -73,15 +73,15 @@ case 0x29: { // subtract r32 from r/m32
|
|||
# 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: and EBX with r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: storing 0x0000000d
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x21: { // and r32 with r/m32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg2 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "and " << rname(arg2) << " with effective address" << end();
|
||||
trace(2, "run") << "and " << rname(arg2) << " with r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
BINARY_BITWISE_OP(&, *arg1, Reg[arg2].u);
|
||||
break;
|
||||
|
@ -95,15 +95,15 @@ case 0x21: { // and r32 with r/m32
|
|||
# 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: or EBX with r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: storing 0xaabbccdd
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x09: { // or r32 with r/m32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg2 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "or " << rname(arg2) << " with effective address" << end();
|
||||
trace(2, "run") << "or " << rname(arg2) << " with r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
BINARY_BITWISE_OP(|, *arg1, Reg[arg2].u);
|
||||
break;
|
||||
|
@ -117,15 +117,15 @@ case 0x09: { // or r32 with r/m32
|
|||
# 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: xor EBX with r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: storing 0xa0b0ccdd
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x31: { // xor r32 with r/m32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg2 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "xor " << rname(arg2) << " with effective address" << end();
|
||||
trace(2, "run") << "xor " << rname(arg2) << " with r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
BINARY_BITWISE_OP(^, *arg1, Reg[arg2].u);
|
||||
break;
|
||||
|
@ -138,14 +138,14 @@ case 0x31: { // xor r32 with r/m32
|
|||
# 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: 'not' of r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: storing 0xf0f0ff00
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0xf7: { // xor r32 with r/m32
|
||||
uint8_t modrm = next();
|
||||
trace(2, "run") << "'not' of effective address" << end();
|
||||
trace(2, "run") << "'not' of r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
*arg1 = ~(*arg1);
|
||||
trace(2, "run") << "storing 0x" << HEXWORD << *arg1 << end();
|
||||
|
@ -163,15 +163,15 @@ case 0xf7: { // xor r32 with r/m32
|
|||
# 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: compare EBX with r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: SF=0; ZF=0; OF=0
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x39: { // set SF if r/m32 < r32
|
||||
uint8_t modrm = next();
|
||||
uint8_t reg2 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "compare " << rname(reg2) << " with effective address" << end();
|
||||
trace(2, "run") << "compare " << rname(reg2) << " with r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
int32_t arg2 = Reg[reg2].i;
|
||||
int32_t tmp1 = *arg1 - arg2;
|
||||
|
@ -189,8 +189,8 @@ case 0x39: { // set SF if r/m32 < r32
|
|||
# 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: compare EBX with r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: SF=1; ZF=0; OF=0
|
||||
|
||||
:(scenario compare_r32_with_r32_equal)
|
||||
|
@ -199,8 +199,8 @@ case 0x39: { // set SF if r/m32 < r32
|
|||
# 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: compare EBX with r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: SF=0; ZF=1; OF=0
|
||||
|
||||
//:: copy (mov)
|
||||
|
@ -210,15 +210,15 @@ case 0x39: { // set SF if r/m32 < r32
|
|||
# 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: copy EBX to r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: storing 0x000000af
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x89: { // copy r32 to r/m32
|
||||
uint8_t modrm = next();
|
||||
uint8_t reg2 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "copy " << rname(reg2) << " to effective address" << end();
|
||||
trace(2, "run") << "copy " << rname(reg2) << " to r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
*arg1 = Reg[reg2].i;
|
||||
trace(2, "run") << "storing 0x" << HEXWORD << *arg1 << end();
|
||||
|
@ -233,21 +233,21 @@ case 0x89: { // copy r32 to r/m32
|
|||
# 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
|
||||
+run: exchange EBX with r/m32
|
||||
+run: r/m32 is EAX
|
||||
+run: storing 0x000000af in r/m32
|
||||
+run: storing 0x0000002e in EBX
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x87: { // exchange r32 with r/m32
|
||||
uint8_t modrm = next();
|
||||
uint8_t reg2 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "exchange " << rname(reg2) << " with effective address" << end();
|
||||
trace(2, "run") << "exchange " << rname(reg2) << " with r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
int32_t tmp = *arg1;
|
||||
*arg1 = Reg[reg2].i;
|
||||
Reg[reg2].i = tmp;
|
||||
trace(2, "run") << "storing 0x" << HEXWORD << *arg1 << " in effective address" << end();
|
||||
trace(2, "run") << "storing 0x" << HEXWORD << *arg1 << " in r/m32" << end();
|
||||
trace(2, "run") << "storing 0x" << HEXWORD << Reg[reg2].i << " in " << rname(reg2) << end();
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -7,15 +7,15 @@
|
|||
# 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: add EBX to r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x00000011
|
||||
|
||||
:(before "End Mod Special-cases")
|
||||
case 0:
|
||||
switch (rm) {
|
||||
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();
|
||||
trace(2, "run") << "effective address is 0x" << std::hex << Reg[rm].u << " (" << rname(rm) << ")" << end();
|
||||
assert(Reg[rm].u + sizeof(int32_t) <= Mem.size());
|
||||
result = reinterpret_cast<int32_t*>(&Mem.at(Reg[rm].u)); // rely on the host itself being in little-endian order
|
||||
break;
|
||||
|
@ -32,15 +32,15 @@ case 0:
|
|||
# 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: add r/m32 to EBX
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x00000011
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x03: { // add r/m32 to r32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg1 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "add effective address to " << rname(arg1) << end();
|
||||
trace(2, "run") << "add r/m32 to " << rname(arg1) << end();
|
||||
const int32_t* arg2 = effective_address(modrm);
|
||||
BINARY_ARITHMETIC_OP(+, Reg[arg1].i, *arg2);
|
||||
break;
|
||||
|
@ -55,8 +55,8 @@ case 0x03: { // add r/m32 to r32
|
|||
# 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: subtract EBX from r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x00000009
|
||||
|
||||
//:
|
||||
|
@ -68,15 +68,15 @@ case 0x03: { // add r/m32 to r32
|
|||
# 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: subtract r/m32 from EBX
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x00000009
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x2b: { // subtract r/m32 from r32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg1 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "subtract effective address from " << rname(arg1) << end();
|
||||
trace(2, "run") << "subtract r/m32 from " << rname(arg1) << end();
|
||||
const int32_t* arg2 = effective_address(modrm);
|
||||
BINARY_ARITHMETIC_OP(-, Reg[arg1].i, *arg2);
|
||||
break;
|
||||
|
@ -91,8 +91,8 @@ case 0x2b: { // subtract r/m32 from r32
|
|||
# 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: and EBX with r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x0000000d
|
||||
|
||||
//:
|
||||
|
@ -104,15 +104,15 @@ case 0x2b: { // subtract r/m32 from r32
|
|||
# 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: and r/m32 with EBX
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x0000000d
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x23: { // and r/m32 with r32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg1 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "and effective address with " << rname(arg1) << end();
|
||||
trace(2, "run") << "and r/m32 with " << rname(arg1) << end();
|
||||
const int32_t* arg2 = effective_address(modrm);
|
||||
BINARY_BITWISE_OP(&, Reg[arg1].u, *arg2);
|
||||
break;
|
||||
|
@ -127,8 +127,8 @@ case 0x23: { // and r/m32 with r32
|
|||
# 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: or EBX with r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0xaabbccdd
|
||||
|
||||
//:
|
||||
|
@ -140,15 +140,15 @@ case 0x23: { // and r/m32 with r32
|
|||
# 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: or r/m32 with EBX
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0xaabbccdd
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x0b: { // or r/m32 with r32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg1 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "or effective address with " << rname(arg1) << end();
|
||||
trace(2, "run") << "or r/m32 with " << rname(arg1) << end();
|
||||
const int32_t* arg2 = effective_address(modrm);
|
||||
BINARY_BITWISE_OP(|, Reg[arg1].u, *arg2);
|
||||
break;
|
||||
|
@ -163,8 +163,8 @@ case 0x0b: { // or r/m32 with r32
|
|||
# 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: xor EBX with r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x0a0bccdd
|
||||
|
||||
//:
|
||||
|
@ -176,15 +176,15 @@ case 0x0b: { // or r/m32 with r32
|
|||
# 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: xor r/m32 with EBX
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0xaabbccdd
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x33: { // xor r/m32 with r32
|
||||
uint8_t modrm = next();
|
||||
uint8_t arg1 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "xor effective address with " << rname(arg1) << end();
|
||||
trace(2, "run") << "xor r/m32 with " << rname(arg1) << end();
|
||||
const int32_t* arg2 = effective_address(modrm);
|
||||
BINARY_BITWISE_OP(|, Reg[arg1].u, *arg2);
|
||||
break;
|
||||
|
@ -199,8 +199,8 @@ case 0x33: { // xor r/m32 with r32
|
|||
# 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: 'not' of r/m32
|
||||
+run: effective address is 0x60 (EBX)
|
||||
+run: storing 0xf0f0ff00
|
||||
|
||||
//:: compare (cmp)
|
||||
|
@ -212,8 +212,8 @@ case 0x33: { // xor r/m32 with r32
|
|||
# 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: 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)
|
||||
|
@ -223,8 +223,8 @@ case 0x33: { // xor r/m32 with r32
|
|||
# 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: 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)
|
||||
|
@ -234,8 +234,8 @@ case 0x33: { // xor r/m32 with r32
|
|||
# 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: compare EBX with r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: SF=0; ZF=1; OF=0
|
||||
|
||||
//:
|
||||
|
@ -247,15 +247,15 @@ case 0x33: { // xor r/m32 with r32
|
|||
# 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: compare r/m32 with EBX
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: SF=0; ZF=0; OF=0
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x3b: { // set SF if r32 < r/m32
|
||||
uint8_t modrm = next();
|
||||
uint8_t reg1 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "compare effective address with " << rname(reg1) << end();
|
||||
trace(2, "run") << "compare r/m32 with " << rname(reg1) << end();
|
||||
int32_t arg1 = Reg[reg1].i;
|
||||
int32_t* arg2 = effective_address(modrm);
|
||||
int32_t tmp1 = arg1 - *arg2;
|
||||
|
@ -274,8 +274,8 @@ case 0x3b: { // set SF if r32 < r/m32
|
|||
# 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: 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)
|
||||
|
@ -285,8 +285,8 @@ case 0x3b: { // set SF if r32 < r/m32
|
|||
# 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: compare r/m32 with EBX
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: SF=0; ZF=1; OF=0
|
||||
|
||||
//:: copy (mov)
|
||||
|
@ -297,8 +297,8 @@ case 0x3b: { // set SF if r32 < r/m32
|
|||
# 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: copy EBX to r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x000000af
|
||||
|
||||
//:
|
||||
|
@ -309,15 +309,15 @@ case 0x3b: { // set SF if r32 < r/m32
|
|||
# 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: copy r/m32 to EBX
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x000000af
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0x8b: { // copy r32 to r/m32
|
||||
uint8_t modrm = next();
|
||||
uint8_t reg1 = (modrm>>3)&0x7;
|
||||
trace(2, "run") << "copy effective address to " << rname(reg1) << end();
|
||||
trace(2, "run") << "copy r/m32 to " << rname(reg1) << end();
|
||||
int32_t* arg2 = effective_address(modrm);
|
||||
Reg[reg1].i = *arg2;
|
||||
trace(2, "run") << "storing 0x" << HEXWORD << *arg2 << end();
|
||||
|
@ -335,8 +335,8 @@ case 0x8b: { // copy r32 to r/m32
|
|||
05 00 00 00 01
|
||||
05 00 00 00 02
|
||||
+run: inst: 0x00000001
|
||||
+run: jump to effective address
|
||||
+run: effective address is mem at address 0x60 (EAX)
|
||||
+run: jump to r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: jumping to 0x00000008
|
||||
+run: inst: 0x00000008
|
||||
-run: inst: 0x00000003
|
||||
|
@ -347,7 +347,7 @@ case 0xff: {
|
|||
uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits
|
||||
switch (subop) {
|
||||
case 4: { // jump to r/m32
|
||||
trace(2, "run") << "jump to effective address" << end();
|
||||
trace(2, "run") << "jump to r/m32" << end();
|
||||
int32_t* arg2 = effective_address(modrm);
|
||||
EIP = *arg2;
|
||||
trace(2, "run") << "jumping to 0x" << HEXWORD << EIP << end();
|
||||
|
@ -367,14 +367,14 @@ case 0xff: {
|
|||
# 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: push r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: decrementing ESP to 0x00000010
|
||||
+run: pushing value 0x000000af
|
||||
|
||||
:(before "End Op ff Subops")
|
||||
case 6: { // push r/m32 to stack
|
||||
trace(2, "run") << "push effective address" << end();
|
||||
trace(2, "run") << "push r/m32" << end();
|
||||
const int32_t* val = effective_address(modrm);
|
||||
push(*val);
|
||||
break;
|
||||
|
@ -389,8 +389,8 @@ case 6: { // push r/m32 to stack
|
|||
# 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: pop into r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: popping value 0x00000030
|
||||
+run: incrementing ESP to 0x00000014
|
||||
|
||||
|
@ -400,7 +400,7 @@ case 0x8f: { // pop stack into r/m32
|
|||
uint8_t subop = (modrm>>3)&0x7;
|
||||
switch (subop) {
|
||||
case 0: {
|
||||
trace(2, "run") << "pop into effective address" << end();
|
||||
trace(2, "run") << "pop into r/m32" << end();
|
||||
int32_t* dest = effective_address(modrm);
|
||||
*dest = pop();
|
||||
break;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
# 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: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: subop add
|
||||
+run: storing 0x0d0c0b0b
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
|||
case 0x81: { // combine imm32 with r/m32
|
||||
uint8_t modrm = next();
|
||||
int32_t arg2 = imm32();
|
||||
trace(2, "run") << "combine imm32 0x" << HEXWORD << arg2 << " with effective address" << end();
|
||||
trace(2, "run") << "combine imm32 0x" << HEXWORD << arg2 << " with r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits
|
||||
switch (subop) {
|
||||
|
@ -38,8 +38,8 @@ case 0x81: { // combine imm32 with r/m32
|
|||
# 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: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: effective address is 0x60 (EBX)
|
||||
+run: subop add
|
||||
+run: storing 0x0d0c0b0b
|
||||
|
||||
|
@ -68,8 +68,8 @@ case 0x2d: { // subtract imm32 from EAX
|
|||
# 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: combine imm32 0x00000001 with r/m32
|
||||
+run: effective address is 0x60 (EBX)
|
||||
+run: subop subtract
|
||||
+run: storing 0x00000009
|
||||
|
||||
|
@ -87,8 +87,8 @@ 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 effective address
|
||||
+run: effective address is EBX
|
||||
+run: combine imm32 0x00000001 with r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: subop subtract
|
||||
+run: storing 0x00000009
|
||||
|
||||
|
@ -117,8 +117,8 @@ case 0x25: { // and imm32 with EAX
|
|||
# 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: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: effective address is 0x60 (EBX)
|
||||
+run: subop and
|
||||
+run: storing 0x0000000a
|
||||
|
||||
|
@ -136,8 +136,8 @@ 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 effective address
|
||||
+run: effective address is EBX
|
||||
+run: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: subop and
|
||||
+run: storing 0x0000000a
|
||||
|
||||
|
@ -166,8 +166,8 @@ case 0x0d: { // or imm32 with EAX
|
|||
# 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: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: effective address is 0x60 (EBX)
|
||||
+run: subop or
|
||||
+run: storing 0xddccbbaa
|
||||
|
||||
|
@ -183,8 +183,8 @@ 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 effective address
|
||||
+run: effective address is EBX
|
||||
+run: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: subop or
|
||||
+run: storing 0xddccbbaa
|
||||
|
||||
|
@ -213,8 +213,8 @@ case 0x35: { // xor imm32 with EAX
|
|||
# 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: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: effective address is 0x60 (EBX)
|
||||
+run: subop xor
|
||||
+run: storing 0xddccbbaa
|
||||
|
||||
|
@ -230,8 +230,8 @@ 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 effective address
|
||||
+run: effective address is EBX
|
||||
+run: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: subop xor
|
||||
+run: storing 0xddccbbaa
|
||||
|
||||
|
@ -279,8 +279,8 @@ 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 effective address
|
||||
+run: effective address is EBX
|
||||
+run: combine imm32 0x0d0c0b07 with r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: SF=0; ZF=0; OF=0
|
||||
|
||||
:(before "End Op 81 Subops")
|
||||
|
@ -300,8 +300,8 @@ 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 effective address
|
||||
+run: effective address is EBX
|
||||
+run: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: SF=1; ZF=0; OF=0
|
||||
|
||||
:(scenario compare_imm32_with_r32_equal)
|
||||
|
@ -309,8 +309,8 @@ 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 effective address
|
||||
+run: effective address is EBX
|
||||
+run: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: SF=0; ZF=1; OF=0
|
||||
|
||||
:(scenario compare_imm32_with_mem_at_r32_greater)
|
||||
|
@ -319,8 +319,8 @@ case 7: {
|
|||
# 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: effective address is mem at address 0x60 (EBX)
|
||||
+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)
|
||||
|
@ -329,8 +329,8 @@ case 7: {
|
|||
# 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: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: effective address is 0x60 (EBX)
|
||||
+run: SF=1; ZF=0; OF=0
|
||||
|
||||
:(scenario compare_imm32_with_mem_at_r32_equal)
|
||||
|
@ -340,8 +340,8 @@ case 7: {
|
|||
# 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: combine imm32 0x0d0c0b0a with r/m32
|
||||
+run: effective address is 0x60 (EBX)
|
||||
+run: SF=0; ZF=1; OF=0
|
||||
|
||||
//:: copy (mov)
|
||||
|
@ -374,14 +374,14 @@ case 0xbf: { // copy imm32 to r32
|
|||
# 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)
|
||||
+run: copy imm32 0x0d0c0b0a to r/m32
|
||||
+run: effective address is 0x60 (EBX)
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0xc7: { // copy imm32 to r32
|
||||
uint8_t modrm = next();
|
||||
int32_t arg2 = imm32();
|
||||
trace(2, "run") << "copy imm32 0x" << HEXWORD << arg2 << " to effective address" << end();
|
||||
trace(2, "run") << "copy imm32 0x" << HEXWORD << arg2 << " to r/m32" << end();
|
||||
int32_t* arg1 = effective_address(modrm);
|
||||
*arg1 = arg2;
|
||||
break;
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
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)
|
||||
+run: add EBX to effective address
|
||||
+run: effective address is mem at address 0x60 (EAX)
|
||||
+run: add EBX to r/m32
|
||||
+run: effective address is 0x60 (EAX)
|
||||
+run: storing 0x00000011
|
||||
|
||||
:(before "End Mod 0 Special-cases")
|
||||
|
@ -45,13 +45,13 @@ uint32_t effective_address_from_sib(uint8_t mod) {
|
|||
uint8_t index = (sib>>3)&0x7;
|
||||
if (index == ESP) {
|
||||
// ignore index and scale
|
||||
trace(2, "run") << "effective address is mem at address 0x" << std::hex << Reg[base].u << " (" << rname(base) << ")" << end();
|
||||
trace(2, "run") << "effective address is 0x" << std::hex << Reg[base].u << " (" << rname(base) << ")" << end();
|
||||
return Reg[base].u;
|
||||
}
|
||||
else {
|
||||
uint8_t scale = (1 << (sib>>6));
|
||||
uint32_t addr = Reg[base].u + Reg[index].i*scale; // treat index register as signed. Maybe base as well? But we'll always ensure it's non-negative.
|
||||
trace(2, "run") << "effective address is mem at address 0x" << std::hex << addr << " (" << rname(base) << " + " << rname(index) << "*" << NUM(scale) << ")" << end();
|
||||
trace(2, "run") << "effective address is 0x" << std::hex << addr << " (" << rname(base) << " + " << rname(index) << "*" << NUM(scale) << ")" << end();
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
@ -65,6 +65,6 @@ uint32_t effective_address_from_sib(uint8_t mod) {
|
|||
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)
|
||||
+run: add EBX to effective address
|
||||
+run: effective address is mem at address 0x60 (EAX + ECX*1)
|
||||
+run: add EBX to r/m32
|
||||
+run: effective address is 0x60 (EAX + ECX*1)
|
||||
+run: storing 0x00000011
|
||||
|
|
|
@ -28,15 +28,15 @@ case 0xe8: { // call imm32 relative to next EIP
|
|||
# op ModR/M SIB displacement immediate
|
||||
ff d3 # call function offset at EBX
|
||||
# next EIP is 3
|
||||
+run: call to effective address
|
||||
+run: effective address is EBX
|
||||
+run: call to r/m32
|
||||
+run: r/m32 is EBX
|
||||
+run: decrementing ESP to 0x00000060
|
||||
+run: pushing value 0x00000003
|
||||
+run: jumping to 0x000000a3
|
||||
|
||||
:(before "End Op ff Subops")
|
||||
case 2: { // call function pointer at r/m32
|
||||
trace(2, "run") << "call to effective address" << end();
|
||||
trace(2, "run") << "call to r/m32" << end();
|
||||
int32_t* offset = effective_address(modrm);
|
||||
push(EIP);
|
||||
EIP += *offset;
|
||||
|
@ -51,8 +51,8 @@ case 2: { // call function pointer at r/m32
|
|||
# op ModR/M SIB displacement immediate
|
||||
ff 13 # call function offset at *EBX
|
||||
# next EIP is 3
|
||||
+run: call to effective address
|
||||
+run: effective address is mem at address 0x10 (EBX)
|
||||
+run: call to r/m32
|
||||
+run: effective address is 0x10 (EBX)
|
||||
+run: decrementing ESP to 0x00000060
|
||||
+run: pushing value 0x00000003
|
||||
+run: jumping to 0x000000a3
|
||||
|
|
Loading…
Reference in New Issue