4695
This commit is contained in:
parent
06d9b1a541
commit
0f851e48aa
|
@ -365,28 +365,28 @@ void dump_registers() {
|
|||
|
||||
//: start tracking supported opcodes
|
||||
:(before "End Globals")
|
||||
map</*op*/string, string> name;
|
||||
map</*op*/string, string> name_0f;
|
||||
map</*op*/string, string> name_f3;
|
||||
map</*op*/string, string> name_f3_0f;
|
||||
map</*op*/string, string> Name;
|
||||
map</*op*/string, string> Name_0f;
|
||||
map</*op*/string, string> Name_f3;
|
||||
map</*op*/string, string> Name_f3_0f;
|
||||
:(before "End One-time Setup")
|
||||
init_op_names();
|
||||
:(code)
|
||||
void init_op_names() {
|
||||
put(name, "f4", "halt (hlt)");
|
||||
// End Initialize Op Names(name)
|
||||
put(Name, "f4", "halt (hlt)");
|
||||
// End Initialize Op Names
|
||||
}
|
||||
|
||||
:(before "End Help Special-cases(key)")
|
||||
if (key == "opcodes") {
|
||||
cerr << "Opcodes currently supported by SubX:\n";
|
||||
for (map<string, string>::iterator p = name.begin(); p != name.end(); ++p)
|
||||
for (map<string, string>::iterator p = Name.begin(); p != Name.end(); ++p)
|
||||
cerr << " " << p->first << ": " << p->second << '\n';
|
||||
for (map<string, string>::iterator p = name_0f.begin(); p != name_0f.end(); ++p)
|
||||
for (map<string, string>::iterator p = Name_0f.begin(); p != Name_0f.end(); ++p)
|
||||
cerr << " 0f " << p->first << ": " << p->second << '\n';
|
||||
for (map<string, string>::iterator p = name_f3.begin(); p != name_f3.end(); ++p)
|
||||
for (map<string, string>::iterator p = Name_f3.begin(); p != Name_f3.end(); ++p)
|
||||
cerr << " f3 " << p->first << ": " << p->second << '\n';
|
||||
for (map<string, string>::iterator p = name_f3_0f.begin(); p != name_f3_0f.end(); ++p)
|
||||
for (map<string, string>::iterator p = Name_f3_0f.begin(); p != Name_f3_0f.end(); ++p)
|
||||
cerr << " f3 0f " << p->first << ": " << p->second << '\n';
|
||||
cerr << "Run `subx help instructions` for details on words like 'r32' and 'disp8'.\n"
|
||||
"For complete details on these instructions, consult the IA-32 manual (volume 2).\n"
|
||||
|
|
|
@ -326,8 +326,8 @@ void parse_and_load(const string& text_bytes) {
|
|||
|
||||
//:: run
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "05", "add imm32 to EAX (add)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "05", "add imm32 to EAX (add)");
|
||||
|
||||
//: our first opcode
|
||||
:(before "End Single-Byte Opcodes")
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//: operating directly on a register
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "01", "add r32 to rm32 (add)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "01", "add r32 to rm32 (add)");
|
||||
|
||||
:(scenario add_r32_to_r32)
|
||||
% Reg[EAX].i = 0x10;
|
||||
|
@ -75,8 +75,8 @@ string rname(uint8_t r) {
|
|||
|
||||
//:: subtract
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "29", "subtract r32 from rm32 (sub)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "29", "subtract r32 from rm32 (sub)");
|
||||
|
||||
:(scenario subtract_r32_from_r32)
|
||||
% Reg[EAX].i = 10;
|
||||
|
@ -101,8 +101,8 @@ case 0x29: { // subtract r32 from r/m32
|
|||
|
||||
//:: multiply
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "f7", "negate/multiply rm32 (with EAX if necessary) depending on subop (neg/mul)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "f7", "negate/multiply rm32 (with EAX if necessary) depending on subop (neg/mul)");
|
||||
|
||||
:(scenario multiply_eax_by_r32)
|
||||
% Reg[EAX].i = 4;
|
||||
|
@ -142,8 +142,8 @@ case 0xf7: { // xor r32 with r/m32
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name_0f, "af", "multiply rm32 into r32 (imul)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name_0f, "af", "multiply rm32 into r32 (imul)");
|
||||
|
||||
:(scenario multiply_r32_into_r32)
|
||||
% Reg[EAX].i = 4;
|
||||
|
@ -168,8 +168,8 @@ case 0xaf: { // multiply r32 into r/m32
|
|||
|
||||
//:: and
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "21", "rm32 = bitwise AND of r32 with rm32 (and)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "21", "rm32 = bitwise AND of r32 with rm32 (and)");
|
||||
|
||||
:(scenario and_r32_with_r32)
|
||||
% Reg[EAX].i = 0x0a0b0c0d;
|
||||
|
@ -194,8 +194,8 @@ case 0x21: { // and r32 with r/m32
|
|||
|
||||
//:: or
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "09", "rm32 = bitwise OR of r32 with rm32 (or)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "09", "rm32 = bitwise OR of r32 with rm32 (or)");
|
||||
|
||||
:(scenario or_r32_with_r32)
|
||||
% Reg[EAX].i = 0x0a0b0c0d;
|
||||
|
@ -220,8 +220,8 @@ case 0x09: { // or r32 with r/m32
|
|||
|
||||
//:: xor
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "31", "rm32 = bitwise XOR of r32 with rm32 (xor)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "31", "rm32 = bitwise XOR of r32 with rm32 (xor)");
|
||||
|
||||
:(scenario xor_r32_with_r32)
|
||||
% Reg[EAX].i = 0x0a0b0c0d;
|
||||
|
@ -270,8 +270,8 @@ case 2: { // not r/m32
|
|||
|
||||
//:: compare (cmp)
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "39", "compare: set SF if rm32 < r32 (cmp)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "39", "compare: set SF if rm32 < r32 (cmp)");
|
||||
|
||||
:(scenario compare_r32_with_r32_greater)
|
||||
% Reg[EAX].i = 0x0a0b0c0d;
|
||||
|
@ -324,8 +324,8 @@ case 0x39: { // set SF if r/m32 < r32
|
|||
|
||||
//:: copy (mov)
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "89", "copy r32 to rm32 (mov)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "89", "copy r32 to rm32 (mov)");
|
||||
|
||||
:(scenario copy_r32_to_r32)
|
||||
% Reg[EBX].i = 0xaf;
|
||||
|
@ -350,8 +350,8 @@ case 0x89: { // copy r32 to r/m32
|
|||
|
||||
//:: xchg
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "87", "swap the contents of r32 and rm32 (xchg)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "87", "swap the contents of r32 and rm32 (xchg)");
|
||||
|
||||
:(scenario xchg_r32_with_r32)
|
||||
% Reg[EBX].i = 0xaf;
|
||||
|
@ -381,15 +381,15 @@ case 0x87: { // exchange r32 with r/m32
|
|||
|
||||
//:: increment
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "40", "increment EAX (inc)");
|
||||
put_new(name, "41", "increment ECX (inc)");
|
||||
put_new(name, "42", "increment EDX (inc)");
|
||||
put_new(name, "43", "increment EBX (inc)");
|
||||
put_new(name, "44", "increment ESP (inc)");
|
||||
put_new(name, "45", "increment EBP (inc)");
|
||||
put_new(name, "46", "increment ESI (inc)");
|
||||
put_new(name, "47", "increment EDI (inc)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "40", "increment EAX (inc)");
|
||||
put_new(Name, "41", "increment ECX (inc)");
|
||||
put_new(Name, "42", "increment EDX (inc)");
|
||||
put_new(Name, "43", "increment EBX (inc)");
|
||||
put_new(Name, "44", "increment ESP (inc)");
|
||||
put_new(Name, "45", "increment EBP (inc)");
|
||||
put_new(Name, "46", "increment ESI (inc)");
|
||||
put_new(Name, "47", "increment EDI (inc)");
|
||||
|
||||
:(scenario increment_r32)
|
||||
% Reg[ECX].u = 0x1f;
|
||||
|
@ -415,8 +415,8 @@ case 0x47: { // increment r32
|
|||
break;
|
||||
}
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "ff", "increment/decrement/jump/push/call rm32 based on subop (inc/dec/jmp/push/call)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "ff", "increment/decrement/jump/push/call rm32 based on subop (inc/dec/jmp/push/call)");
|
||||
|
||||
:(scenario increment_rm32)
|
||||
% Reg[EAX].u = 0x20;
|
||||
|
@ -447,15 +447,15 @@ case 0xff: {
|
|||
|
||||
//:: decrement
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "48", "decrement EAX (dec)");
|
||||
put_new(name, "49", "decrement ECX (dec)");
|
||||
put_new(name, "4a", "decrement EDX (dec)");
|
||||
put_new(name, "4b", "decrement EBX (dec)");
|
||||
put_new(name, "4c", "decrement ESP (dec)");
|
||||
put_new(name, "4d", "decrement EBP (dec)");
|
||||
put_new(name, "4e", "decrement ESI (dec)");
|
||||
put_new(name, "4f", "decrement EDI (dec)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "48", "decrement EAX (dec)");
|
||||
put_new(Name, "49", "decrement ECX (dec)");
|
||||
put_new(Name, "4a", "decrement EDX (dec)");
|
||||
put_new(Name, "4b", "decrement EBX (dec)");
|
||||
put_new(Name, "4c", "decrement ESP (dec)");
|
||||
put_new(Name, "4d", "decrement EBP (dec)");
|
||||
put_new(Name, "4e", "decrement ESI (dec)");
|
||||
put_new(Name, "4f", "decrement EDI (dec)");
|
||||
|
||||
:(scenario decrement_r32)
|
||||
% Reg[ECX].u = 0x1f;
|
||||
|
@ -502,15 +502,15 @@ case 1: { // decrement r/m32
|
|||
|
||||
//:: push
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "50", "push EAX to stack (push)");
|
||||
put_new(name, "51", "push ECX to stack (push)");
|
||||
put_new(name, "52", "push EDX to stack (push)");
|
||||
put_new(name, "53", "push EBX to stack (push)");
|
||||
put_new(name, "54", "push ESP to stack (push)");
|
||||
put_new(name, "55", "push EBP to stack (push)");
|
||||
put_new(name, "56", "push ESI to stack (push)");
|
||||
put_new(name, "57", "push EDI to stack (push)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "50", "push EAX to stack (push)");
|
||||
put_new(Name, "51", "push ECX to stack (push)");
|
||||
put_new(Name, "52", "push EDX to stack (push)");
|
||||
put_new(Name, "53", "push EBX to stack (push)");
|
||||
put_new(Name, "54", "push ESP to stack (push)");
|
||||
put_new(Name, "55", "push EBP to stack (push)");
|
||||
put_new(Name, "56", "push ESI to stack (push)");
|
||||
put_new(Name, "57", "push EDI to stack (push)");
|
||||
|
||||
:(scenario push_r32)
|
||||
% Reg[ESP].u = 0x64;
|
||||
|
@ -540,15 +540,15 @@ case 0x57: { // push r32 to stack
|
|||
|
||||
//:: pop
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "58", "pop top of stack to EAX (pop)");
|
||||
put_new(name, "59", "pop top of stack to ECX (pop)");
|
||||
put_new(name, "5a", "pop top of stack to EDX (pop)");
|
||||
put_new(name, "5b", "pop top of stack to EBX (pop)");
|
||||
put_new(name, "5c", "pop top of stack to ESP (pop)");
|
||||
put_new(name, "5d", "pop top of stack to EBP (pop)");
|
||||
put_new(name, "5e", "pop top of stack to ESI (pop)");
|
||||
put_new(name, "5f", "pop top of stack to EDI (pop)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "58", "pop top of stack to EAX (pop)");
|
||||
put_new(Name, "59", "pop top of stack to ECX (pop)");
|
||||
put_new(Name, "5a", "pop top of stack to EDX (pop)");
|
||||
put_new(Name, "5b", "pop top of stack to EBX (pop)");
|
||||
put_new(Name, "5c", "pop top of stack to ESP (pop)");
|
||||
put_new(Name, "5d", "pop top of stack to EBP (pop)");
|
||||
put_new(Name, "5e", "pop top of stack to ESI (pop)");
|
||||
put_new(Name, "5f", "pop top of stack to EDI (pop)");
|
||||
|
||||
:(scenario pop_r32)
|
||||
% Reg[ESP].u = 0x2000;
|
||||
|
|
|
@ -27,8 +27,8 @@ case 0: // indirect addressing
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "03", "add rm32 to r32 (add)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "03", "add rm32 to r32 (add)");
|
||||
|
||||
:(scenario add_mem_at_r32_to_r32)
|
||||
% Reg[EAX].i = 0x2000;
|
||||
|
@ -70,8 +70,8 @@ case 0x03: { // add r/m32 to r32
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "2b", "subtract rm32 from r32 (sub)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "2b", "subtract rm32 from r32 (sub)");
|
||||
|
||||
:(scenario subtract_mem_at_r32_from_r32)
|
||||
% Reg[EAX].i = 0x2000;
|
||||
|
@ -113,8 +113,8 @@ case 0x2b: { // subtract r/m32 from r32
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "23", "r32 = bitwise AND of r32 with rm32 (and)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "23", "r32 = bitwise AND of r32 with rm32 (and)");
|
||||
|
||||
:(scenario and_mem_at_r32_with_r32)
|
||||
% Reg[EAX].i = 0x2000;
|
||||
|
@ -156,8 +156,8 @@ case 0x23: { // and r/m32 with r32
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "0b", "r32 = bitwise OR of r32 with rm32 (or)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "0b", "r32 = bitwise OR of r32 with rm32 (or)");
|
||||
|
||||
:(scenario or_mem_at_r32_with_r32)
|
||||
% Reg[EAX].i = 0x2000;
|
||||
|
@ -199,8 +199,8 @@ case 0x0b: { // or r/m32 with r32
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "33", "r32 = bitwise XOR of r32 with rm32 (xor)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "33", "r32 = bitwise XOR of r32 with rm32 (xor)");
|
||||
|
||||
:(scenario xor_mem_at_r32_with_r32)
|
||||
% Reg[EAX].i = 0x2000;
|
||||
|
@ -283,8 +283,8 @@ ff 00 0f 0f # 0x0f0f00ff
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "3b", "compare: set SF if r32 < rm32 (cmp)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "3b", "compare: set SF if r32 < rm32 (cmp)");
|
||||
|
||||
:(scenario compare_r32_with_mem_at_r32_greater)
|
||||
% Reg[EAX].i = 0x2000;
|
||||
|
@ -356,8 +356,8 @@ case 0x3b: { // set SF if r32 < r/m32
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "8b", "copy rm32 to r32 (mov)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "8b", "copy rm32 to r32 (mov)");
|
||||
|
||||
:(scenario copy_mem_at_r32_to_r32)
|
||||
% Reg[EAX].i = 0x2000;
|
||||
|
@ -436,8 +436,8 @@ case 6: { // push r/m32 to stack
|
|||
|
||||
//:: pop
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "8f", "pop top of stack to rm32 (pop)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "8f", "pop top of stack to rm32 (pop)");
|
||||
|
||||
:(scenario pop_mem_at_r32)
|
||||
% Reg[EAX].i = 0x60;
|
||||
|
@ -580,8 +580,8 @@ case 2: // indirect + disp32 addressing
|
|||
|
||||
//:: lea
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "8d", "copy address in rm32 into r32 (lea)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "8d", "copy address in rm32 into r32 (lea)");
|
||||
|
||||
:(scenario lea)
|
||||
% Reg[EAX].u = 0x2000;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//: instructions that (immediately) contain an argument to act with
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "81", "combine rm32 with imm32 based on subop (add/sub/and/or/xor/cmp)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "81", "combine rm32 with imm32 based on subop (add/sub/and/or/xor/cmp)");
|
||||
|
||||
:(scenario add_imm32_to_r32)
|
||||
% Reg[EBX].i = 1;
|
||||
|
@ -54,8 +54,8 @@ case 0x81: { // combine imm32 with r/m32
|
|||
|
||||
//:: subtract
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "2d", "subtract imm32 from EAX (sub)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "2d", "subtract imm32 from EAX (sub)");
|
||||
|
||||
:(scenario subtract_imm32_from_eax)
|
||||
% Reg[EAX].i = 0x0d0c0baa;
|
||||
|
@ -112,8 +112,8 @@ case 5: {
|
|||
|
||||
//:: and
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "25", "EAX = bitwise AND of imm32 with EAX (and)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "25", "EAX = bitwise AND of imm32 with EAX (and)");
|
||||
|
||||
:(scenario and_imm32_with_eax)
|
||||
% Reg[EAX].i = 0xff;
|
||||
|
@ -170,8 +170,8 @@ case 4: {
|
|||
|
||||
//:: or
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "0d", "EAX = bitwise OR of imm32 with EAX (or)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "0d", "EAX = bitwise OR of imm32 with EAX (or)");
|
||||
|
||||
:(scenario or_imm32_with_eax)
|
||||
% Reg[EAX].i = 0xd0c0b0a0;
|
||||
|
@ -226,8 +226,8 @@ case 1: {
|
|||
|
||||
//:: xor
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "35", "EAX = bitwise XOR of imm32 with EAX (xor)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "35", "EAX = bitwise XOR of imm32 with EAX (xor)");
|
||||
|
||||
:(scenario xor_imm32_with_eax)
|
||||
% Reg[EAX].i = 0xddccb0a0;
|
||||
|
@ -282,8 +282,8 @@ case 6: {
|
|||
|
||||
//:: compare (cmp)
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "3d", "compare: set SF if EAX < imm32 (cmp)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "3d", "compare: set SF if EAX < imm32 (cmp)");
|
||||
|
||||
:(scenario compare_imm32_with_eax_greater)
|
||||
% Reg[EAX].i = 0x0d0c0b0a;
|
||||
|
@ -412,15 +412,15 @@ case 7: {
|
|||
|
||||
//:: copy (mov)
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "b8", "copy imm32 to EAX (mov)");
|
||||
put_new(name, "b9", "copy imm32 to ECX (mov)");
|
||||
put_new(name, "ba", "copy imm32 to EDX (mov)");
|
||||
put_new(name, "bb", "copy imm32 to EBX (mov)");
|
||||
put_new(name, "bc", "copy imm32 to ESP (mov)");
|
||||
put_new(name, "bd", "copy imm32 to EBP (mov)");
|
||||
put_new(name, "be", "copy imm32 to ESI (mov)");
|
||||
put_new(name, "bf", "copy imm32 to EDI (mov)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "b8", "copy imm32 to EAX (mov)");
|
||||
put_new(Name, "b9", "copy imm32 to ECX (mov)");
|
||||
put_new(Name, "ba", "copy imm32 to EDX (mov)");
|
||||
put_new(Name, "bb", "copy imm32 to EBX (mov)");
|
||||
put_new(Name, "bc", "copy imm32 to ESP (mov)");
|
||||
put_new(Name, "bd", "copy imm32 to EBP (mov)");
|
||||
put_new(Name, "be", "copy imm32 to ESI (mov)");
|
||||
put_new(Name, "bf", "copy imm32 to EDI (mov)");
|
||||
|
||||
:(scenario copy_imm32_to_r32)
|
||||
== 0x1
|
||||
|
@ -446,8 +446,8 @@ case 0xbf: { // copy imm32 to r32
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "c7", "copy imm32 to rm32 (mov)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "c7", "copy imm32 to rm32 (mov)");
|
||||
|
||||
:(scenario copy_imm32_to_mem_at_r32)
|
||||
% Reg[EBX].i = 0x60;
|
||||
|
@ -472,8 +472,8 @@ case 0xc7: { // copy imm32 to r32
|
|||
|
||||
//:: push
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "68", "push imm32 to stack (push)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "68", "push imm32 to stack (push)");
|
||||
|
||||
:(scenario push_imm32)
|
||||
% Reg[ESP].u = 0x14;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
//:: jump
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "eb", "jump disp8 bytes away (jmp)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "eb", "jump disp8 bytes away (jmp)");
|
||||
|
||||
:(scenario jump_rel8)
|
||||
== 0x1
|
||||
|
@ -26,8 +26,8 @@ case 0xeb: { // jump rel8
|
|||
|
||||
//:: jump if equal/zero
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "74", "jump disp8 bytes away if equal, if ZF is set. (jcc/jz/je)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "74", "jump disp8 bytes away if equal, if ZF is set. (jcc/jz/je)");
|
||||
|
||||
:(scenario je_rel8_success)
|
||||
% ZF = true;
|
||||
|
@ -65,8 +65,8 @@ case 0x74: { // jump rel8 if ZF
|
|||
|
||||
//:: jump if not equal/not zero
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "75", "jump disp8 bytes away if not equal, if ZF is not set. (jcc/jnz/jne)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "75", "jump disp8 bytes away if not equal, if ZF is not set. (jcc/jnz/jne)");
|
||||
|
||||
:(scenario jne_rel8_success)
|
||||
% ZF = false;
|
||||
|
@ -104,8 +104,8 @@ case 0x75: { // jump rel8 unless ZF
|
|||
|
||||
//:: jump if greater
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "7f", "jump disp8 bytes away if greater, if ZF is unset and SF == OF. (jcc/jg/jnle)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "7f", "jump disp8 bytes away if greater, if ZF is unset and SF == OF. (jcc/jg/jnle)");
|
||||
|
||||
:(scenario jg_rel8_success)
|
||||
% ZF = false;
|
||||
|
@ -147,8 +147,8 @@ case 0x7f: { // jump rel8 if !SF and !ZF
|
|||
|
||||
//:: jump if greater or equal
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "7d", "jump disp8 bytes away if greater or equal, if SF == OF. (jcc/jge/jnl)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "7d", "jump disp8 bytes away if greater or equal, if SF == OF. (jcc/jge/jnl)");
|
||||
|
||||
:(scenario jge_rel8_success)
|
||||
% SF = false;
|
||||
|
@ -188,8 +188,8 @@ case 0x7d: { // jump rel8 if !SF
|
|||
|
||||
//:: jump if lesser
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "7c", "jump disp8 bytes away if lesser, if SF != OF. (jcc/jl/jnge)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "7c", "jump disp8 bytes away if lesser, if SF != OF. (jcc/jl/jnge)");
|
||||
|
||||
:(scenario jl_rel8_success)
|
||||
% ZF = false;
|
||||
|
@ -231,8 +231,8 @@ case 0x7c: { // jump rel8 if SF and !ZF
|
|||
|
||||
//:: jump if lesser or equal
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "7e", "jump disp8 bytes away if lesser or equal, if ZF is set or SF != OF. (jcc/jle/jng)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "7e", "jump disp8 bytes away if lesser or equal, if ZF is set or SF != OF. (jcc/jle/jng)");
|
||||
|
||||
:(scenario jle_rel8_equal)
|
||||
% ZF = true;
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
//:: jump
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "e9", "jump disp16 bytes away (jmp)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "e9", "jump disp16 bytes away (jmp)");
|
||||
|
||||
:(scenario jump_rel16)
|
||||
== 0x1
|
||||
|
@ -32,8 +32,8 @@ int16_t imm16() {
|
|||
|
||||
//:: jump if equal/zero
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name_0f, "84", "jump disp16 bytes away if equal, if ZF is set. (jcc/jz/je)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name_0f, "84", "jump disp16 bytes away if equal, if ZF is set. (jcc/jz/je)");
|
||||
|
||||
:(scenario je_rel16_success)
|
||||
% ZF = true;
|
||||
|
@ -71,8 +71,8 @@ case 0x84: { // jump rel16 if ZF
|
|||
|
||||
//:: jump if not equal/not zero
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name_0f, "85", "jump disp16 bytes away if not equal, if ZF is not set. (jcc/jnz/jne)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name_0f, "85", "jump disp16 bytes away if not equal, if ZF is not set. (jcc/jnz/jne)");
|
||||
|
||||
:(scenario jne_rel16_success)
|
||||
% ZF = false;
|
||||
|
@ -110,8 +110,8 @@ case 0x85: { // jump rel16 unless ZF
|
|||
|
||||
//:: jump if greater
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name_0f, "8f", "jump disp16 bytes away if greater, if ZF is unset and SF == OF. (jcc/jg/jnle)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name_0f, "8f", "jump disp16 bytes away if greater, if ZF is unset and SF == OF. (jcc/jg/jnle)");
|
||||
|
||||
:(scenario jg_rel16_success)
|
||||
% ZF = false;
|
||||
|
@ -153,8 +153,8 @@ case 0x8f: { // jump rel16 if !SF and !ZF
|
|||
|
||||
//:: jump if greater or equal
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name_0f, "8d", "jump disp16 bytes away if greater or equal, if SF == OF. (jcc/jge/jnl)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name_0f, "8d", "jump disp16 bytes away if greater or equal, if SF == OF. (jcc/jge/jnl)");
|
||||
|
||||
:(scenario jge_rel16_success)
|
||||
% SF = false;
|
||||
|
@ -194,8 +194,8 @@ case 0x8d: { // jump rel16 if !SF
|
|||
|
||||
//:: jump if lesser
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name_0f, "8c", "jump disp16 bytes away if lesser, if SF != OF. (jcc/jl/jnge)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name_0f, "8c", "jump disp16 bytes away if lesser, if SF != OF. (jcc/jl/jnge)");
|
||||
|
||||
:(scenario jl_rel16_success)
|
||||
% ZF = false;
|
||||
|
@ -237,8 +237,8 @@ case 0x8c: { // jump rel16 if SF and !ZF
|
|||
|
||||
//:: jump if lesser or equal
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name_0f, "8e", "jump disp16 bytes away if lesser or equal, if ZF is set or SF != OF. (jcc/jle/jng)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name_0f, "8e", "jump disp16 bytes away if lesser or equal, if ZF is set or SF != OF. (jcc/jle/jng)");
|
||||
|
||||
:(scenario jle_rel16_equal)
|
||||
% ZF = true;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//:: call
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "e8", "call disp32 (call)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "e8", "call disp32 (call)");
|
||||
|
||||
:(scenario call_disp32)
|
||||
% Reg[ESP].u = 0x64;
|
||||
|
@ -67,8 +67,8 @@ a0 00 00 00 # 0xa0
|
|||
|
||||
//:: ret
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "c3", "return from most recent unfinished call (ret)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "c3", "return from most recent unfinished call (ret)");
|
||||
|
||||
:(scenario ret)
|
||||
% Reg[ESP].u = 0x2000;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "cd", "software interrupt (int)");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "cd", "software interrupt (int)");
|
||||
|
||||
:(before "End Single-Byte Opcodes")
|
||||
case 0xcd: { // int imm8 (software interrupt)
|
||||
|
|
|
@ -37,8 +37,8 @@ uint8_t* reg_8bit(uint8_t rm) {
|
|||
return result;
|
||||
}
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "88", "copy r8 to r8/m8-at-r32");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "88", "copy r8 to r8/m8-at-r32");
|
||||
|
||||
:(scenario copy_r8_to_mem_at_r32)
|
||||
% Reg[EBX].i = 0x224488ab;
|
||||
|
@ -69,8 +69,8 @@ case 0x88: { // copy r8 to r/m8
|
|||
|
||||
//:
|
||||
|
||||
:(before "End Initialize Op Names(name)")
|
||||
put_new(name, "8a", "copy r8/m8-at-r32 to r8");
|
||||
:(before "End Initialize Op Names")
|
||||
put_new(Name, "8a", "copy r8/m8-at-r32 to r8");
|
||||
|
||||
:(scenario copy_mem_at_r32_to_r8)
|
||||
% Reg[EBX].i = 0xaabbcc0f; // one nibble each of lowest byte set to all 0s and all 1s, to maximize value of this test
|
||||
|
|
|
@ -274,8 +274,8 @@ void compare_bitvector(const line& inst, uint8_t expected, const word& op) {
|
|||
|
||||
string maybe_name(const word& op) {
|
||||
if (!is_hex_byte(op)) return "";
|
||||
if (!contains_key(name, op.data)) return "";
|
||||
return " ("+get(name, op.data)+')';
|
||||
if (!contains_key(Name, op.data)) return "";
|
||||
return " ("+get(Name, op.data)+')';
|
||||
}
|
||||
|
||||
uint32_t compute_operand_bitvector(const line& inst) {
|
||||
|
@ -385,12 +385,12 @@ void compare_bitvector_modrm(const line& inst, uint8_t expected, const word& op)
|
|||
|
||||
void check_operand_metadata_present(const line& inst, const string& type, const word& op) {
|
||||
if (!has_operand_metadata(inst, type))
|
||||
raise << "'" << to_string(inst) << "' (" << get(name, op.data) << "): missing " << type << " operand\n" << end();
|
||||
raise << "'" << to_string(inst) << "' (" << get(Name, op.data) << "): missing " << type << " operand\n" << end();
|
||||
}
|
||||
|
||||
void check_operand_metadata_absent(const line& inst, const string& type, const word& op, const string& msg) {
|
||||
if (has_operand_metadata(inst, type))
|
||||
raise << "'" << to_string(inst) << "' (" << get(name, op.data) << "): unexpected " << type << " operand (" << msg << ")\n" << end();
|
||||
raise << "'" << to_string(inst) << "' (" << get(Name, op.data) << "): unexpected " << type << " operand (" << msg << ")\n" << end();
|
||||
}
|
||||
|
||||
:(scenarios transform)
|
||||
|
@ -459,7 +459,7 @@ void check_operands_0f(const line& inst) {
|
|||
return;
|
||||
}
|
||||
word op = preprocess_op(inst.words.at(1));
|
||||
if (!contains_key(name_0f, op.data)) {
|
||||
if (!contains_key(Name_0f, op.data)) {
|
||||
raise << "unknown 2-byte opcode '0f " << op.data << "'\n" << end();
|
||||
return;
|
||||
}
|
||||
|
@ -515,9 +515,9 @@ void compare_bitvector_0f(const line& inst, uint8_t expected, const word& op) {
|
|||
if ((bitvector & 0x1) == (expected & 0x1)) continue; // all good with this operand
|
||||
const string& optype = Operand_type_name.at(i);
|
||||
if ((bitvector & 0x1) > (expected & 0x1))
|
||||
raise << "'" << to_string(inst) << "' (" << get(name_0f, op.data) << "): unexpected " << optype << " operand\n" << end();
|
||||
raise << "'" << to_string(inst) << "' (" << get(Name_0f, op.data) << "): unexpected " << optype << " operand\n" << end();
|
||||
else
|
||||
raise << "'" << to_string(inst) << "' (" << get(name_0f, op.data) << "): missing " << optype << " operand\n" << end();
|
||||
raise << "'" << to_string(inst) << "' (" << get(Name_0f, op.data) << "): missing " << optype << " operand\n" << end();
|
||||
// continue giving all errors for a single instruction
|
||||
}
|
||||
// ignore settings in any unused bits
|
||||
|
|
Loading…
Reference in New Issue