diff options
author | Kartik Agaram <vc@akkartik.com> | 2019-02-25 00:17:46 -0800 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2019-02-25 01:50:53 -0800 |
commit | c442a5ad806b6cccbb3ec4c5744b14b0c1f31a01 (patch) | |
tree | 318fb1d56e7ee3c750635d3326ad0739dfdacefe /subx/015immediate_addressing.cc | |
parent | e5998f74ac29bb4bf2aedfdd6fbea801ffdb08f6 (diff) | |
download | mu-c442a5ad806b6cccbb3ec4c5744b14b0c1f31a01.tar.gz |
4987 - support `browse_trace` tool in SubX
I've extracted it into a separate binary, independent of my Mu prototype. I also cleaned up my tracing layer to be a little nicer. Major improvements: - Realized that incremental tracing really ought to be the default. And to minimize printing traces to screen. - Finally figured out how to combine layers and call stack frames in a single dimension of depth. The answer: optimize for the experience of `browse_trace`. Instructions occupy a range of depths based on their call stack frame, and minor details of an instruction lie one level deeper in each case. Other than that, I spent some time adjusting levels everywhere to make `browse_trace` useful.
Diffstat (limited to 'subx/015immediate_addressing.cc')
-rw-r--r-- | subx/015immediate_addressing.cc | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/subx/015immediate_addressing.cc b/subx/015immediate_addressing.cc index 55b4fa37..93dd699b 100644 --- a/subx/015immediate_addressing.cc +++ b/subx/015immediate_addressing.cc @@ -17,15 +17,15 @@ put_new(Name, "81", "combine rm32 with imm32 based on subop (add/sub/and/or/xor/ :(before "End Single-Byte Opcodes") case 0x81: { // combine imm32 with r/m32 - trace(90, "run") << "combine imm32 with r/m32" << end(); + trace(Callstack_depth+1, "run") << "combine imm32 with r/m32" << end(); const uint8_t modrm = next(); int32_t* arg1 = effective_address(modrm); const int32_t arg2 = next32(); - trace(90, "run") << "imm32 is 0x" << HEXWORD << arg2 << end(); + trace(Callstack_depth+1, "run") << "imm32 is 0x" << HEXWORD << arg2 << end(); const uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits switch (subop) { case 0: - trace(90, "run") << "subop add" << end(); + trace(Callstack_depth+1, "run") << "subop add" << end(); BINARY_ARITHMETIC_OP(+, *arg1, arg2); break; // End Op 81 Subops @@ -68,7 +68,7 @@ put_new(Name, "2d", "subtract imm32 from EAX (sub)"); :(before "End Single-Byte Opcodes") case 0x2d: { // subtract imm32 from EAX const int32_t arg2 = next32(); - trace(90, "run") << "subtract imm32 0x" << HEXWORD << arg2 << " from EAX" << end(); + trace(Callstack_depth+1, "run") << "subtract imm32 0x" << HEXWORD << arg2 << " from EAX" << end(); BINARY_ARITHMETIC_OP(-, Reg[EAX].i, arg2); break; } @@ -91,7 +91,7 @@ case 0x2d: { // subtract imm32 from EAX :(before "End Op 81 Subops") case 5: { - trace(90, "run") << "subop subtract" << end(); + trace(Callstack_depth+1, "run") << "subop subtract" << end(); BINARY_ARITHMETIC_OP(-, *arg1, arg2); break; } @@ -129,12 +129,12 @@ put_new(Name, "c1", "shift rm32 by imm8 bits depending on subop (sal/sar/shl/shr :(before "End Single-Byte Opcodes") case 0xc1: { const uint8_t modrm = next(); - trace(90, "run") << "operate on r/m32" << end(); + trace(Callstack_depth+1, "run") << "operate on r/m32" << end(); int32_t* arg1 = effective_address(modrm); const uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits switch (subop) { case 4: { // shift left r/m32 by CL - trace(90, "run") << "subop: shift left by CL bits" << end(); + trace(Callstack_depth+1, "run") << "subop: shift left by CL bits" << end(); uint8_t count = next() & 0x1f; // OF is only defined if count is 1 if (count == 1) { @@ -145,7 +145,7 @@ case 0xc1: { *arg1 = (*arg1 << count); ZF = (*arg1 == 0); SF = (*arg1 < 0); - trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << end(); + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } // End Op c1 Subops @@ -171,14 +171,14 @@ case 0xc1: { :(before "End Op c1 Subops") case 7: { // shift right r/m32 by CL, preserving sign - trace(90, "run") << "subop: shift right by CL bits, while preserving sign" << end(); + trace(Callstack_depth+1, "run") << "subop: shift right by CL bits, while preserving sign" << end(); uint8_t count = next() & 0x1f; *arg1 = (*arg1 >> count); ZF = (*arg1 == 0); SF = (*arg1 < 0); // OF is only defined if count is 1 if (count == 1) OF = false; - trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << end(); + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -221,7 +221,7 @@ case 7: { // shift right r/m32 by CL, preserving sign :(before "End Op c1 Subops") case 5: { // shift right r/m32 by CL, preserving sign - trace(90, "run") << "subop: shift right by CL bits, while padding zeroes" << end(); + trace(Callstack_depth+1, "run") << "subop: shift right by CL bits, while padding zeroes" << end(); uint8_t count = next() & 0x1f; // OF is only defined if count is 1 if (count == 1) { @@ -234,7 +234,7 @@ case 5: { // shift right r/m32 by CL, preserving sign ZF = (*uarg1 == 0); // result is always positive by definition SF = false; - trace(90, "run") << "storing 0x" << HEXWORD << *arg1 << end(); + trace(Callstack_depth+1, "run") << "storing 0x" << HEXWORD << *arg1 << end(); break; } @@ -277,7 +277,7 @@ put_new(Name, "25", "EAX = bitwise AND of imm32 with EAX (and)"); :(before "End Single-Byte Opcodes") case 0x25: { // and imm32 with EAX const int32_t arg2 = next32(); - trace(90, "run") << "and imm32 0x" << HEXWORD << arg2 << " with EAX" << end(); + trace(Callstack_depth+1, "run") << "and imm32 0x" << HEXWORD << arg2 << " with EAX" << end(); BINARY_BITWISE_OP(&, Reg[EAX].i, arg2); break; } @@ -300,7 +300,7 @@ ff 00 00 00 # 0xff :(before "End Op 81 Subops") case 4: { - trace(90, "run") << "subop and" << end(); + trace(Callstack_depth+1, "run") << "subop and" << end(); BINARY_BITWISE_OP(&, *arg1, arg2); break; } @@ -335,7 +335,7 @@ put_new(Name, "0d", "EAX = bitwise OR of imm32 with EAX (or)"); :(before "End Single-Byte Opcodes") case 0x0d: { // or imm32 with EAX const int32_t arg2 = next32(); - trace(90, "run") << "or imm32 0x" << HEXWORD << arg2 << " with EAX" << end(); + trace(Callstack_depth+1, "run") << "or imm32 0x" << HEXWORD << arg2 << " with EAX" << end(); BINARY_BITWISE_OP(|, Reg[EAX].i, arg2); break; } @@ -358,7 +358,7 @@ a0 b0 c0 d0 # 0xd0c0b0a0 :(before "End Op 81 Subops") case 1: { - trace(90, "run") << "subop or" << end(); + trace(Callstack_depth+1, "run") << "subop or" << end(); BINARY_BITWISE_OP(|, *arg1, arg2); break; } @@ -391,7 +391,7 @@ put_new(Name, "35", "EAX = bitwise XOR of imm32 with EAX (xor)"); :(before "End Single-Byte Opcodes") case 0x35: { // xor imm32 with EAX const int32_t arg2 = next32(); - trace(90, "run") << "xor imm32 0x" << HEXWORD << arg2 << " with EAX" << end(); + trace(Callstack_depth+1, "run") << "xor imm32 0x" << HEXWORD << arg2 << " with EAX" << end(); BINARY_BITWISE_OP(^, Reg[EAX].i, arg2); break; } @@ -414,7 +414,7 @@ a0 b0 c0 d0 # 0xd0c0b0a0 :(before "End Op 81 Subops") case 6: { - trace(90, "run") << "subop xor" << end(); + trace(Callstack_depth+1, "run") << "subop xor" << end(); BINARY_BITWISE_OP(^, *arg1, arg2); break; } @@ -448,13 +448,13 @@ put_new(Name, "3d", "compare: set SF if EAX < imm32 (cmp)"); case 0x3d: { // compare EAX with imm32 const int32_t arg1 = Reg[EAX].i; const int32_t arg2 = next32(); - trace(90, "run") << "compare EAX and imm32 0x" << HEXWORD << arg2 << end(); + trace(Callstack_depth+1, "run") << "compare EAX and imm32 0x" << HEXWORD << arg2 << end(); const int32_t tmp1 = arg1 - arg2; SF = (tmp1 < 0); ZF = (tmp1 == 0); const int64_t tmp2 = arg1 - arg2; OF = (tmp1 != tmp2); - trace(90, "run") << "SF=" << SF << "; ZF=" << ZF << "; OF=" << OF << end(); + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; OF=" << OF << end(); break; } @@ -489,13 +489,13 @@ case 0x3d: { // compare EAX with imm32 :(before "End Op 81 Subops") case 7: { - trace(90, "run") << "subop compare" << end(); + trace(Callstack_depth+1, "run") << "subop compare" << end(); const int32_t tmp1 = *arg1 - arg2; SF = (tmp1 < 0); ZF = (tmp1 == 0); const int64_t tmp2 = *arg1 - arg2; OF = (tmp1 != tmp2); - trace(90, "run") << "SF=" << SF << "; ZF=" << ZF << "; OF=" << OF << end(); + trace(Callstack_depth+1, "run") << "SF=" << SF << "; ZF=" << ZF << "; OF=" << OF << end(); break; } @@ -590,7 +590,7 @@ case 0xbe: case 0xbf: { // copy imm32 to r32 const uint8_t rdest = op & 0x7; const int32_t src = next32(); - trace(90, "run") << "copy imm32 0x" << HEXWORD << src << " to " << rname(rdest) << end(); + trace(Callstack_depth+1, "run") << "copy imm32 0x" << HEXWORD << src << " to " << rname(rdest) << end(); Reg[rdest].i = src; break; } @@ -613,7 +613,7 @@ put_new(Name, "c7", "copy imm32 to rm32 (mov)"); :(before "End Single-Byte Opcodes") case 0xc7: { // copy imm32 to r32 const uint8_t modrm = next(); - trace(90, "run") << "copy imm32 to r/m32" << end(); + trace(Callstack_depth+1, "run") << "copy imm32 to r/m32" << end(); const uint8_t subop = (modrm>>3)&0x7; // middle 3 'reg opcode' bits if (subop != 0) { cerr << "unrecognized subop for opcode c7: " << NUM(subop) << " (only 0/copy currently implemented)\n"; @@ -621,7 +621,7 @@ case 0xc7: { // copy imm32 to r32 } int32_t* dest = effective_address(modrm); const int32_t src = next32(); - trace(90, "run") << "imm32 is 0x" << HEXWORD << src << end(); + trace(Callstack_depth+1, "run") << "imm32 is 0x" << HEXWORD << src << end(); *dest = src; break; } @@ -643,10 +643,10 @@ put_new(Name, "68", "push imm32 to stack (push)"); :(before "End Single-Byte Opcodes") case 0x68: { const uint32_t val = static_cast<uint32_t>(next32()); - trace(90, "run") << "push imm32 0x" << HEXWORD << val << end(); + trace(Callstack_depth+1, "run") << "push imm32 0x" << HEXWORD << val << end(); //? cerr << "push: " << val << " => " << Reg[ESP].u << '\n'; push(val); - trace(90, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); - trace(90, "run") << "contents at ESP: 0x" << HEXWORD << read_mem_u32(Reg[ESP].u) << end(); + trace(Callstack_depth+1, "run") << "ESP is now 0x" << HEXWORD << Reg[ESP].u << end(); + trace(Callstack_depth+1, "run") << "contents at ESP: 0x" << HEXWORD << read_mem_u32(Reg[ESP].u) << end(); break; } |