diff options
Diffstat (limited to 'apps')
-rwxr-xr-x | apps/assort | bin | 40175 -> 44323 bytes | |||
-rwxr-xr-x | apps/braces | bin | 39569 -> 43717 bytes | |||
-rwxr-xr-x | apps/calls | bin | 44930 -> 49078 bytes | |||
-rwxr-xr-x | apps/crenshaw2-1 | bin | 33919 -> 38067 bytes | |||
-rwxr-xr-x | apps/crenshaw2-1b | bin | 34478 -> 38626 bytes | |||
-rwxr-xr-x | apps/dquotes | bin | 45364 -> 49512 bytes | |||
-rwxr-xr-x | apps/factorial | bin | 32931 -> 37079 bytes | |||
-rwxr-xr-x | apps/handle | bin | 33785 -> 37972 bytes | |||
-rw-r--r-- | apps/handle.subx | 18 | ||||
-rwxr-xr-x | apps/hex | bin | 42573 -> 19492 bytes | |||
-rw-r--r-- | apps/hex.subx | 1486 | ||||
-rwxr-xr-x | apps/pack | bin | 52846 -> 56994 bytes | |||
-rwxr-xr-x | apps/sigils | bin | 52868 -> 57016 bytes | |||
-rwxr-xr-x | apps/survey | bin | 49448 -> 53596 bytes | |||
-rwxr-xr-x | apps/tests | bin | 38992 -> 43140 bytes |
15 files changed, 17 insertions, 1487 deletions
diff --git a/apps/assort b/apps/assort index d04fab27..ef57e4e3 100755 --- a/apps/assort +++ b/apps/assort Binary files differdiff --git a/apps/braces b/apps/braces index 187567e5..36e33941 100755 --- a/apps/braces +++ b/apps/braces Binary files differdiff --git a/apps/calls b/apps/calls index 863bd993..68c86663 100755 --- a/apps/calls +++ b/apps/calls Binary files differdiff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1 index fd28bf3a..aefbe733 100755 --- a/apps/crenshaw2-1 +++ b/apps/crenshaw2-1 Binary files differdiff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b index 8c96482d..fcd81297 100755 --- a/apps/crenshaw2-1b +++ b/apps/crenshaw2-1b Binary files differdiff --git a/apps/dquotes b/apps/dquotes index 108a74bb..c682b312 100755 --- a/apps/dquotes +++ b/apps/dquotes Binary files differdiff --git a/apps/factorial b/apps/factorial index 0fa9ab2b..3c8a8e46 100755 --- a/apps/factorial +++ b/apps/factorial Binary files differdiff --git a/apps/handle b/apps/handle index 1ebf8f81..f1e9f60a 100755 --- a/apps/handle +++ b/apps/handle Binary files differdiff --git a/apps/handle.subx b/apps/handle.subx index b5c98422..36283c16 100644 --- a/apps/handle.subx +++ b/apps/handle.subx @@ -26,7 +26,23 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes -# no Entry; the standard library runs all tests by default +Entry: + # initialize heap + # . Heap = new-segment(64KB) + # . . push args + 68/push Heap/imm32 + 68/push 0x10000/imm32/64KB + # . . call + e8/call new-segment/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + + e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. +$handle-main:end: + # syscall(exit, Num-test-failures) + 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx + b8/copy-to-eax 1/imm32/exit + cd/syscall 0x80/imm8 new: # ad : (address allocation-descriptor), n : int, out : (address handle) # . prolog diff --git a/apps/hex b/apps/hex index c9241871..4506f819 100755 --- a/apps/hex +++ b/apps/hex Binary files differdiff --git a/apps/hex.subx b/apps/hex.subx deleted file mode 100644 index ad09a3c3..00000000 --- a/apps/hex.subx +++ /dev/null @@ -1,1486 +0,0 @@ -# Read a text file containing whitespace-separated pairs of ascii hex bytes -# from stdin, and convert them into binary bytes (octets) on stdout. Ignore -# comments between '#' and newline. -# -# To run: -# $ ./subx translate init.linux 0*.subx apps/subx-common.subx apps/hex.subx -o apps/hex -# $ echo '80 81 82 # comment' |./subx run apps/hex |xxd - -# Expected output: -# 00000000: 8081 82 -# -# Only hex bytes and comments are permitted. Outside of comments all words -# must be exactly 2 characters long and contain only characters [0-9a-f]. No -# uppercase hex. - -== code -# instruction effective address register displacement immediate -# . op subop mod rm32 base index scale r32 -# . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes - -Entry: # run tests if necessary, convert stdin if not - # . prolog - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - - # initialize heap - # . Heap = new-segment(64KB) - # . . push args - 68/push Heap/imm32 - 68/push 0x10000/imm32/64KB - # . . call - e8/call new-segment/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - - # - if argc > 1 and argv[1] == "test", then return run_tests() - # if (argc <= 1) goto run-main - 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32 # compare *ebp - 7e/jump-if-lesser-or-equal $run-main/disp8 - # if (!kernel-string-equal?(argv[1], "test")) goto run-main - # . eax = kernel-string-equal?(argv[1], "test") - # . . push args - 68/push "test"/imm32 - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto run-main - 3d/compare-eax-and 0/imm32 - 74/jump-if-equal $run-main/disp8 - # run-tests() - e8/call run-tests/disp32 - # syscall(exit, *Num-test-failures) - 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 -$run-main: - # - otherwise convert stdin - # var ed/eax : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax - # configure ed to really exit() - # . ed->target = 0 - c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax - # convert(Stdin, 1/stdout, 2/stderr, ed) - # . . push args - 50/push-eax/ed - 68/push Stderr/imm32 - 68/push Stdout/imm32 - 68/push Stdin/imm32 - # . . call - e8/call convert/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp - # syscall(exit, 0) - bb/copy-to-ebx 0/imm32 -$main:end: - b8/copy-to-eax 1/imm32/exit - cd/syscall 0x80/imm8 - -# the main entry point -convert: # in : (address buffered-file), out : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> <void> - # pseudocode: - # while true - # eax = convert-next-octet(in, err, ed) - # if (eax == Eof) break - # write-byte-buffered(out, AL) - # flush(out) - # - # . prolog - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # . save registers - 50/push-eax -$convert:loop: - # eax = convert-next-octet(in, err, ed) - # . . push args - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 . # push *(ebp+20) - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - # . . call - e8/call convert-next-octet/disp32 - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # if (eax == Eof) break - 3d/compare-eax-and 0xffffffff/imm32/Eof - 74/jump-if-equal $convert:loop-end/disp8 - # write-byte-buffered(out, AL) - # . . push args - 50/push-eax - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - # . . call - e8/call write-byte-buffered/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # loop - eb/jump $convert:loop/disp8 -$convert:loop-end: - # flush(out) - # . . push args - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - # . . call - e8/call flush/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -$convert:end: - # . restore registers - 58/pop-to-eax - # . epilog - 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 5d/pop-to-ebp - c3/return - -# read bytes from 'in' until a sequence of two lowercase hex (0-9, a-f) bytes -# skip spaces and newlines -# on '#' skip bytes until newline -# raise an error and abort on all other unexpected bytes -# return in eax an _octet_ containing the binary value of the two hex characters -# return Eof on reaching end of file -convert-next-octet: # in : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> byte-or-Eof/eax - # pseudocode: - # eax = scan-next-byte(in, err, ed) - # if (eax == Eof) return - # ecx = from-hex-char(eax) - # eax = scan-next-byte(in, err, ed) - # if (eax == Eof) error("partial byte found.") - # eax = from-hex-char(eax) - # eax = (ecx << 4) | eax - # return - # - # . prolog - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # . save registers - 51/push-ecx - # eax = scan-next-byte(in, err, ed) - # . . push args - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - # . . call - e8/call scan-next-byte/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # if (eax == Eof) return - 3d/compare-eax-and 0xffffffff/imm32/Eof - 74/jump-if-equal $convert-next-octet:end/disp8 - # eax = from-hex-char(eax) - e8/call from-hex-char/disp32 - # ecx = eax - 89/copy 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # copy eax to ecx - # eax = scan-next-byte(in, err, ed) - # . . push args - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - # . . call - e8/call scan-next-byte/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # if (eax == Eof) error(ed, err, "partial byte found.") - 3d/compare-eax-and 0xffffffff/imm32/Eof - 75/jump-if-not-equal $convert-next-octet:convert/disp8 - # . error-byte(ed, err, msg, '.') # reusing error-byte to avoid creating _yet_ another helper - # . . push args - 68/push 0x2e/imm32/period/dummy - 68/push "convert-next-octet: partial byte found"/imm32 - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - # . . call - e8/call error-byte/disp32 # never returns -$convert-next-octet:convert: - # eax = from-hex-char(eax) - e8/call from-hex-char/disp32 - # eax = (ecx << 4) | eax - # . ecx <<= 4 - c1/shift 4/subop/left 3/mod/direct 1/rm32/ecx . . . . . 4/imm8 # shift ecx left by 4 bits - # . eax |= ecx - 09/or 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # eax = bitwise OR with ecx -$convert-next-octet:end: - # . restore registers - 59/pop-to-ecx - # . epilog - 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 5d/pop-to-ebp - c3/return - -test-convert-next-octet: - # - check that the first two bytes of the input are assembled into the resulting octet - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 '_test-stream' to "abc" - # . write(_test-stream, "abc") - # . . push args - 68/push "abc"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-convert-next-octet - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = convert-next-octet(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call convert-next-octet/disp32 - # registers except esp may be clobbered at this point - # pop args to convert-next-octet - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that convert-next-octet didn't abort - # . check-ints-equal(ed->value, 0, msg) - # . . push args - 68/push "F - test-convert-next-octet: unexpected abort"/imm32 - 68/push 0/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # return if abort - 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 75/jump-if-not-equal $test-convert-next-octet:end/disp8 - # check-ints-equal(eax, 0xab, msg) - # . . push args - 68/push "F - test-convert-next-octet"/imm32 - 68/push 0xab/imm32/ab - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-convert-next-octet:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -test-convert-next-octet-handles-Eof: - # - check that reaching end of file returns Eof - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 - # don't initialize '_test-stream' - # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-convert-next-octet - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = convert-next-octet(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call convert-next-octet/disp32 - # registers except esp may be clobbered at this point - # pop args to convert-next-octet - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that convert-next-octet didn't abort - # . check-ints-equal(ed->value, 0, msg) - # . . push args - 68/push "F - test-convert-next-octet: unexpected abort"/imm32 - 68/push 0/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # return if abort - 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 75/jump-if-not-equal $test-convert-next-octet-handles-Eof:end/disp8 - # check-ints-equal(eax, Eof, msg) - # . . push args - 68/push "F - test-convert-next-octet-handles-Eof"/imm32 - 68/push 0xffffffff/imm32/Eof - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-convert-next-octet-handles-Eof:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -test-convert-next-octet-aborts-on-single-hex-byte: - # - check that a single unaccompanied hex byte aborts - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 '_test-stream' to "a" - # . write(_test-stream, "a") - # . . push args - 68/push "a"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-convert-next-octet - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = convert-next-octet(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call convert-next-octet/disp32 - # registers except esp may be clobbered at this point - # pop args to convert-next-octet - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that convert-next-octet aborted - # . check-ints-equal(ed->value, 2, msg) - # . . push args - 68/push "F - test-convert-next-octet-aborts-on-single-hex-byte: unexpected abort"/imm32 - 68/push 2/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-convert-next-octet-aborts-on-single-hex-byte:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -# read whitespace until a hex byte, and return it -# return Eof if file ends without finding a hex byte -# on '#' skip all bytes until newline -# abort on any other byte -scan-next-byte: # in : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> byte-or-Eof/eax - # pseudocode: - # while true - # eax = read-byte-buffered(in) - # if (eax == Eof) return eax - # if (is-hex-digit?(eax)) return eax - # if (eax == ' ' or '\t' or '\n') continue - # if (eax == '#') skip-until-newline(in) - # else error-byte(ed, err, "invalid byte: " eax) - # - # . prolog - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # . save registers -$scan-next-byte:loop: - # eax = read-byte-buffered(in) - # . . push args - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - # . . call - e8/call read-byte-buffered/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # if (eax == Eof) return eax - 3d/compare-with-eax 0xffffffff/imm32/Eof - 74/jump-if-equal $scan-next-byte:end/disp8 - # if (is-hex-digit?(eax)) return eax - # . save eax for now - 50/push-eax - # . is-hex-digit?(eax) - # . . push args - 50/push-eax - # . . call - e8/call is-hex-digit?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . compare with 'false' - 3d/compare-with-eax 0/imm32 - # . restore eax (does not affect flags) - 58/pop-to-eax - # . check whether to return - 75/jump-if-not-equal $scan-next-byte:end/disp8 -$scan-next-byte:check1: - # if (eax == ' ') continue - 3d/compare-eax-and 0x20/imm32/space - 74/jump-if-equal $scan-next-byte:loop/disp8 - # if (eax == '\t') continue - 3d/compare-eax-and 9/imm32/tab - 74/jump-if-equal $scan-next-byte:loop/disp8 - # if (eax == '\n') continue - 3d/compare-eax-and 0xa/imm32/newline - 74/jump-if-equal $scan-next-byte:loop/disp8 -$scan-next-byte:check2: - # if (eax == '#') skip-until-newline(in) - 3d/compare-with-eax 0x23/imm32 - 75/jump-if-not-equal $scan-next-byte:check3/disp8 - # . skip-until-newline(in) - # . . push args - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - # . . call - e8/call skip-until-newline/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - eb/jump $scan-next-byte:loop/disp8 -$scan-next-byte:check3: - # otherwise error-byte(ed, err, msg, eax) - # . . push args - 50/push-eax - 68/push "scan-next-byte: invalid byte"/imm32 - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - # . . call - e8/call error-byte/disp32 # never returns -$scan-next-byte:end: - # . restore registers - # . epilog - 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 5d/pop-to-ebp - c3/return - -test-scan-next-byte: - # - check that the first byte of the input is returned - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 '_test-stream' to "abc" - # . write(_test-stream, "abc") - # . . push args - 68/push "abc"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call scan-next-byte/disp32 - # registers except esp may be clobbered at this point - # pop args to scan-next-byte - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that scan-next-byte didn't abort - # . check-ints-equal(ed->value, 0, msg) - # . . push args - 68/push "F - test-scan-next-byte: unexpected abort"/imm32 - 68/push 0/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # return if abort - 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 75/jump-if-not-equal $test-scan-next-byte:end/disp8 - # check-ints-equal(eax, 0x61/a, msg) - # . . push args - 68/push "F - test-scan-next-byte"/imm32 - 68/push 0x61/imm32/a - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-scan-next-byte:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -test-scan-next-byte-skips-whitespace: - # - check that the first byte after whitespace is returned - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 '_test-stream' to input with leading whitespace - # . write(_test-stream, text) - # . . push args - 68/push " abc"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call scan-next-byte/disp32 - # registers except esp may be clobbered at this point - # pop args to scan-next-byte - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that scan-next-byte didn't abort - # . check-ints-equal(ed->value, 0, msg) - # . . push args - 68/push "F - test-scan-next-byte-skips-whitespace: unexpected abort"/imm32 - 68/push 0/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # return if abort - 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 75/jump-if-not-equal $test-scan-next-byte-skips-whitespace:end/disp8 - # check-ints-equal(eax, 0x61/a, msg) - # . . push args - 68/push "F - test-scan-next-byte-skips-whitespace"/imm32 - 68/push 0x61/imm32/a - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-scan-next-byte-skips-whitespace:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -test-scan-next-byte-skips-comment: - # - check that the first byte after a comment (and newline) is returned - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 '_test-stream' to input with leading comment - # . write(_test-stream, comment) - # . . push args - 68/push "#x\n"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . write(_test-stream, real text) - # . . push args - 68/push "ab"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call scan-next-byte/disp32 - # registers except esp may be clobbered at this point - # pop args to scan-next-byte - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that scan-next-byte didn't abort - # . check-ints-equal(ed->value, 0, msg) - # . . push args - 68/push "F - test-scan-next-byte-skips-comment: unexpected abort"/imm32 - 68/push 0/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # return if abort - 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 75/jump-if-not-equal $test-scan-next-byte-skips-comment:end/disp8 - # check-ints-equal(eax, 0x61/a, msg) - # . . push args - 68/push "F - test-scan-next-byte-skips-comment"/imm32 - 68/push 0x61/imm32/a - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-scan-next-byte-skips-comment:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -test-scan-next-byte-skips-comment-and-whitespace: - # - check that the first byte after a comment and any further whitespace is returned - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 '_test-stream' to input with leading comment and more whitespace after newline - # . write(_test-stream, comment) - # . . push args - 68/push "#x\n"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . write(_test-stream, real text) - # . . push args - 68/push " ab"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call scan-next-byte/disp32 - # registers except esp may be clobbered at this point - # pop args to scan-next-byte - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that scan-next-byte didn't abort - # . check-ints-equal(ed->value, 0, msg) - # . . push args - 68/push "F - test-scan-next-byte-skips-comment-and-whitespace: unexpected abort"/imm32 - 68/push 0/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # return if abort - 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 75/jump-if-not-equal $test-scan-next-byte-skips-comment-and-whitespace:end/disp8 - # check-ints-equal(eax, 0x61/a, msg) - # . . push args - 68/push "F - test-scan-next-byte-skips-comment-and-whitespace"/imm32 - 68/push 0x61/imm32/a - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-scan-next-byte-skips-comment-and-whitespace:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -test-scan-next-byte-skips-whitespace-and-comment: - # - check that the first byte after any whitespace and comments is returned - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 '_test-stream' to input with leading whitespace and comment - # . write(_test-stream, comment) - # . . push args - 68/push " #x\n"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . write(_test-stream, real text) - # . . push args - 68/push "ab"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call scan-next-byte/disp32 - # registers except esp may be clobbered at this point - # pop args to scan-next-byte - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that scan-next-byte didn't abort - # . check-ints-equal(ed->value, 0, msg) - # . . push args - 68/push "F - test-scan-next-byte-skips-whitespace-and-comment: unexpected abort"/imm32 - 68/push 0/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # return if abort - 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 75/jump-if-not-equal $test-scan-next-byte-skips-whitespace-and-comment:end/disp8 - # check-ints-equal(eax, 0x61/a, msg) - # . . push args - 68/push "F - test-scan-next-byte-skips-whitespace-and-comment"/imm32 - 68/push 0x61/imm32/a - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-scan-next-byte-skips-whitespace-and-comment:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -test-scan-next-byte-reads-final-byte: - # - check that the final byte in input is returned - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 '_test-stream' to input with single character - # . write(_test-stream, character) - # . . push args - 68/push "a"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call scan-next-byte/disp32 - # registers except esp may be clobbered at this point - # pop args to scan-next-byte - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that scan-next-byte didn't abort - # . check-ints-equal(ed->value, 0, msg) - # . . push args - 68/push "F - test-scan-next-byte-reads-final-byte: unexpected abort"/imm32 - 68/push 0/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # return if abort - 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 75/jump-if-not-equal $test-scan-next-byte-reads-final-byte:end/disp8 - # check-ints-equal(eax, 0x61/a, msg) - # . . push args - 68/push "F - test-scan-next-byte-reads-final-byte"/imm32 - 68/push 0x61/imm32/a - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-scan-next-byte-reads-final-byte:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -test-scan-next-byte-handles-Eof: - # - check that the right sentinel value is returned when there's no data remaining to be read - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 - # leave '_test-stream' empty - # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call scan-next-byte/disp32 - # registers except esp may be clobbered at this point - # pop args to scan-next-byte - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that scan-next-byte didn't abort - # . check-ints-equal(ed->value, 0, msg) - # . . push args - 68/push "F - test-scan-next-byte-handles-Eof: unexpected abort"/imm32 - 68/push 0/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # return if abort - 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 75/jump-if-not-equal $test-scan-next-byte-handles-Eof:end/disp8 - # check-ints-equal(eax, Eof, msg) - # . . push args - 68/push "F - test-scan-next-byte-handles-Eof"/imm32 - 68/push 0xffffffff/imm32/Eof - 50/push-eax - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-scan-next-byte-handles-Eof:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -test-scan-next-byte-aborts-on-invalid-byte: - # - check that the a bad byte immediately aborts - # This test uses exit-descriptors. Use ebp for setting up local variables. - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # clear all streams - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 - # . clear-stream(_test-error-stream) - # . . push args - 68/push _test-error-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-error-buffered-file+4) - # . . push args - b8/copy-to-eax _test-error-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 '_test-stream' to "x" - # . write(_test-stream, "x") - # . . push args - 68/push "x"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor - 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . tailor-exit-descriptor(ed, 12) - # . . push args - 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 51/push-ecx/ed - # . . call - e8/call tailor-exit-descriptor/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - # . . push args - 51/push-ecx/ed - 68/push _test-error-buffered-file/imm32 - 68/push _test-buffered-file/imm32 - # . . call - e8/call scan-next-byte/disp32 - # registers except esp may be clobbered at this point - # pop args to scan-next-byte - # . . discard first 2 args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . . restore ed - 59/pop-to-ecx - # check that scan-next-byte aborted - # . check-ints-equal(ed->value, 2, msg) - # . . push args - 68/push "F - test-scan-next-byte-aborts-on-invalid-byte"/imm32 - 68/push 2/imm32 - # . . push ed->value - ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -$test-scan-next-byte-aborts-on-invalid-byte:end: - # . epilog - # don't restore esp from ebp; manually reclaim locals - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 5d/pop-to-ebp - c3/return - -skip-until-newline: # in : (address buffered-file) -> <void> - # pseudocode: - # push eax - # while true - # eax = read-byte-buffered(in) - # if (eax == Eof) break - # if (eax == 0x0a) break - # pop eax - # . prolog - 55/push-ebp - 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # . save registers - 50/push-eax -$skip-until-newline:loop: - # . eax = read-byte-buffered(in) - # . . push args - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - # . . call - e8/call read-byte-buffered/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax == Eof) break - 3d/compare-eax-and 0xffffffff/imm32/Eof - 74/jump-if-equal $skip-until-newline:end/disp8 - # . if (eax != 0xa/newline) loop - 3d/compare-eax-and 0xa/imm32/newline - 75/jump-if-not-equal $skip-until-newline:loop/disp8 -$skip-until-newline:end: - # . restore registers - 58/pop-to-eax - # . epilog - 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 5d/pop-to-ebp - c3/return - -test-skip-until-newline: - # - check that the read pointer points after the newline - # setup - # . clear-stream(_test-stream) - # . . push args - 68/push _test-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-buffered-file+4) - # . . push args - b8/copy-to-eax _test-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 '_test-stream' to "abc\nde" - # . write(_test-stream, "abc") - # . . push args - 68/push "abc\n"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . write(_test-stream, "de") - # . . push args - 68/push "de"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call write/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # skip-until-newline(_test-buffered-file) - # . . push args - 68/push _test-buffered-file/imm32 - # . . call - e8/call skip-until-newline/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # check-ints-equal(_test-buffered-file->read, 4, msg) - # . . push args - 68/push "F - test-skip-until-newline"/imm32 - 68/push 4/imm32 - b8/copy-to-eax _test-buffered-file/imm32 - ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 8/disp8 . # push *(eax+8) - # . . call - e8/call check-ints-equal/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - # . end - c3/return - -# . . vim:nowrap:textwidth=0 diff --git a/apps/pack b/apps/pack index 95a306bd..0926d466 100755 --- a/apps/pack +++ b/apps/pack Binary files differdiff --git a/apps/sigils b/apps/sigils index f4f1834d..6c54e194 100755 --- a/apps/sigils +++ b/apps/sigils Binary files differdiff --git a/apps/survey b/apps/survey index 6097c5df..81a4623c 100755 --- a/apps/survey +++ b/apps/survey Binary files differdiff --git a/apps/tests b/apps/tests index 8def31f9..22968ff7 100755 --- a/apps/tests +++ b/apps/tests Binary files differ |