diff options
-rwxr-xr-x | subx/apps/pack | bin | 34688 -> 34859 bytes | |||
-rw-r--r-- | subx/apps/pack.subx | 226 |
2 files changed, 127 insertions, 99 deletions
diff --git a/subx/apps/pack b/subx/apps/pack index 6bb05d3f..b3a20354 100755 --- a/subx/apps/pack +++ b/subx/apps/pack Binary files differdiff --git a/subx/apps/pack.subx b/subx/apps/pack.subx index a72aeb0d..4fff835c 100644 --- a/subx/apps/pack.subx +++ b/subx/apps/pack.subx @@ -22,7 +22,7 @@ Entry: # run tests if necessary, convert stdin if not # for debugging: run a single test -#? e8/call test-convert-instruction-emits-modrm-byte/disp32 +#? e8/call test-convert-instruction-handles-disp8-name/disp32 #? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX #? eb/jump $main:end/disp8 @@ -2909,22 +2909,18 @@ emit-disp: # line : (address stream byte), out : (address buffered-file) -> <vo # pseudocode: # rewind-stream(line) # var word-slice = {0, 0} - # var disp = 0 # while true # word-slice = next-word(line) # if (slice-empty?(word-slice)) break # if (slice-starts-with?(word-slice, "#")) break # if has-metadata?(word-slice, "disp32") - # disp = parse-hex-int(next-token-from-slice(word-slice, "/")) - # emit-hex(out, disp, 4) + # emit(out, word-slice, 4) # break # if has-metadata?(word-slice, "disp16") - # disp = parse-hex-int(next-token-from-slice(word-slice, "/")) - # emit-hex(out, disp, 2) + # emit(out, word-slice, 2) # break # if has-metadata?(word-slice, "disp8") - # disp = parse-hex-int(next-token-from-slice(word-slice, "/")) - # emit-hex(out, disp, 1) + # emit(out, word-slice, 1) # break # # . prolog @@ -2934,12 +2930,10 @@ emit-disp: # line : (address stream byte), out : (address buffered-file) -> <vo 50/push-EAX 51/push-ECX 52/push-EDX - 53/push-EBX # var word-slice/ECX = {0, 0} 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # var disp/EBX = 0 # rewind-stream(line) # . . push args ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) @@ -3076,23 +3070,13 @@ $emit-disp:check-for-disp32: 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX 74/jump-if-equal $emit-disp:check-for-disp16/disp8 $emit-disp:disp32: - # disp = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) - # . EAX = parse-datum-of-word(word-slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-datum-of-word/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . disp = EAX - 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX - # emit-hex(out, disp, 4) + # emit(out, word-slice, 4) # . . push args 68/push 4/imm32 - 53/push-EBX + 51/push-ECX ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) # . . call - e8/call emit-hex/disp32 + e8/call emit/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # break @@ -3111,23 +3095,13 @@ $emit-disp:check-for-disp16: 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX 74/jump-if-equal $emit-disp:check-for-disp8/disp8 $emit-disp:disp16: - # disp = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) - # . EAX = parse-datum-of-word(word-slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-datum-of-word/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . disp = EAX - 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX - # emit-hex(out, disp, 2) + # emit(out, word-slice, 2) # . . push args 68/push 2/imm32 - 53/push-EBX + 51/push-ECX ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) # . . call - e8/call emit-hex/disp32 + e8/call emit/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # break @@ -3146,23 +3120,13 @@ $emit-disp:check-for-disp8: 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX 0f 84/jump-if-equal $emit-disp:loop/disp32 $emit-disp:disp8: - # disp = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) - # . EAX = parse-datum-of-word(word-slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-datum-of-word/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . disp = EAX - 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX - # emit-hex(out, imm, 1) + # emit(out, word-slice, 1) # . . push args 68/push 1/imm32 - 53/push-EBX + 51/push-ECX ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) # . . call - e8/call emit-hex/disp32 + e8/call emit/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # break @@ -3170,7 +3134,6 @@ $emit-disp:break: # . restore locals 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # . restore registers - 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX 58/pop-to-EAX @@ -3183,22 +3146,18 @@ emit-imm: # line : (address stream byte), out : (address buffered-file) -> <voi # pseudocode: # rewind-stream(line) # var word-slice = {0, 0} - # var imm = 0 # while true # word-slice = next-word(line) # if (slice-empty?(word-slice)) break # if (slice-starts-with?(word-slice, "#")) break # if has-metadata?(word-slice, "imm32") - # imm = parse-hex-int(next-token-from-slice(word-slice, "/")) - # emit-hex(out, imm, 4) + # emit(out, word-slice, 4) # break # if has-metadata?(word-slice, "imm16") - # imm = parse-hex-int(next-token-from-slice(word-slice, "/")) - # emit-hex(out, imm, 2) + # emit(out, word-slice, 2) # break # if has-metadata?(word-slice, "imm8") - # imm = parse-hex-int(next-token-from-slice(word-slice, "/")) - # emit-hex(out, imm, 1) + # emit(out, word-slice, 1) # break # # . prolog @@ -3208,12 +3167,10 @@ emit-imm: # line : (address stream byte), out : (address buffered-file) -> <voi 50/push-EAX 51/push-ECX 52/push-EDX - 53/push-EBX # var word-slice/ECX = {0, 0} 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # var imm/EBX = 0 # rewind-stream(line) # . . push args ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) @@ -3350,23 +3307,13 @@ $emit-imm:check-for-imm32: 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX 74/jump-if-equal $emit-imm:check-for-imm16/disp8 $emit-imm:imm32: - # imm = parse-hex-int(next-token-from-slice(slice->start, slice->end, '/')) - # . EAX = parse-datum-of-word(word-slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-datum-of-word/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . imm = EAX - 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX - # emit-hex(out, imm, 4) + # emit(out, word-slice, 4) # . . push args 68/push 4/imm32 - 53/push-EBX + 51/push-ECX ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) # . . call - e8/call emit-hex/disp32 + e8/call emit/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # break @@ -3385,23 +3332,13 @@ $emit-imm:check-for-imm16: 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX 74/jump-if-equal $emit-imm:check-for-imm8/disp8 $emit-imm:imm16: - # imm = parse-hex-int(next-token-from-slice(slice->start, slice->end, '/')) - # . EAX = parse-datum-of-word(word-slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-datum-of-word/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . imm = EAX - 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX - # emit-hex(out, imm, 2) + # emit(out, word-slice, 2) # . . push args 68/push 2/imm32 - 53/push-EBX + 51/push-ECX ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) # . . call - e8/call emit-hex/disp32 + e8/call emit/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # break @@ -3420,23 +3357,13 @@ $emit-imm:check-for-imm8: 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0/imm32 # compare EAX 0f 84/jump-if-equal $emit-imm:loop/disp32 $emit-imm:imm8: - # word-slice = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) - # . EAX = parse-datum-of-word(word-slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-datum-of-word/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . imm = EAX - 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX - # emit-hex(out, imm, 1) + # emit(out, word-slice, 1) # . . push args 68/push 1/imm32 - 53/push-EBX + 51/push-ECX ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 0xc/disp8 . # push *(EBP+12) # . . call - e8/call emit-hex/disp32 + e8/call emit/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP # break @@ -3444,7 +3371,6 @@ $emit-imm:break: # . restore locals 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP # . restore registers - 5b/pop-to-EBX 5a/pop-to-EDX 59/pop-to-ECX 58/pop-to-EAX @@ -5757,6 +5683,108 @@ test-convert-instruction-handles-disp8-operand: 5d/pop-to-EBP c3/return +test-convert-instruction-handles-disp8-name: + # pass /disp8 name directly through + # . prolog + 55/push-EBP + 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + # setup + # . clear-stream(_test-input-stream) + # . . push args + 68/push _test-input-stream/imm32 + # . . call + e8/call clear-stream/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + # . clear-stream(_test-output-stream) + # . . push args + 68/push _test-output-stream/imm32 + # . . call + e8/call clear-stream/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + # . clear-stream(_test-output-buffered-file+4) + # . . push args + b8/copy-to-EAX _test-output-buffered-file/imm32 + 05/add-to-EAX 4/imm32 + 50/push-EAX + # . . call + e8/call clear-stream/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + # initialize input + # . write(_test-input-stream, "eb/jump xyz/disp8") + # . . push args + 68/push "eb/jump xyz/disp8"/imm32 + 68/push _test-input-stream/imm32 + # . . call + e8/call write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + # convert-instruction(_test-input-stream, _test-output-buffered-file) + # . . push args + 68/push _test-output-buffered-file/imm32 + 68/push _test-input-stream/imm32 + # . . call + e8/call convert-instruction/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + # check output + # . flush(_test-output-buffered-file) + # . . push args + 68/push _test-output-buffered-file/imm32 + # . . call + e8/call flush/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP +#? # dump output {{{ +#? # . write(2/stderr, "^") +#? # . . push args +#? 68/push "^"/imm32 +#? 68/push 2/imm32/stderr +#? # . . call +#? e8/call write/disp32 +#? # . . discard args +#? 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +#? # . write-stream(2/stderr, _test-output-stream) +#? # . . push args +#? 68/push _test-output-stream/imm32 +#? 68/push 2/imm32/stderr +#? # . . call +#? e8/call write-stream/disp32 +#? # . . discard args +#? 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +#? # . write(2/stderr, "$") +#? # . . push args +#? 68/push "$"/imm32 +#? 68/push 2/imm32/stderr +#? # . . call +#? e8/call write/disp32 +#? # . . discard args +#? 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +#? # . write(2/stderr, "\n") +#? # . . push args +#? 68/push Newline/imm32 +#? 68/push 2/imm32/stderr +#? # . . call +#? e8/call write/disp32 +#? # . . discard args +#? 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP +#? # }}} + # . check-stream-equal(_test-output-stream, "eb xyz/disp8 # eb/jump xyz/disp8", msg) + # . . push args + 68/push "F - test-convert-instruction-handles-disp8-name"/imm32 + 68/push "eb xyz/disp8 # eb/jump xyz/disp8"/imm32 + 68/push _test-output-stream/imm32 + # . . call + e8/call check-stream-equal/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + # . epilog + 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP + 5d/pop-to-EBP + c3/return + test-convert-instruction-handles-imm32-operand: # expand /imm32 operand into 4 bytes # . prolog |