diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-10-16 23:02:57 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-10-16 23:02:57 -0700 |
commit | 7ea0b5325b5bb609f15a8b70b07cb0d6464c8414 (patch) | |
tree | 8d2f6f846cea450a6e8cf5e171cb5e0c3719bb50 /subx | |
parent | 04be5eb2aead455137a756a7eff47cc31d08f4e3 (diff) | |
download | mu-7ea0b5325b5bb609f15a8b70b07cb0d6464c8414.tar.gz |
4704
Diffstat (limited to 'subx')
-rw-r--r-- | subx/055trace.subx | 70 |
1 files changed, 41 insertions, 29 deletions
diff --git a/subx/055trace.subx b/subx/055trace.subx index 1ed42e8a..00f09ed5 100644 --- a/subx/055trace.subx +++ b/subx/055trace.subx @@ -84,34 +84,46 @@ trace: # t : (address trace-stream), line : string # append line to t.data from t.write # # pseudocode: - # length = *(EBX+8) - # i = *EBX - # j = 0 - # while i < length - # if j >= len(line) break - # t.data[i] = line[j] - # inc j - # inc i - # registers: - # t, line, i, j, length, line.length, t.data[i] + # destend = &t.data[t.length] + # oldw = t.write + # if line.length == 0 return + # t.write += line.length + 1 # for newline + # dest = &t.data[oldw] + # srcend = &line.data[line.length] + # src = &line.data[0] + # while true: + # if src >= srcend break + # if dest >= destend break # for now silently ignore filled up trace buffer + # *dest = *src + # ++src + # ++dest + # if dest >= destend return + # *dest = 10/newline # - # we could reduce registers to just tdata, line, tmax, lmax - # A = *(BP+8) # t - # B = *(BP+12) # line - # C = *(A+8) # t.length - # C = A+12+C # &t.data[t.length] - # SI = *A # t.write - # D = *B # line.length - # *A = *A + D # update t.write (can go over, we'll guard against it) - # A = A+12+SI # &t.data[t.write] - # SI = B+4+D # &line.data[line.length] - # B = B+4 # &line.data[0] + # key registers to set up for the loop: + # EAX/dest, ECX/destend, EBX/src, ESI/srcend + # we save EDX for byte operations (has to be one of the first 4 registers) # + # register setup before the loop: + # EAX = *(EBP+8) # t + # EBX = *(EBP+12) # line + # ECX = *(EAX+8) # t.length + # ECX = EAX+12+ECX # destend = &t.data[t.length] + # ESI = *EAX # oldw = t.write + # EDX = *EBX # line.length + # *EAX = *EAX + EDX # update t.write (allowed to go past t.length) + # # do this here just because it's convenient + # ++ *EAX # for the newline + # EAX = EAX+12+ESI # dest = &t.data[t.write] + # ESI = EBX+4+EDX # srcend = &line.data[line.length] + # EBX = EBX+4 # src = &line.data[0] + # + # EAX/t and EBX/line are already initialized # ECX = t.length 8b/copy 1/mod/*+disp8 0/rm32/EAX . . . 1/r32/ECX 8/disp8 . # copy *(EAX+8) to ECX - # ECX = &t.data[t.length] + # ECX/destend = &t.data[t.length] 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 1/index/ECX . 1/r32/ECX 0xc/disp8 . # copy EAX+ECX+12 to ECX - # ESI = t.write + # ESI/oldw = t.write 8b/copy 0/mod/indirect 0/rm32/EAX . . . 6/r32/ESI . . # copy *EAX to ESI # EDX = line.length 8b/copy 0/mod/indirect 3/rm32/EBX . . . 2/r32/EDX . . # copy *EBX to EDX @@ -122,18 +134,18 @@ trace: # t : (address trace-stream), line : string 01/add 0/mod/indirect 0/rm32/EAX . . . 2/r32/EDX . . # add EDX to *EAX # t.write++ (for the newline we'll append below) 81 0/subop/add 0/mod/indirect 0/rm32/EAX . . . . . 1/imm32 # add to *EAX - # EAX = &t.data[old t.write] + # EAX/dest = &t.data[oldw] 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/EAX 6/index/ESI . 0/r32/EAX 0xc/disp8 . # copy EAX+ESI+12 to EAX - # ESI = &line.data[line.length] + # ESI/srcend = &line.data[line.length] 8d/copy-address 1/mod/*+disp8 4/rm32/sib 3/base/EBX 2/index/EDX . 6/r32/ESI 4/disp8 . # copy EBX+EDX+4 to ESI - # EBX = &line.data + # EBX/src = &line.data 81 0/subop/add 3/mod/direct 3/rm32/EBX . . . . . 4/imm32 # add to EBX # while (true) $trace:loop: - # if EBX >= ESI break + # if EBX/src >= ESI/srcend break 39/compare 3/mod/direct 3/rm32/EBX . . . 6/r32/ESI . . # compare EBX with ESI 7d/jump-if-greater-or-equal $trace:break/disp8 - # if EAX >= ECX break (for now silently ignore full trace) + # if EAX/dest >= ECX/destend break (for now silently ignore filled up trace buffer) 39/compare 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # compare EAX with ECX 7d/jump-if-greater-or-equal $trace:break/disp8 # copy one byte @@ -145,7 +157,7 @@ $trace:loop: eb/jump $trace:loop/disp8 $trace:break: # finally, append a newline - # if EAX >= ECX return + # if EAX/dest >= ECX/destend return 39/compare 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # compare EAX with ECX 7d/jump-if-greater-or-equal $trace:end/disp8 # append |