From 282681c729857026e3713d45e9027fdfccda0880 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 31 Aug 2019 23:22:49 -0700 Subject: 5600 --- html/apps/hex.subx.html | 2921 ++++++++++++++++++++++++----------------------- 1 file changed, 1462 insertions(+), 1459 deletions(-) (limited to 'html/apps/hex.subx.html') diff --git a/html/apps/hex.subx.html b/html/apps/hex.subx.html index a1892092..6478a270 100644 --- a/html/apps/hex.subx.html +++ b/html/apps/hex.subx.html @@ -79,1469 +79,1472 @@ if ('onhashchange' in window) { 18 # . 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 19 20 Entry: # run tests if necessary, convert stdin if not - 21 # initialize heap - 22 # . Heap = new-segment(64KB) - 23 # . . push args - 24 68/push Heap/imm32 - 25 68/push 0x10000/imm32/64KB - 26 # . . call - 27 e8/call new-segment/disp32 - 28 # . . discard args - 29 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 30 - 31 # . prolog - 32 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 33 # - if argc > 1 and argv[1] == "test", then return run_tests() - 34 # . argc > 1 - 35 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32 # compare *ebp - 36 7e/jump-if-lesser-or-equal $run-main/disp8 - 37 # . argv[1] == "test" - 38 # . . push args - 39 68/push "test"/imm32 - 40 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 41 # . . call - 42 e8/call kernel-string-equal?/disp32 - 43 # . . discard args - 44 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 45 # . check result - 46 3d/compare-eax-and 1/imm32 - 47 75/jump-if-not-equal $run-main/disp8 - 48 # . run-tests() - 49 e8/call run-tests/disp32 - 50 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx - 51 eb/jump $main:end/disp8 - 52 $run-main: - 53 # - otherwise convert stdin - 54 # var ed/eax : exit-descriptor - 55 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 56 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax - 57 # configure ed to really exit() - 58 # . ed->target = 0 - 59 c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax - 60 # return convert(Stdin, 1/stdout, 2/stderr, ed) - 61 # . . push args - 62 50/push-eax/ed - 63 68/push Stderr/imm32 - 64 68/push Stdout/imm32 - 65 68/push Stdin/imm32 - 66 # . . call - 67 e8/call convert/disp32 - 68 # . . discard args - 69 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp - 70 # . syscall(exit, 0) - 71 bb/copy-to-ebx 0/imm32 - 72 $main:end: - 73 b8/copy-to-eax 1/imm32/exit - 74 cd/syscall 0x80/imm8 - 75 - 76 # the main entry point - 77 convert: # in : (address buffered-file), out : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> <void> - 78 # pseudocode: - 79 # while true - 80 # eax = convert-next-octet(in, err, ed) - 81 # if (eax == Eof) break - 82 # write-byte-buffered(out, AL) - 83 # flush(out) - 84 # - 85 # . prolog - 86 55/push-ebp - 87 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 88 # . save registers - 89 50/push-eax - 90 $convert:loop: - 91 # eax = convert-next-octet(in, err, ed) - 92 # . . push args - 93 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 . # push *(ebp+20) - 94 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 95 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 96 # . . call - 97 e8/call convert-next-octet/disp32 - 98 # . . discard first 2 args - 99 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 100 # if (eax == Eof) break - 101 3d/compare-eax-and 0xffffffff/imm32/Eof - 102 74/jump-if-equal $convert:loop-end/disp8 - 103 # write-byte-buffered(out, AL) - 104 # . . push args - 105 50/push-eax - 106 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 107 # . . call - 108 e8/call write-byte-buffered/disp32 - 109 # . . discard args - 110 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 111 # loop - 112 eb/jump $convert:loop/disp8 - 113 $convert:loop-end: - 114 # flush(out) - 115 # . . push args - 116 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 117 # . . call - 118 e8/call flush/disp32 - 119 # . . discard args - 120 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 121 $convert:end: - 122 # . restore registers - 123 58/pop-to-eax - 124 # . epilog - 125 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 126 5d/pop-to-ebp - 127 c3/return - 128 - 129 # read bytes from 'in' until a sequence of two lowercase hex (0-9, a-f) bytes - 130 # skip spaces and newlines - 131 # on '#' skip bytes until newline - 132 # raise an error and abort on all other unexpected bytes - 133 # return in eax an _octet_ containing the binary value of the two hex characters - 134 # return Eof on reaching end of file - 135 convert-next-octet: # in : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> byte-or-Eof/eax - 136 # pseudocode: - 137 # eax = scan-next-byte(in, err, ed) - 138 # if (eax == Eof) return - 139 # ecx = from-hex-char(eax) + 21 # . prolog + 22 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 23 + 24 # initialize heap + 25 # . Heap = new-segment(64KB) + 26 # . . push args + 27 68/push Heap/imm32 + 28 68/push 0x10000/imm32/64KB + 29 # . . call + 30 e8/call new-segment/disp32 + 31 # . . discard args + 32 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 33 + 34 # - if argc > 1 and argv[1] == "test", then return run_tests() + 35 # if (argc <= 1) goto run-main + 36 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32 # compare *ebp + 37 7e/jump-if-lesser-or-equal $run-main/disp8 + 38 # if (!kernel-string-equal?(argv[1], "test")) goto run-main + 39 # . eax = kernel-string-equal?(argv[1], "test") + 40 # . . push args + 41 68/push "test"/imm32 + 42 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 43 # . . call + 44 e8/call kernel-string-equal?/disp32 + 45 # . . discard args + 46 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 47 # . if (eax == 0) goto run-main + 48 3d/compare-eax-and 0/imm32 + 49 74/jump-if-equal $run-main/disp8 + 50 # run-tests() + 51 e8/call run-tests/disp32 + 52 # return *Num-test-failures + 53 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx + 54 eb/jump $main:end/disp8 + 55 $run-main: + 56 # - otherwise convert stdin + 57 # var ed/eax : exit-descriptor + 58 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp + 59 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax + 60 # configure ed to really exit() + 61 # . ed->target = 0 + 62 c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax + 63 # return convert(Stdin, 1/stdout, 2/stderr, ed) + 64 # . . push args + 65 50/push-eax/ed + 66 68/push Stderr/imm32 + 67 68/push Stdout/imm32 + 68 68/push Stdin/imm32 + 69 # . . call + 70 e8/call convert/disp32 + 71 # . . discard args + 72 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp + 73 # . syscall(exit, 0) + 74 bb/copy-to-ebx 0/imm32 + 75 $main:end: + 76 b8/copy-to-eax 1/imm32/exit + 77 cd/syscall 0x80/imm8 + 78 + 79 # the main entry point + 80 convert: # in : (address buffered-file), out : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> <void> + 81 # pseudocode: + 82 # while true + 83 # eax = convert-next-octet(in, err, ed) + 84 # if (eax == Eof) break + 85 # write-byte-buffered(out, AL) + 86 # flush(out) + 87 # + 88 # . prolog + 89 55/push-ebp + 90 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 91 # . save registers + 92 50/push-eax + 93 $convert:loop: + 94 # eax = convert-next-octet(in, err, ed) + 95 # . . push args + 96 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x14/disp8 . # push *(ebp+20) + 97 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 98 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 99 # . . call + 100 e8/call convert-next-octet/disp32 + 101 # . . discard first 2 args + 102 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 103 # if (eax == Eof) break + 104 3d/compare-eax-and 0xffffffff/imm32/Eof + 105 74/jump-if-equal $convert:loop-end/disp8 + 106 # write-byte-buffered(out, AL) + 107 # . . push args + 108 50/push-eax + 109 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 110 # . . call + 111 e8/call write-byte-buffered/disp32 + 112 # . . discard args + 113 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 114 # loop + 115 eb/jump $convert:loop/disp8 + 116 $convert:loop-end: + 117 # flush(out) + 118 # . . push args + 119 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 120 # . . call + 121 e8/call flush/disp32 + 122 # . . discard args + 123 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 124 $convert:end: + 125 # . restore registers + 126 58/pop-to-eax + 127 # . epilog + 128 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 129 5d/pop-to-ebp + 130 c3/return + 131 + 132 # read bytes from 'in' until a sequence of two lowercase hex (0-9, a-f) bytes + 133 # skip spaces and newlines + 134 # on '#' skip bytes until newline + 135 # raise an error and abort on all other unexpected bytes + 136 # return in eax an _octet_ containing the binary value of the two hex characters + 137 # return Eof on reaching end of file + 138 convert-next-octet: # in : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> byte-or-Eof/eax + 139 # pseudocode: 140 # eax = scan-next-byte(in, err, ed) - 141 # if (eax == Eof) error("partial byte found.") - 142 # eax = from-hex-char(eax) - 143 # eax = (ecx << 4) | eax - 144 # return - 145 # - 146 # . prolog - 147 55/push-ebp - 148 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 149 # . save registers - 150 51/push-ecx - 151 # eax = scan-next-byte(in, err, ed) - 152 # . . push args - 153 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 154 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 155 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 156 # . . call - 157 e8/call scan-next-byte/disp32 - 158 # . . discard args - 159 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 160 # if (eax == Eof) return - 161 3d/compare-eax-and 0xffffffff/imm32/Eof - 162 74/jump-if-equal $convert-next-octet:end/disp8 - 163 # eax = from-hex-char(eax) - 164 e8/call from-hex-char/disp32 - 165 # ecx = eax - 166 89/copy 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # copy eax to ecx - 167 # eax = scan-next-byte(in, err, ed) - 168 # . . push args - 169 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 170 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 171 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 172 # . . call - 173 e8/call scan-next-byte/disp32 - 174 # . . discard args - 175 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 176 # if (eax == Eof) error(ed, err, "partial byte found.") - 177 3d/compare-eax-and 0xffffffff/imm32/Eof - 178 75/jump-if-not-equal $convert-next-octet:convert/disp8 - 179 # . error-byte(ed, err, msg, '.') # reusing error-byte to avoid creating _yet_ another helper - 180 # . . push args - 181 68/push 0x2e/imm32/period/dummy - 182 68/push "convert-next-octet: partial byte found"/imm32 - 183 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 184 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 185 # . . call - 186 e8/call error-byte/disp32 # never returns - 187 $convert-next-octet:convert: - 188 # eax = from-hex-char(eax) - 189 e8/call from-hex-char/disp32 - 190 # eax = (ecx << 4) | eax - 191 # . ecx <<= 4 - 192 c1/shift 4/subop/left 3/mod/direct 1/rm32/ecx . . . . . 4/imm8 # shift ecx left by 4 bits - 193 # . eax |= ecx - 194 09/or 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # eax = bitwise OR with ecx - 195 $convert-next-octet:end: - 196 # . restore registers - 197 59/pop-to-ecx - 198 # . epilog - 199 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 200 5d/pop-to-ebp - 201 c3/return - 202 - 203 test-convert-next-octet: - 204 # - check that the first two bytes of the input are assembled into the resulting octet - 205 # This test uses exit-descriptors. Use ebp for setting up local variables. - 206 55/push-ebp - 207 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 208 # clear all streams - 209 # . clear-stream(_test-stream) - 210 # . . push args - 211 68/push _test-stream/imm32 - 212 # . . call - 213 e8/call clear-stream/disp32 - 214 # . . discard args - 215 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 216 # . clear-stream(_test-buffered-file+4) - 217 # . . push args - 218 b8/copy-to-eax _test-buffered-file/imm32 - 219 05/add-to-eax 4/imm32 - 220 50/push-eax - 221 # . . call - 222 e8/call clear-stream/disp32 - 223 # . . discard args - 224 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 225 # . clear-stream(_test-error-stream) - 226 # . . push args - 227 68/push _test-error-stream/imm32 - 228 # . . call - 229 e8/call clear-stream/disp32 - 230 # . . discard args - 231 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 232 # . clear-stream(_test-error-buffered-file+4) - 233 # . . push args - 234 b8/copy-to-eax _test-error-buffered-file/imm32 - 235 05/add-to-eax 4/imm32 - 236 50/push-eax - 237 # . . call - 238 e8/call clear-stream/disp32 - 239 # . . discard args - 240 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 241 # initialize '_test-stream' to "abc" - 242 # . write(_test-stream, "abc") - 243 # . . push args - 244 68/push "abc"/imm32 - 245 68/push _test-stream/imm32 - 246 # . . call - 247 e8/call write/disp32 - 248 # . . discard args - 249 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 250 # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below - 251 # . var ed/ecx : exit-descriptor - 252 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 253 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 254 # . tailor-exit-descriptor(ed, 12) - 255 # . . push args - 256 68/push 0xc/imm32/nbytes-of-args-for-convert-next-octet - 257 51/push-ecx/ed - 258 # . . call - 259 e8/call tailor-exit-descriptor/disp32 - 260 # . . discard args - 261 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 262 # eax = convert-next-octet(_test-buffered-file, _test-error-buffered-file, ed) - 263 # . . push args - 264 51/push-ecx/ed - 265 68/push _test-error-buffered-file/imm32 - 266 68/push _test-buffered-file/imm32 - 267 # . . call - 268 e8/call convert-next-octet/disp32 - 269 # registers except esp may be clobbered at this point - 270 # pop args to convert-next-octet - 271 # . . discard first 2 args - 272 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 273 # . . restore ed - 274 59/pop-to-ecx - 275 # check that convert-next-octet didn't abort - 276 # . check-ints-equal(ed->value, 0, msg) - 277 # . . push args - 278 68/push "F - test-convert-next-octet: unexpected abort"/imm32 - 279 68/push 0/imm32 - 280 # . . push ed->value - 281 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - 282 # . . call - 283 e8/call check-ints-equal/disp32 - 284 # . . discard args - 285 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 286 # return if abort - 287 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 288 75/jump-if-not-equal $test-convert-next-octet:end/disp8 - 289 # check-ints-equal(eax, 0xab, msg) - 290 # . . push args - 291 68/push "F - test-convert-next-octet"/imm32 - 292 68/push 0xab/imm32/ab - 293 50/push-eax - 294 # . . call - 295 e8/call check-ints-equal/disp32 - 296 # . . discard args - 297 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 298 $test-convert-next-octet:end: - 299 # . epilog - 300 # don't restore esp from ebp; manually reclaim locals - 301 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 302 5d/pop-to-ebp - 303 c3/return - 304 - 305 test-convert-next-octet-handles-Eof: - 306 # - check that reaching end of file returns Eof - 307 # This test uses exit-descriptors. Use ebp for setting up local variables. - 308 55/push-ebp - 309 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 310 # clear all streams - 311 # . clear-stream(_test-stream) - 312 # . . push args - 313 68/push _test-stream/imm32 - 314 # . . call - 315 e8/call clear-stream/disp32 - 316 # . . discard args - 317 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 318 # . clear-stream(_test-buffered-file+4) - 319 # . . push args - 320 b8/copy-to-eax _test-buffered-file/imm32 - 321 05/add-to-eax 4/imm32 - 322 50/push-eax - 323 # . . call - 324 e8/call clear-stream/disp32 - 325 # . . discard args - 326 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 327 # . clear-stream(_test-error-stream) - 328 # . . push args - 329 68/push _test-error-stream/imm32 - 330 # . . call - 331 e8/call clear-stream/disp32 - 332 # . . discard args - 333 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 334 # . clear-stream(_test-error-buffered-file+4) - 335 # . . push args - 336 b8/copy-to-eax _test-error-buffered-file/imm32 - 337 05/add-to-eax 4/imm32 - 338 50/push-eax - 339 # . . call - 340 e8/call clear-stream/disp32 - 341 # . . discard args - 342 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 343 # don't initialize '_test-stream' - 344 # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below - 345 # . var ed/ecx : exit-descriptor - 346 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 347 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 348 # . tailor-exit-descriptor(ed, 12) - 349 # . . push args - 350 68/push 0xc/imm32/nbytes-of-args-for-convert-next-octet - 351 51/push-ecx/ed - 352 # . . call - 353 e8/call tailor-exit-descriptor/disp32 - 354 # . . discard args - 355 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 356 # eax = convert-next-octet(_test-buffered-file, _test-error-buffered-file, ed) - 357 # . . push args - 358 51/push-ecx/ed - 359 68/push _test-error-buffered-file/imm32 - 360 68/push _test-buffered-file/imm32 - 361 # . . call - 362 e8/call convert-next-octet/disp32 - 363 # registers except esp may be clobbered at this point - 364 # pop args to convert-next-octet - 365 # . . discard first 2 args - 366 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 367 # . . restore ed - 368 59/pop-to-ecx - 369 # check that convert-next-octet didn't abort - 370 # . check-ints-equal(ed->value, 0, msg) - 371 # . . push args - 372 68/push "F - test-convert-next-octet: unexpected abort"/imm32 - 373 68/push 0/imm32 - 374 # . . push ed->value - 375 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - 376 # . . call - 377 e8/call check-ints-equal/disp32 - 378 # . . discard args - 379 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 380 # return if abort - 381 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 382 75/jump-if-not-equal $test-convert-next-octet-handles-Eof:end/disp8 - 383 # check-ints-equal(eax, Eof, msg) - 384 # . . push args - 385 68/push "F - test-convert-next-octet-handles-Eof"/imm32 - 386 68/push 0xffffffff/imm32/Eof - 387 50/push-eax - 388 # . . call - 389 e8/call check-ints-equal/disp32 - 390 # . . discard args - 391 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 392 $test-convert-next-octet-handles-Eof:end: - 393 # . epilog - 394 # don't restore esp from ebp; manually reclaim locals - 395 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 396 5d/pop-to-ebp - 397 c3/return - 398 - 399 test-convert-next-octet-aborts-on-single-hex-byte: - 400 # - check that a single unaccompanied hex byte aborts - 401 # This test uses exit-descriptors. Use ebp for setting up local variables. - 402 55/push-ebp - 403 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 404 # clear all streams - 405 # . clear-stream(_test-stream) - 406 # . . push args - 407 68/push _test-stream/imm32 - 408 # . . call - 409 e8/call clear-stream/disp32 - 410 # . . discard args - 411 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 412 # . clear-stream(_test-buffered-file+4) - 413 # . . push args - 414 b8/copy-to-eax _test-buffered-file/imm32 - 415 05/add-to-eax 4/imm32 - 416 50/push-eax - 417 # . . call - 418 e8/call clear-stream/disp32 - 419 # . . discard args - 420 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 421 # . clear-stream(_test-error-stream) - 422 # . . push args - 423 68/push _test-error-stream/imm32 - 424 # . . call - 425 e8/call clear-stream/disp32 - 426 # . . discard args - 427 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 428 # . clear-stream(_test-error-buffered-file+4) - 429 # . . push args - 430 b8/copy-to-eax _test-error-buffered-file/imm32 - 431 05/add-to-eax 4/imm32 - 432 50/push-eax - 433 # . . call - 434 e8/call clear-stream/disp32 - 435 # . . discard args - 436 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 437 # initialize '_test-stream' to "a" - 438 # . write(_test-stream, "a") - 439 # . . push args - 440 68/push "a"/imm32 - 441 68/push _test-stream/imm32 - 442 # . . call - 443 e8/call write/disp32 - 444 # . . discard args - 445 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 446 # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below - 447 # . var ed/ecx : exit-descriptor - 448 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 449 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 450 # . tailor-exit-descriptor(ed, 12) - 451 # . . push args - 452 68/push 0xc/imm32/nbytes-of-args-for-convert-next-octet - 453 51/push-ecx/ed - 454 # . . call - 455 e8/call tailor-exit-descriptor/disp32 - 456 # . . discard args - 457 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 458 # eax = convert-next-octet(_test-buffered-file, _test-error-buffered-file, ed) - 459 # . . push args - 460 51/push-ecx/ed - 461 68/push _test-error-buffered-file/imm32 - 462 68/push _test-buffered-file/imm32 - 463 # . . call - 464 e8/call convert-next-octet/disp32 - 465 # registers except esp may be clobbered at this point - 466 # pop args to convert-next-octet - 467 # . . discard first 2 args - 468 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 469 # . . restore ed - 470 59/pop-to-ecx - 471 # check that convert-next-octet aborted - 472 # . check-ints-equal(ed->value, 2, msg) - 473 # . . push args - 474 68/push "F - test-convert-next-octet-aborts-on-single-hex-byte: unexpected abort"/imm32 - 475 68/push 2/imm32 - 476 # . . push ed->value - 477 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - 478 # . . call - 479 e8/call check-ints-equal/disp32 - 480 # . . discard args - 481 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 482 $test-convert-next-octet-aborts-on-single-hex-byte:end: - 483 # . epilog - 484 # don't restore esp from ebp; manually reclaim locals - 485 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 486 5d/pop-to-ebp - 487 c3/return - 488 - 489 # read whitespace until a hex byte, and return it - 490 # return Eof if file ends without finding a hex byte - 491 # on '#' skip all bytes until newline - 492 # abort on any other byte - 493 scan-next-byte: # in : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> byte-or-Eof/eax - 494 # pseudocode: - 495 # while true - 496 # eax = read-byte-buffered(in) - 497 # if (eax == Eof) return eax - 498 # if (is-hex-digit?(eax)) return eax - 499 # if (eax == ' ' or '\t' or '\n') continue - 500 # if (eax == '#') skip-until-newline(in) - 501 # else error-byte(ed, err, "invalid byte: " eax) - 502 # - 503 # . prolog - 504 55/push-ebp - 505 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 506 # . save registers - 507 $scan-next-byte:loop: - 508 # eax = read-byte-buffered(in) - 509 # . . push args - 510 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 511 # . . call - 512 e8/call read-byte-buffered/disp32 - 513 # . . discard args - 514 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 515 # if (eax == Eof) return eax - 516 3d/compare-with-eax 0xffffffff/imm32/Eof - 517 74/jump-if-equal $scan-next-byte:end/disp8 - 518 # if (is-hex-digit?(eax)) return eax - 519 # . save eax for now - 520 50/push-eax - 521 # . is-hex-digit?(eax) - 522 # . . push args + 141 # if (eax == Eof) return + 142 # ecx = from-hex-char(eax) + 143 # eax = scan-next-byte(in, err, ed) + 144 # if (eax == Eof) error("partial byte found.") + 145 # eax = from-hex-char(eax) + 146 # eax = (ecx << 4) | eax + 147 # return + 148 # + 149 # . prolog + 150 55/push-ebp + 151 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 152 # . save registers + 153 51/push-ecx + 154 # eax = scan-next-byte(in, err, ed) + 155 # . . push args + 156 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 157 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 158 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 159 # . . call + 160 e8/call scan-next-byte/disp32 + 161 # . . discard args + 162 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 163 # if (eax == Eof) return + 164 3d/compare-eax-and 0xffffffff/imm32/Eof + 165 74/jump-if-equal $convert-next-octet:end/disp8 + 166 # eax = from-hex-char(eax) + 167 e8/call from-hex-char/disp32 + 168 # ecx = eax + 169 89/copy 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # copy eax to ecx + 170 # eax = scan-next-byte(in, err, ed) + 171 # . . push args + 172 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 173 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 174 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 175 # . . call + 176 e8/call scan-next-byte/disp32 + 177 # . . discard args + 178 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 179 # if (eax == Eof) error(ed, err, "partial byte found.") + 180 3d/compare-eax-and 0xffffffff/imm32/Eof + 181 75/jump-if-not-equal $convert-next-octet:convert/disp8 + 182 # . error-byte(ed, err, msg, '.') # reusing error-byte to avoid creating _yet_ another helper + 183 # . . push args + 184 68/push 0x2e/imm32/period/dummy + 185 68/push "convert-next-octet: partial byte found"/imm32 + 186 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 187 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 188 # . . call + 189 e8/call error-byte/disp32 # never returns + 190 $convert-next-octet:convert: + 191 # eax = from-hex-char(eax) + 192 e8/call from-hex-char/disp32 + 193 # eax = (ecx << 4) | eax + 194 # . ecx <<= 4 + 195 c1/shift 4/subop/left 3/mod/direct 1/rm32/ecx . . . . . 4/imm8 # shift ecx left by 4 bits + 196 # . eax |= ecx + 197 09/or 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # eax = bitwise OR with ecx + 198 $convert-next-octet:end: + 199 # . restore registers + 200 59/pop-to-ecx + 201 # . epilog + 202 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 203 5d/pop-to-ebp + 204 c3/return + 205 + 206 test-convert-next-octet: + 207 # - check that the first two bytes of the input are assembled into the resulting octet + 208 # This test uses exit-descriptors. Use ebp for setting up local variables. + 209 55/push-ebp + 210 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 211 # clear all streams + 212 # . clear-stream(_test-stream) + 213 # . . push args + 214 68/push _test-stream/imm32 + 215 # . . call + 216 e8/call clear-stream/disp32 + 217 # . . discard args + 218 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 219 # . clear-stream(_test-buffered-file+4) + 220 # . . push args + 221 b8/copy-to-eax _test-buffered-file/imm32 + 222 05/add-to-eax 4/imm32 + 223 50/push-eax + 224 # . . call + 225 e8/call clear-stream/disp32 + 226 # . . discard args + 227 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 228 # . clear-stream(_test-error-stream) + 229 # . . push args + 230 68/push _test-error-stream/imm32 + 231 # . . call + 232 e8/call clear-stream/disp32 + 233 # . . discard args + 234 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 235 # . clear-stream(_test-error-buffered-file+4) + 236 # . . push args + 237 b8/copy-to-eax _test-error-buffered-file/imm32 + 238 05/add-to-eax 4/imm32 + 239 50/push-eax + 240 # . . call + 241 e8/call clear-stream/disp32 + 242 # . . discard args + 243 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 244 # initialize '_test-stream' to "abc" + 245 # . write(_test-stream, "abc") + 246 # . . push args + 247 68/push "abc"/imm32 + 248 68/push _test-stream/imm32 + 249 # . . call + 250 e8/call write/disp32 + 251 # . . discard args + 252 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 253 # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below + 254 # . var ed/ecx : exit-descriptor + 255 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp + 256 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx + 257 # . tailor-exit-descriptor(ed, 12) + 258 # . . push args + 259 68/push 0xc/imm32/nbytes-of-args-for-convert-next-octet + 260 51/push-ecx/ed + 261 # . . call + 262 e8/call tailor-exit-descriptor/disp32 + 263 # . . discard args + 264 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 265 # eax = convert-next-octet(_test-buffered-file, _test-error-buffered-file, ed) + 266 # . . push args + 267 51/push-ecx/ed + 268 68/push _test-error-buffered-file/imm32 + 269 68/push _test-buffered-file/imm32 + 270 # . . call + 271 e8/call convert-next-octet/disp32 + 272 # registers except esp may be clobbered at this point + 273 # pop args to convert-next-octet + 274 # . . discard first 2 args + 275 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 276 # . . restore ed + 277 59/pop-to-ecx + 278 # check that convert-next-octet didn't abort + 279 # . check-ints-equal(ed->value, 0, msg) + 280 # . . push args + 281 68/push "F - test-convert-next-octet: unexpected abort"/imm32 + 282 68/push 0/imm32 + 283 # . . push ed->value + 284 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) + 285 # . . call + 286 e8/call check-ints-equal/disp32 + 287 # . . discard args + 288 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 289 # return if abort + 290 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) + 291 75/jump-if-not-equal $test-convert-next-octet:end/disp8 + 292 # check-ints-equal(eax, 0xab, msg) + 293 # . . push args + 294 68/push "F - test-convert-next-octet"/imm32 + 295 68/push 0xab/imm32/ab + 296 50/push-eax + 297 # . . call + 298 e8/call check-ints-equal/disp32 + 299 # . . discard args + 300 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 301 $test-convert-next-octet:end: + 302 # . epilog + 303 # don't restore esp from ebp; manually reclaim locals + 304 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 305 5d/pop-to-ebp + 306 c3/return + 307 + 308 test-convert-next-octet-handles-Eof: + 309 # - check that reaching end of file returns Eof + 310 # This test uses exit-descriptors. Use ebp for setting up local variables. + 311 55/push-ebp + 312 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 313 # clear all streams + 314 # . clear-stream(_test-stream) + 315 # . . push args + 316 68/push _test-stream/imm32 + 317 # . . call + 318 e8/call clear-stream/disp32 + 319 # . . discard args + 320 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 321 # . clear-stream(_test-buffered-file+4) + 322 # . . push args + 323 b8/copy-to-eax _test-buffered-file/imm32 + 324 05/add-to-eax 4/imm32 + 325 50/push-eax + 326 # . . call + 327 e8/call clear-stream/disp32 + 328 # . . discard args + 329 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 330 # . clear-stream(_test-error-stream) + 331 # . . push args + 332 68/push _test-error-stream/imm32 + 333 # . . call + 334 e8/call clear-stream/disp32 + 335 # . . discard args + 336 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 337 # . clear-stream(_test-error-buffered-file+4) + 338 # . . push args + 339 b8/copy-to-eax _test-error-buffered-file/imm32 + 340 05/add-to-eax 4/imm32 + 341 50/push-eax + 342 # . . call + 343 e8/call clear-stream/disp32 + 344 # . . discard args + 345 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 346 # don't initialize '_test-stream' + 347 # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below + 348 # . var ed/ecx : exit-descriptor + 349 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp + 350 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx + 351 # . tailor-exit-descriptor(ed, 12) + 352 # . . push args + 353 68/push 0xc/imm32/nbytes-of-args-for-convert-next-octet + 354 51/push-ecx/ed + 355 # . . call + 356 e8/call tailor-exit-descriptor/disp32 + 357 # . . discard args + 358 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 359 # eax = convert-next-octet(_test-buffered-file, _test-error-buffered-file, ed) + 360 # . . push args + 361 51/push-ecx/ed + 362 68/push _test-error-buffered-file/imm32 + 363 68/push _test-buffered-file/imm32 + 364 # . . call + 365 e8/call convert-next-octet/disp32 + 366 # registers except esp may be clobbered at this point + 367 # pop args to convert-next-octet + 368 # . . discard first 2 args + 369 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 370 # . . restore ed + 371 59/pop-to-ecx + 372 # check that convert-next-octet didn't abort + 373 # . check-ints-equal(ed->value, 0, msg) + 374 # . . push args + 375 68/push "F - test-convert-next-octet: unexpected abort"/imm32 + 376 68/push 0/imm32 + 377 # . . push ed->value + 378 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) + 379 # . . call + 380 e8/call check-ints-equal/disp32 + 381 # . . discard args + 382 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 383 # return if abort + 384 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) + 385 75/jump-if-not-equal $test-convert-next-octet-handles-Eof:end/disp8 + 386 # check-ints-equal(eax, Eof, msg) + 387 # . . push args + 388 68/push "F - test-convert-next-octet-handles-Eof"/imm32 + 389 68/push 0xffffffff/imm32/Eof + 390 50/push-eax + 391 # . . call + 392 e8/call check-ints-equal/disp32 + 393 # . . discard args + 394 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 395 $test-convert-next-octet-handles-Eof:end: + 396 # . epilog + 397 # don't restore esp from ebp; manually reclaim locals + 398 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 399 5d/pop-to-ebp + 400 c3/return + 401 + 402 test-convert-next-octet-aborts-on-single-hex-byte: + 403 # - check that a single unaccompanied hex byte aborts + 404 # This test uses exit-descriptors. Use ebp for setting up local variables. + 405 55/push-ebp + 406 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 407 # clear all streams + 408 # . clear-stream(_test-stream) + 409 # . . push args + 410 68/push _test-stream/imm32 + 411 # . . call + 412 e8/call clear-stream/disp32 + 413 # . . discard args + 414 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 415 # . clear-stream(_test-buffered-file+4) + 416 # . . push args + 417 b8/copy-to-eax _test-buffered-file/imm32 + 418 05/add-to-eax 4/imm32 + 419 50/push-eax + 420 # . . call + 421 e8/call clear-stream/disp32 + 422 # . . discard args + 423 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 424 # . clear-stream(_test-error-stream) + 425 # . . push args + 426 68/push _test-error-stream/imm32 + 427 # . . call + 428 e8/call clear-stream/disp32 + 429 # . . discard args + 430 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 431 # . clear-stream(_test-error-buffered-file+4) + 432 # . . push args + 433 b8/copy-to-eax _test-error-buffered-file/imm32 + 434 05/add-to-eax 4/imm32 + 435 50/push-eax + 436 # . . call + 437 e8/call clear-stream/disp32 + 438 # . . discard args + 439 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 440 # initialize '_test-stream' to "a" + 441 # . write(_test-stream, "a") + 442 # . . push args + 443 68/push "a"/imm32 + 444 68/push _test-stream/imm32 + 445 # . . call + 446 e8/call write/disp32 + 447 # . . discard args + 448 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 449 # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below + 450 # . var ed/ecx : exit-descriptor + 451 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp + 452 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx + 453 # . tailor-exit-descriptor(ed, 12) + 454 # . . push args + 455 68/push 0xc/imm32/nbytes-of-args-for-convert-next-octet + 456 51/push-ecx/ed + 457 # . . call + 458 e8/call tailor-exit-descriptor/disp32 + 459 # . . discard args + 460 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 461 # eax = convert-next-octet(_test-buffered-file, _test-error-buffered-file, ed) + 462 # . . push args + 463 51/push-ecx/ed + 464 68/push _test-error-buffered-file/imm32 + 465 68/push _test-buffered-file/imm32 + 466 # . . call + 467 e8/call convert-next-octet/disp32 + 468 # registers except esp may be clobbered at this point + 469 # pop args to convert-next-octet + 470 # . . discard first 2 args + 471 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 472 # . . restore ed + 473 59/pop-to-ecx + 474 # check that convert-next-octet aborted + 475 # . check-ints-equal(ed->value, 2, msg) + 476 # . . push args + 477 68/push "F - test-convert-next-octet-aborts-on-single-hex-byte: unexpected abort"/imm32 + 478 68/push 2/imm32 + 479 # . . push ed->value + 480 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) + 481 # . . call + 482 e8/call check-ints-equal/disp32 + 483 # . . discard args + 484 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 485 $test-convert-next-octet-aborts-on-single-hex-byte:end: + 486 # . epilog + 487 # don't restore esp from ebp; manually reclaim locals + 488 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 489 5d/pop-to-ebp + 490 c3/return + 491 + 492 # read whitespace until a hex byte, and return it + 493 # return Eof if file ends without finding a hex byte + 494 # on '#' skip all bytes until newline + 495 # abort on any other byte + 496 scan-next-byte: # in : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> byte-or-Eof/eax + 497 # pseudocode: + 498 # while true + 499 # eax = read-byte-buffered(in) + 500 # if (eax == Eof) return eax + 501 # if (is-hex-digit?(eax)) return eax + 502 # if (eax == ' ' or '\t' or '\n') continue + 503 # if (eax == '#') skip-until-newline(in) + 504 # else error-byte(ed, err, "invalid byte: " eax) + 505 # + 506 # . prolog + 507 55/push-ebp + 508 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 509 # . save registers + 510 $scan-next-byte:loop: + 511 # eax = read-byte-buffered(in) + 512 # . . push args + 513 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 514 # . . call + 515 e8/call read-byte-buffered/disp32 + 516 # . . discard args + 517 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 518 # if (eax == Eof) return eax + 519 3d/compare-with-eax 0xffffffff/imm32/Eof + 520 74/jump-if-equal $scan-next-byte:end/disp8 + 521 # if (is-hex-digit?(eax)) return eax + 522 # . save eax for now 523 50/push-eax - 524 # . . call - 525 e8/call is-hex-digit?/disp32 - 526 # . . discard args - 527 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 528 # . compare with 'false' - 529 3d/compare-with-eax 0/imm32 - 530 # . restore eax (does not affect flags) - 531 58/pop-to-eax - 532 # . check whether to return - 533 75/jump-if-not-equal $scan-next-byte:end/disp8 - 534 $scan-next-byte:check1: - 535 # if (eax == ' ') continue - 536 3d/compare-eax-and 0x20/imm32/space - 537 74/jump-if-equal $scan-next-byte:loop/disp8 - 538 # if (eax == '\t') continue - 539 3d/compare-eax-and 9/imm32/tab + 524 # . is-hex-digit?(eax) + 525 # . . push args + 526 50/push-eax + 527 # . . call + 528 e8/call is-hex-digit?/disp32 + 529 # . . discard args + 530 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 531 # . compare with 'false' + 532 3d/compare-with-eax 0/imm32 + 533 # . restore eax (does not affect flags) + 534 58/pop-to-eax + 535 # . check whether to return + 536 75/jump-if-not-equal $scan-next-byte:end/disp8 + 537 $scan-next-byte:check1: + 538 # if (eax == ' ') continue + 539 3d/compare-eax-and 0x20/imm32/space 540 74/jump-if-equal $scan-next-byte:loop/disp8 - 541 # if (eax == '\n') continue - 542 3d/compare-eax-and 0xa/imm32/newline + 541 # if (eax == '\t') continue + 542 3d/compare-eax-and 9/imm32/tab 543 74/jump-if-equal $scan-next-byte:loop/disp8 - 544 $scan-next-byte:check2: - 545 # if (eax == '#') skip-until-newline(in) - 546 3d/compare-with-eax 0x23/imm32 - 547 75/jump-if-not-equal $scan-next-byte:check3/disp8 - 548 # . skip-until-newline(in) - 549 # . . push args - 550 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - 551 # . . call - 552 e8/call skip-until-newline/disp32 - 553 # . . discard args - 554 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 555 eb/jump $scan-next-byte:loop/disp8 - 556 $scan-next-byte:check3: - 557 # otherwise error-byte(ed, err, msg, eax) - 558 # . . push args - 559 50/push-eax - 560 68/push "scan-next-byte: invalid byte"/imm32 - 561 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) - 562 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) - 563 # . . call - 564 e8/call error-byte/disp32 # never returns - 565 $scan-next-byte:end: - 566 # . restore registers - 567 # . epilog - 568 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp - 569 5d/pop-to-ebp - 570 c3/return - 571 - 572 test-scan-next-byte: - 573 # - check that the first byte of the input is returned - 574 # This test uses exit-descriptors. Use ebp for setting up local variables. - 575 55/push-ebp - 576 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 577 # clear all streams - 578 # . clear-stream(_test-stream) - 579 # . . push args - 580 68/push _test-stream/imm32 - 581 # . . call - 582 e8/call clear-stream/disp32 - 583 # . . discard args - 584 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 585 # . clear-stream(_test-buffered-file+4) - 586 # . . push args - 587 b8/copy-to-eax _test-buffered-file/imm32 - 588 05/add-to-eax 4/imm32 - 589 50/push-eax - 590 # . . call - 591 e8/call clear-stream/disp32 - 592 # . . discard args - 593 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 594 # . clear-stream(_test-error-stream) - 595 # . . push args - 596 68/push _test-error-stream/imm32 - 597 # . . call - 598 e8/call clear-stream/disp32 - 599 # . . discard args - 600 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 601 # . clear-stream(_test-error-buffered-file+4) - 602 # . . push args - 603 b8/copy-to-eax _test-error-buffered-file/imm32 - 604 05/add-to-eax 4/imm32 - 605 50/push-eax - 606 # . . call - 607 e8/call clear-stream/disp32 - 608 # . . discard args - 609 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 610 # initialize '_test-stream' to "abc" - 611 # . write(_test-stream, "abc") - 612 # . . push args - 613 68/push "abc"/imm32 - 614 68/push _test-stream/imm32 - 615 # . . call - 616 e8/call write/disp32 - 617 # . . discard args - 618 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 619 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - 620 # . var ed/ecx : exit-descriptor - 621 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 622 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 623 # . tailor-exit-descriptor(ed, 12) - 624 # . . push args - 625 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 626 51/push-ecx/ed - 627 # . . call - 628 e8/call tailor-exit-descriptor/disp32 - 629 # . . discard args - 630 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 631 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - 632 # . . push args - 633 51/push-ecx/ed - 634 68/push _test-error-buffered-file/imm32 - 635 68/push _test-buffered-file/imm32 - 636 # . . call - 637 e8/call scan-next-byte/disp32 - 638 # registers except esp may be clobbered at this point - 639 # pop args to scan-next-byte - 640 # . . discard first 2 args - 641 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 642 # . . restore ed - 643 59/pop-to-ecx - 644 # check that scan-next-byte didn't abort - 645 # . check-ints-equal(ed->value, 0, msg) - 646 # . . push args - 647 68/push "F - test-scan-next-byte: unexpected abort"/imm32 - 648 68/push 0/imm32 - 649 # . . push ed->value - 650 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - 651 # . . call - 652 e8/call check-ints-equal/disp32 - 653 # . . discard args - 654 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 655 # return if abort - 656 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 657 75/jump-if-not-equal $test-scan-next-byte:end/disp8 - 658 # check-ints-equal(eax, 0x61/a, msg) - 659 # . . push args - 660 68/push "F - test-scan-next-byte"/imm32 - 661 68/push 0x61/imm32/a - 662 50/push-eax - 663 # . . call - 664 e8/call check-ints-equal/disp32 - 665 # . . discard args - 666 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 667 $test-scan-next-byte:end: - 668 # . epilog - 669 # don't restore esp from ebp; manually reclaim locals - 670 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 671 5d/pop-to-ebp - 672 c3/return - 673 - 674 test-scan-next-byte-skips-whitespace: - 675 # - check that the first byte after whitespace is returned - 676 # This test uses exit-descriptors. Use ebp for setting up local variables. - 677 55/push-ebp - 678 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 679 # clear all streams - 680 # . clear-stream(_test-stream) - 681 # . . push args - 682 68/push _test-stream/imm32 - 683 # . . call - 684 e8/call clear-stream/disp32 - 685 # . . discard args - 686 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 687 # . clear-stream(_test-buffered-file+4) - 688 # . . push args - 689 b8/copy-to-eax _test-buffered-file/imm32 - 690 05/add-to-eax 4/imm32 - 691 50/push-eax - 692 # . . call - 693 e8/call clear-stream/disp32 - 694 # . . discard args - 695 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 696 # . clear-stream(_test-error-stream) - 697 # . . push args - 698 68/push _test-error-stream/imm32 - 699 # . . call - 700 e8/call clear-stream/disp32 - 701 # . . discard args - 702 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 703 # . clear-stream(_test-error-buffered-file+4) - 704 # . . push args - 705 b8/copy-to-eax _test-error-buffered-file/imm32 - 706 05/add-to-eax 4/imm32 - 707 50/push-eax - 708 # . . call - 709 e8/call clear-stream/disp32 - 710 # . . discard args - 711 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 712 # initialize '_test-stream' to input with leading whitespace - 713 # . write(_test-stream, text) - 714 # . . push args - 715 68/push " abc"/imm32 - 716 68/push _test-stream/imm32 - 717 # . . call - 718 e8/call write/disp32 - 719 # . . discard args - 720 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 721 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - 722 # . var ed/ecx : exit-descriptor - 723 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 724 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 725 # . tailor-exit-descriptor(ed, 12) - 726 # . . push args - 727 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 728 51/push-ecx/ed - 729 # . . call - 730 e8/call tailor-exit-descriptor/disp32 - 731 # . . discard args - 732 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 733 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - 734 # . . push args - 735 51/push-ecx/ed - 736 68/push _test-error-buffered-file/imm32 - 737 68/push _test-buffered-file/imm32 - 738 # . . call - 739 e8/call scan-next-byte/disp32 - 740 # registers except esp may be clobbered at this point - 741 # pop args to scan-next-byte - 742 # . . discard first 2 args - 743 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 744 # . . restore ed - 745 59/pop-to-ecx - 746 # check that scan-next-byte didn't abort - 747 # . check-ints-equal(ed->value, 0, msg) - 748 # . . push args - 749 68/push "F - test-scan-next-byte-skips-whitespace: unexpected abort"/imm32 - 750 68/push 0/imm32 - 751 # . . push ed->value - 752 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - 753 # . . call - 754 e8/call check-ints-equal/disp32 - 755 # . . discard args - 756 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 757 # return if abort - 758 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 759 75/jump-if-not-equal $test-scan-next-byte-skips-whitespace:end/disp8 - 760 # check-ints-equal(eax, 0x61/a, msg) - 761 # . . push args - 762 68/push "F - test-scan-next-byte-skips-whitespace"/imm32 - 763 68/push 0x61/imm32/a - 764 50/push-eax - 765 # . . call - 766 e8/call check-ints-equal/disp32 - 767 # . . discard args - 768 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 769 $test-scan-next-byte-skips-whitespace:end: - 770 # . epilog - 771 # don't restore esp from ebp; manually reclaim locals - 772 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 773 5d/pop-to-ebp - 774 c3/return - 775 - 776 test-scan-next-byte-skips-comment: - 777 # - check that the first byte after a comment (and newline) is returned - 778 # This test uses exit-descriptors. Use ebp for setting up local variables. - 779 55/push-ebp - 780 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 781 # clear all streams - 782 # . clear-stream(_test-stream) - 783 # . . push args - 784 68/push _test-stream/imm32 - 785 # . . call - 786 e8/call clear-stream/disp32 - 787 # . . discard args - 788 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 789 # . clear-stream(_test-buffered-file+4) - 790 # . . push args - 791 b8/copy-to-eax _test-buffered-file/imm32 - 792 05/add-to-eax 4/imm32 - 793 50/push-eax - 794 # . . call - 795 e8/call clear-stream/disp32 - 796 # . . discard args - 797 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 798 # . clear-stream(_test-error-stream) - 799 # . . push args - 800 68/push _test-error-stream/imm32 - 801 # . . call - 802 e8/call clear-stream/disp32 - 803 # . . discard args - 804 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 805 # . clear-stream(_test-error-buffered-file+4) - 806 # . . push args - 807 b8/copy-to-eax _test-error-buffered-file/imm32 - 808 05/add-to-eax 4/imm32 - 809 50/push-eax - 810 # . . call - 811 e8/call clear-stream/disp32 - 812 # . . discard args - 813 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 814 # initialize '_test-stream' to input with leading comment - 815 # . write(_test-stream, comment) - 816 # . . push args - 817 68/push "#x\n"/imm32 - 818 68/push _test-stream/imm32 - 819 # . . call - 820 e8/call write/disp32 - 821 # . . discard args - 822 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 823 # . write(_test-stream, real text) - 824 # . . push args - 825 68/push "ab"/imm32 - 826 68/push _test-stream/imm32 - 827 # . . call - 828 e8/call write/disp32 - 829 # . . discard args - 830 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 831 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - 832 # . var ed/ecx : exit-descriptor - 833 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 834 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 835 # . tailor-exit-descriptor(ed, 12) - 836 # . . push args - 837 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 838 51/push-ecx/ed - 839 # . . call - 840 e8/call tailor-exit-descriptor/disp32 - 841 # . . discard args - 842 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 843 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - 844 # . . push args - 845 51/push-ecx/ed - 846 68/push _test-error-buffered-file/imm32 - 847 68/push _test-buffered-file/imm32 - 848 # . . call - 849 e8/call scan-next-byte/disp32 - 850 # registers except esp may be clobbered at this point - 851 # pop args to scan-next-byte - 852 # . . discard first 2 args - 853 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 854 # . . restore ed - 855 59/pop-to-ecx - 856 # check that scan-next-byte didn't abort - 857 # . check-ints-equal(ed->value, 0, msg) - 858 # . . push args - 859 68/push "F - test-scan-next-byte-skips-comment: unexpected abort"/imm32 - 860 68/push 0/imm32 - 861 # . . push ed->value - 862 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - 863 # . . call - 864 e8/call check-ints-equal/disp32 - 865 # . . discard args - 866 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 867 # return if abort - 868 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 869 75/jump-if-not-equal $test-scan-next-byte-skips-comment:end/disp8 - 870 # check-ints-equal(eax, 0x61/a, msg) - 871 # . . push args - 872 68/push "F - test-scan-next-byte-skips-comment"/imm32 - 873 68/push 0x61/imm32/a - 874 50/push-eax - 875 # . . call - 876 e8/call check-ints-equal/disp32 - 877 # . . discard args - 878 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 879 $test-scan-next-byte-skips-comment:end: - 880 # . epilog - 881 # don't restore esp from ebp; manually reclaim locals - 882 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 883 5d/pop-to-ebp - 884 c3/return - 885 - 886 test-scan-next-byte-skips-comment-and-whitespace: - 887 # - check that the first byte after a comment and any further whitespace is returned - 888 # This test uses exit-descriptors. Use ebp for setting up local variables. - 889 55/push-ebp - 890 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 891 # clear all streams - 892 # . clear-stream(_test-stream) - 893 # . . push args - 894 68/push _test-stream/imm32 - 895 # . . call - 896 e8/call clear-stream/disp32 - 897 # . . discard args - 898 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 899 # . clear-stream(_test-buffered-file+4) - 900 # . . push args - 901 b8/copy-to-eax _test-buffered-file/imm32 - 902 05/add-to-eax 4/imm32 - 903 50/push-eax - 904 # . . call - 905 e8/call clear-stream/disp32 - 906 # . . discard args - 907 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 908 # . clear-stream(_test-error-stream) - 909 # . . push args - 910 68/push _test-error-stream/imm32 - 911 # . . call - 912 e8/call clear-stream/disp32 - 913 # . . discard args - 914 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 915 # . clear-stream(_test-error-buffered-file+4) - 916 # . . push args - 917 b8/copy-to-eax _test-error-buffered-file/imm32 - 918 05/add-to-eax 4/imm32 - 919 50/push-eax - 920 # . . call - 921 e8/call clear-stream/disp32 - 922 # . . discard args - 923 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - 924 # initialize '_test-stream' to input with leading comment and more whitespace after newline - 925 # . write(_test-stream, comment) - 926 # . . push args - 927 68/push "#x\n"/imm32 - 928 68/push _test-stream/imm32 - 929 # . . call - 930 e8/call write/disp32 - 931 # . . discard args - 932 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 933 # . write(_test-stream, real text) - 934 # . . push args - 935 68/push " ab"/imm32 - 936 68/push _test-stream/imm32 - 937 # . . call - 938 e8/call write/disp32 - 939 # . . discard args - 940 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 941 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - 942 # . var ed/ecx : exit-descriptor - 943 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp - 944 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - 945 # . tailor-exit-descriptor(ed, 12) - 946 # . . push args - 947 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte - 948 51/push-ecx/ed - 949 # . . call - 950 e8/call tailor-exit-descriptor/disp32 - 951 # . . discard args - 952 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 953 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) - 954 # . . push args - 955 51/push-ecx/ed - 956 68/push _test-error-buffered-file/imm32 - 957 68/push _test-buffered-file/imm32 - 958 # . . call - 959 e8/call scan-next-byte/disp32 - 960 # registers except esp may be clobbered at this point - 961 # pop args to scan-next-byte - 962 # . . discard first 2 args - 963 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 964 # . . restore ed - 965 59/pop-to-ecx - 966 # check that scan-next-byte didn't abort - 967 # . check-ints-equal(ed->value, 0, msg) - 968 # . . push args - 969 68/push "F - test-scan-next-byte-skips-comment-and-whitespace: unexpected abort"/imm32 - 970 68/push 0/imm32 - 971 # . . push ed->value - 972 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) - 973 # . . call - 974 e8/call check-ints-equal/disp32 - 975 # . . discard args - 976 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 977 # return if abort - 978 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) - 979 75/jump-if-not-equal $test-scan-next-byte-skips-comment-and-whitespace:end/disp8 - 980 # check-ints-equal(eax, 0x61/a, msg) - 981 # . . push args - 982 68/push "F - test-scan-next-byte-skips-comment-and-whitespace"/imm32 - 983 68/push 0x61/imm32/a - 984 50/push-eax - 985 # . . call - 986 e8/call check-ints-equal/disp32 - 987 # . . discard args - 988 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp - 989 $test-scan-next-byte-skips-comment-and-whitespace:end: - 990 # . epilog - 991 # don't restore esp from ebp; manually reclaim locals - 992 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - 993 5d/pop-to-ebp - 994 c3/return - 995 - 996 test-scan-next-byte-skips-whitespace-and-comment: - 997 # - check that the first byte after any whitespace and comments is returned - 998 # This test uses exit-descriptors. Use ebp for setting up local variables. - 999 55/push-ebp -1000 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1001 # clear all streams -1002 # . clear-stream(_test-stream) -1003 # . . push args -1004 68/push _test-stream/imm32 -1005 # . . call -1006 e8/call clear-stream/disp32 -1007 # . . discard args -1008 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1009 # . clear-stream(_test-buffered-file+4) -1010 # . . push args -1011 b8/copy-to-eax _test-buffered-file/imm32 -1012 05/add-to-eax 4/imm32 -1013 50/push-eax -1014 # . . call -1015 e8/call clear-stream/disp32 -1016 # . . discard args -1017 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1018 # . clear-stream(_test-error-stream) -1019 # . . push args -1020 68/push _test-error-stream/imm32 -1021 # . . call -1022 e8/call clear-stream/disp32 -1023 # . . discard args -1024 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1025 # . clear-stream(_test-error-buffered-file+4) -1026 # . . push args -1027 b8/copy-to-eax _test-error-buffered-file/imm32 -1028 05/add-to-eax 4/imm32 -1029 50/push-eax -1030 # . . call -1031 e8/call clear-stream/disp32 -1032 # . . discard args -1033 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1034 # initialize '_test-stream' to input with leading whitespace and comment -1035 # . write(_test-stream, comment) -1036 # . . push args -1037 68/push " #x\n"/imm32 -1038 68/push _test-stream/imm32 -1039 # . . call -1040 e8/call write/disp32 -1041 # . . discard args -1042 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1043 # . write(_test-stream, real text) -1044 # . . push args -1045 68/push "ab"/imm32 -1046 68/push _test-stream/imm32 -1047 # . . call -1048 e8/call write/disp32 -1049 # . . discard args -1050 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1051 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below -1052 # . var ed/ecx : exit-descriptor -1053 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp -1054 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1055 # . tailor-exit-descriptor(ed, 12) -1056 # . . push args -1057 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte -1058 51/push-ecx/ed -1059 # . . call -1060 e8/call tailor-exit-descriptor/disp32 -1061 # . . discard args -1062 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1063 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) -1064 # . . push args -1065 51/push-ecx/ed -1066 68/push _test-error-buffered-file/imm32 -1067 68/push _test-buffered-file/imm32 -1068 # . . call -1069 e8/call scan-next-byte/disp32 -1070 # registers except esp may be clobbered at this point -1071 # pop args to scan-next-byte -1072 # . . discard first 2 args -1073 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1074 # . . restore ed -1075 59/pop-to-ecx -1076 # check that scan-next-byte didn't abort -1077 # . check-ints-equal(ed->value, 0, msg) -1078 # . . push args -1079 68/push "F - test-scan-next-byte-skips-whitespace-and-comment: unexpected abort"/imm32 -1080 68/push 0/imm32 -1081 # . . push ed->value -1082 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) -1083 # . . call -1084 e8/call check-ints-equal/disp32 -1085 # . . discard args -1086 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1087 # return if abort -1088 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) -1089 75/jump-if-not-equal $test-scan-next-byte-skips-whitespace-and-comment:end/disp8 -1090 # check-ints-equal(eax, 0x61/a, msg) -1091 # . . push args -1092 68/push "F - test-scan-next-byte-skips-whitespace-and-comment"/imm32 -1093 68/push 0x61/imm32/a -1094 50/push-eax -1095 # . . call -1096 e8/call check-ints-equal/disp32 -1097 # . . discard args -1098 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1099 $test-scan-next-byte-skips-whitespace-and-comment:end: -1100 # . epilog -1101 # don't restore esp from ebp; manually reclaim locals -1102 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1103 5d/pop-to-ebp -1104 c3/return -1105 -1106 test-scan-next-byte-reads-final-byte: -1107 # - check that the final byte in input is returned -1108 # This test uses exit-descriptors. Use ebp for setting up local variables. -1109 55/push-ebp -1110 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1111 # clear all streams -1112 # . clear-stream(_test-stream) -1113 # . . push args -1114 68/push _test-stream/imm32 -1115 # . . call -1116 e8/call clear-stream/disp32 -1117 # . . discard args -1118 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1119 # . clear-stream(_test-buffered-file+4) -1120 # . . push args -1121 b8/copy-to-eax _test-buffered-file/imm32 -1122 05/add-to-eax 4/imm32 -1123 50/push-eax -1124 # . . call -1125 e8/call clear-stream/disp32 -1126 # . . discard args -1127 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1128 # . clear-stream(_test-error-stream) -1129 # . . push args -1130 68/push _test-error-stream/imm32 -1131 # . . call -1132 e8/call clear-stream/disp32 -1133 # . . discard args -1134 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1135 # . clear-stream(_test-error-buffered-file+4) -1136 # . . push args -1137 b8/copy-to-eax _test-error-buffered-file/imm32 -1138 05/add-to-eax 4/imm32 -1139 50/push-eax -1140 # . . call -1141 e8/call clear-stream/disp32 -1142 # . . discard args -1143 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1144 # initialize '_test-stream' to input with single character -1145 # . write(_test-stream, character) -1146 # . . push args -1147 68/push "a"/imm32 -1148 68/push _test-stream/imm32 -1149 # . . call -1150 e8/call write/disp32 -1151 # . . discard args -1152 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1153 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below -1154 # . var ed/ecx : exit-descriptor -1155 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp -1156 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1157 # . tailor-exit-descriptor(ed, 12) -1158 # . . push args -1159 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte -1160 51/push-ecx/ed -1161 # . . call -1162 e8/call tailor-exit-descriptor/disp32 -1163 # . . discard args -1164 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1165 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) -1166 # . . push args -1167 51/push-ecx/ed -1168 68/push _test-error-buffered-file/imm32 -1169 68/push _test-buffered-file/imm32 -1170 # . . call -1171 e8/call scan-next-byte/disp32 -1172 # registers except esp may be clobbered at this point -1173 # pop args to scan-next-byte -1174 # . . discard first 2 args -1175 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1176 # . . restore ed -1177 59/pop-to-ecx -1178 # check that scan-next-byte didn't abort -1179 # . check-ints-equal(ed->value, 0, msg) -1180 # . . push args -1181 68/push "F - test-scan-next-byte-reads-final-byte: unexpected abort"/imm32 -1182 68/push 0/imm32 -1183 # . . push ed->value -1184 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) -1185 # . . call -1186 e8/call check-ints-equal/disp32 -1187 # . . discard args -1188 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1189 # return if abort -1190 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) -1191 75/jump-if-not-equal $test-scan-next-byte-reads-final-byte:end/disp8 -1192 # check-ints-equal(eax, 0x61/a, msg) -1193 # . . push args -1194 68/push "F - test-scan-next-byte-reads-final-byte"/imm32 -1195 68/push 0x61/imm32/a -1196 50/push-eax -1197 # . . call -1198 e8/call check-ints-equal/disp32 -1199 # . . discard args -1200 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1201 $test-scan-next-byte-reads-final-byte:end: -1202 # . epilog -1203 # don't restore esp from ebp; manually reclaim locals -1204 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1205 5d/pop-to-ebp -1206 c3/return -1207 -1208 test-scan-next-byte-handles-Eof: -1209 # - check that the right sentinel value is returned when there's no data remaining to be read -1210 # This test uses exit-descriptors. Use ebp for setting up local variables. -1211 55/push-ebp -1212 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1213 # clear all streams -1214 # . clear-stream(_test-stream) -1215 # . . push args -1216 68/push _test-stream/imm32 -1217 # . . call -1218 e8/call clear-stream/disp32 -1219 # . . discard args -1220 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1221 # . clear-stream(_test-buffered-file+4) -1222 # . . push args -1223 b8/copy-to-eax _test-buffered-file/imm32 -1224 05/add-to-eax 4/imm32 -1225 50/push-eax -1226 # . . call -1227 e8/call clear-stream/disp32 -1228 # . . discard args -1229 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1230 # . clear-stream(_test-error-stream) -1231 # . . push args -1232 68/push _test-error-stream/imm32 -1233 # . . call -1234 e8/call clear-stream/disp32 -1235 # . . discard args -1236 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1237 # . clear-stream(_test-error-buffered-file+4) -1238 # . . push args -1239 b8/copy-to-eax _test-error-buffered-file/imm32 -1240 05/add-to-eax 4/imm32 -1241 50/push-eax -1242 # . . call -1243 e8/call clear-stream/disp32 -1244 # . . discard args -1245 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1246 # leave '_test-stream' empty -1247 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below -1248 # . var ed/ecx : exit-descriptor -1249 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp -1250 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1251 # . tailor-exit-descriptor(ed, 12) -1252 # . . push args -1253 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte -1254 51/push-ecx/ed -1255 # . . call -1256 e8/call tailor-exit-descriptor/disp32 -1257 # . . discard args -1258 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1259 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) -1260 # . . push args -1261 51/push-ecx/ed -1262 68/push _test-error-buffered-file/imm32 -1263 68/push _test-buffered-file/imm32 -1264 # . . call -1265 e8/call scan-next-byte/disp32 -1266 # registers except esp may be clobbered at this point -1267 # pop args to scan-next-byte -1268 # . . discard first 2 args -1269 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1270 # . . restore ed -1271 59/pop-to-ecx -1272 # check that scan-next-byte didn't abort -1273 # . check-ints-equal(ed->value, 0, msg) -1274 # . . push args -1275 68/push "F - test-scan-next-byte-handles-Eof: unexpected abort"/imm32 -1276 68/push 0/imm32 -1277 # . . push ed->value -1278 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) -1279 # . . call -1280 e8/call check-ints-equal/disp32 -1281 # . . discard args -1282 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1283 # return if abort -1284 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) -1285 75/jump-if-not-equal $test-scan-next-byte-handles-Eof:end/disp8 -1286 # check-ints-equal(eax, Eof, msg) -1287 # . . push args -1288 68/push "F - test-scan-next-byte-handles-Eof"/imm32 -1289 68/push 0xffffffff/imm32/Eof -1290 50/push-eax -1291 # . . call -1292 e8/call check-ints-equal/disp32 -1293 # . . discard args -1294 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1295 $test-scan-next-byte-handles-Eof:end: -1296 # . epilog -1297 # don't restore esp from ebp; manually reclaim locals -1298 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1299 5d/pop-to-ebp -1300 c3/return -1301 -1302 test-scan-next-byte-aborts-on-invalid-byte: -1303 # - check that the a bad byte immediately aborts -1304 # This test uses exit-descriptors. Use ebp for setting up local variables. -1305 55/push-ebp -1306 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1307 # clear all streams -1308 # . clear-stream(_test-stream) -1309 # . . push args -1310 68/push _test-stream/imm32 -1311 # . . call -1312 e8/call clear-stream/disp32 -1313 # . . discard args -1314 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1315 # . clear-stream(_test-buffered-file+4) -1316 # . . push args -1317 b8/copy-to-eax _test-buffered-file/imm32 -1318 05/add-to-eax 4/imm32 -1319 50/push-eax -1320 # . . call -1321 e8/call clear-stream/disp32 -1322 # . . discard args -1323 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1324 # . clear-stream(_test-error-stream) -1325 # . . push args -1326 68/push _test-error-stream/imm32 -1327 # . . call -1328 e8/call clear-stream/disp32 -1329 # . . discard args -1330 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1331 # . clear-stream(_test-error-buffered-file+4) -1332 # . . push args -1333 b8/copy-to-eax _test-error-buffered-file/imm32 -1334 05/add-to-eax 4/imm32 -1335 50/push-eax -1336 # . . call -1337 e8/call clear-stream/disp32 -1338 # . . discard args -1339 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1340 # initialize '_test-stream' to "x" -1341 # . write(_test-stream, "x") -1342 # . . push args -1343 68/push "x"/imm32 -1344 68/push _test-stream/imm32 -1345 # . . call -1346 e8/call write/disp32 -1347 # . . discard args -1348 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1349 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below -1350 # . var ed/ecx : exit-descriptor -1351 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp -1352 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx -1353 # . tailor-exit-descriptor(ed, 12) -1354 # . . push args -1355 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte -1356 51/push-ecx/ed -1357 # . . call -1358 e8/call tailor-exit-descriptor/disp32 -1359 # . . discard args -1360 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1361 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) -1362 # . . push args -1363 51/push-ecx/ed -1364 68/push _test-error-buffered-file/imm32 -1365 68/push _test-buffered-file/imm32 -1366 # . . call -1367 e8/call scan-next-byte/disp32 -1368 # registers except esp may be clobbered at this point -1369 # pop args to scan-next-byte -1370 # . . discard first 2 args -1371 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1372 # . . restore ed -1373 59/pop-to-ecx -1374 # check that scan-next-byte aborted -1375 # . check-ints-equal(ed->value, 2, msg) -1376 # . . push args -1377 68/push "F - test-scan-next-byte-aborts-on-invalid-byte"/imm32 -1378 68/push 2/imm32 -1379 # . . push ed->value -1380 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) -1381 # . . call -1382 e8/call check-ints-equal/disp32 -1383 # . . discard args -1384 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1385 $test-scan-next-byte-aborts-on-invalid-byte:end: -1386 # . epilog -1387 # don't restore esp from ebp; manually reclaim locals -1388 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1389 5d/pop-to-ebp -1390 c3/return -1391 -1392 skip-until-newline: # in : (address buffered-file) -> <void> -1393 # pseudocode: -1394 # push eax -1395 # while true -1396 # eax = read-byte-buffered(in) -1397 # if (eax == Eof) break -1398 # if (eax == 0x0a) break -1399 # pop eax -1400 # . prolog -1401 55/push-ebp -1402 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp -1403 # . save registers -1404 50/push-eax -1405 $skip-until-newline:loop: -1406 # . eax = read-byte-buffered(in) -1407 # . . push args -1408 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) -1409 # . . call -1410 e8/call read-byte-buffered/disp32 -1411 # . . discard args -1412 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1413 # . if (eax == Eof) break -1414 3d/compare-eax-and 0xffffffff/imm32/Eof -1415 74/jump-if-equal $skip-until-newline:end/disp8 -1416 # . if (eax != 0xa/newline) loop -1417 3d/compare-eax-and 0xa/imm32/newline -1418 75/jump-if-not-equal $skip-until-newline:loop/disp8 -1419 $skip-until-newline:end: -1420 # . restore registers -1421 58/pop-to-eax -1422 # . epilog -1423 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp -1424 5d/pop-to-ebp -1425 c3/return -1426 -1427 test-skip-until-newline: -1428 # - check that the read pointer points after the newline -1429 # setup -1430 # . clear-stream(_test-stream) -1431 # . . push args -1432 68/push _test-stream/imm32 -1433 # . . call -1434 e8/call clear-stream/disp32 -1435 # . . discard args -1436 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1437 # . clear-stream(_test-buffered-file+4) -1438 # . . push args -1439 b8/copy-to-eax _test-buffered-file/imm32 -1440 05/add-to-eax 4/imm32 -1441 50/push-eax -1442 # . . call -1443 e8/call clear-stream/disp32 -1444 # . . discard args -1445 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1446 # initialize '_test-stream' to "abc\nde" -1447 # . write(_test-stream, "abc") -1448 # . . push args -1449 68/push "abc\n"/imm32 -1450 68/push _test-stream/imm32 -1451 # . . call -1452 e8/call write/disp32 -1453 # . . discard args -1454 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1455 # . write(_test-stream, "de") -1456 # . . push args -1457 68/push "de"/imm32 -1458 68/push _test-stream/imm32 -1459 # . . call -1460 e8/call write/disp32 -1461 # . . discard args -1462 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp -1463 # skip-until-newline(_test-buffered-file) -1464 # . . push args -1465 68/push _test-buffered-file/imm32 -1466 # . . call -1467 e8/call skip-until-newline/disp32 -1468 # . . discard args -1469 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp -1470 # check-ints-equal(_test-buffered-file->read, 4, msg) -1471 # . . push args -1472 68/push "F - test-skip-until-newline"/imm32 -1473 68/push 4/imm32 -1474 b8/copy-to-eax _test-buffered-file/imm32 -1475 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 8/disp8 . # push *(eax+8) -1476 # . . call -1477 e8/call check-ints-equal/disp32 -1478 # . . discard args -1479 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp -1480 # . end -1481 c3/return -1482 -1483 # . . vim:nowrap:textwidth=0 + 544 # if (eax == '\n') continue + 545 3d/compare-eax-and 0xa/imm32/newline + 546 74/jump-if-equal $scan-next-byte:loop/disp8 + 547 $scan-next-byte:check2: + 548 # if (eax == '#') skip-until-newline(in) + 549 3d/compare-with-eax 0x23/imm32 + 550 75/jump-if-not-equal $scan-next-byte:check3/disp8 + 551 # . skip-until-newline(in) + 552 # . . push args + 553 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + 554 # . . call + 555 e8/call skip-until-newline/disp32 + 556 # . . discard args + 557 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 558 eb/jump $scan-next-byte:loop/disp8 + 559 $scan-next-byte:check3: + 560 # otherwise error-byte(ed, err, msg, eax) + 561 # . . push args + 562 50/push-eax + 563 68/push "scan-next-byte: invalid byte"/imm32 + 564 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + 565 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16) + 566 # . . call + 567 e8/call error-byte/disp32 # never returns + 568 $scan-next-byte:end: + 569 # . restore registers + 570 # . epilog + 571 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 572 5d/pop-to-ebp + 573 c3/return + 574 + 575 test-scan-next-byte: + 576 # - check that the first byte of the input is returned + 577 # This test uses exit-descriptors. Use ebp for setting up local variables. + 578 55/push-ebp + 579 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 580 # clear all streams + 581 # . clear-stream(_test-stream) + 582 # . . push args + 583 68/push _test-stream/imm32 + 584 # . . call + 585 e8/call clear-stream/disp32 + 586 # . . discard args + 587 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 588 # . clear-stream(_test-buffered-file+4) + 589 # . . push args + 590 b8/copy-to-eax _test-buffered-file/imm32 + 591 05/add-to-eax 4/imm32 + 592 50/push-eax + 593 # . . call + 594 e8/call clear-stream/disp32 + 595 # . . discard args + 596 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 597 # . clear-stream(_test-error-stream) + 598 # . . push args + 599 68/push _test-error-stream/imm32 + 600 # . . call + 601 e8/call clear-stream/disp32 + 602 # . . discard args + 603 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 604 # . clear-stream(_test-error-buffered-file+4) + 605 # . . push args + 606 b8/copy-to-eax _test-error-buffered-file/imm32 + 607 05/add-to-eax 4/imm32 + 608 50/push-eax + 609 # . . call + 610 e8/call clear-stream/disp32 + 611 # . . discard args + 612 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 613 # initialize '_test-stream' to "abc" + 614 # . write(_test-stream, "abc") + 615 # . . push args + 616 68/push "abc"/imm32 + 617 68/push _test-stream/imm32 + 618 # . . call + 619 e8/call write/disp32 + 620 # . . discard args + 621 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 622 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below + 623 # . var ed/ecx : exit-descriptor + 624 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp + 625 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx + 626 # . tailor-exit-descriptor(ed, 12) + 627 # . . push args + 628 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte + 629 51/push-ecx/ed + 630 # . . call + 631 e8/call tailor-exit-descriptor/disp32 + 632 # . . discard args + 633 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 634 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) + 635 # . . push args + 636 51/push-ecx/ed + 637 68/push _test-error-buffered-file/imm32 + 638 68/push _test-buffered-file/imm32 + 639 # . . call + 640 e8/call scan-next-byte/disp32 + 641 # registers except esp may be clobbered at this point + 642 # pop args to scan-next-byte + 643 # . . discard first 2 args + 644 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 645 # . . restore ed + 646 59/pop-to-ecx + 647 # check that scan-next-byte didn't abort + 648 # . check-ints-equal(ed->value, 0, msg) + 649 # . . push args + 650 68/push "F - test-scan-next-byte: unexpected abort"/imm32 + 651 68/push 0/imm32 + 652 # . . push ed->value + 653 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) + 654 # . . call + 655 e8/call check-ints-equal/disp32 + 656 # . . discard args + 657 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 658 # return if abort + 659 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) + 660 75/jump-if-not-equal $test-scan-next-byte:end/disp8 + 661 # check-ints-equal(eax, 0x61/a, msg) + 662 # . . push args + 663 68/push "F - test-scan-next-byte"/imm32 + 664 68/push 0x61/imm32/a + 665 50/push-eax + 666 # . . call + 667 e8/call check-ints-equal/disp32 + 668 # . . discard args + 669 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 670 $test-scan-next-byte:end: + 671 # . epilog + 672 # don't restore esp from ebp; manually reclaim locals + 673 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 674 5d/pop-to-ebp + 675 c3/return + 676 + 677 test-scan-next-byte-skips-whitespace: + 678 # - check that the first byte after whitespace is returned + 679 # This test uses exit-descriptors. Use ebp for setting up local variables. + 680 55/push-ebp + 681 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 682 # clear all streams + 683 # . clear-stream(_test-stream) + 684 # . . push args + 685 68/push _test-stream/imm32 + 686 # . . call + 687 e8/call clear-stream/disp32 + 688 # . . discard args + 689 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 690 # . clear-stream(_test-buffered-file+4) + 691 # . . push args + 692 b8/copy-to-eax _test-buffered-file/imm32 + 693 05/add-to-eax 4/imm32 + 694 50/push-eax + 695 # . . call + 696 e8/call clear-stream/disp32 + 697 # . . discard args + 698 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 699 # . clear-stream(_test-error-stream) + 700 # . . push args + 701 68/push _test-error-stream/imm32 + 702 # . . call + 703 e8/call clear-stream/disp32 + 704 # . . discard args + 705 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 706 # . clear-stream(_test-error-buffered-file+4) + 707 # . . push args + 708 b8/copy-to-eax _test-error-buffered-file/imm32 + 709 05/add-to-eax 4/imm32 + 710 50/push-eax + 711 # . . call + 712 e8/call clear-stream/disp32 + 713 # . . discard args + 714 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 715 # initialize '_test-stream' to input with leading whitespace + 716 # . write(_test-stream, text) + 717 # . . push args + 718 68/push " abc"/imm32 + 719 68/push _test-stream/imm32 + 720 # . . call + 721 e8/call write/disp32 + 722 # . . discard args + 723 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 724 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below + 725 # . var ed/ecx : exit-descriptor + 726 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp + 727 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx + 728 # . tailor-exit-descriptor(ed, 12) + 729 # . . push args + 730 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte + 731 51/push-ecx/ed + 732 # . . call + 733 e8/call tailor-exit-descriptor/disp32 + 734 # . . discard args + 735 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 736 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) + 737 # . . push args + 738 51/push-ecx/ed + 739 68/push _test-error-buffered-file/imm32 + 740 68/push _test-buffered-file/imm32 + 741 # . . call + 742 e8/call scan-next-byte/disp32 + 743 # registers except esp may be clobbered at this point + 744 # pop args to scan-next-byte + 745 # . . discard first 2 args + 746 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 747 # . . restore ed + 748 59/pop-to-ecx + 749 # check that scan-next-byte didn't abort + 750 # . check-ints-equal(ed->value, 0, msg) + 751 # . . push args + 752 68/push "F - test-scan-next-byte-skips-whitespace: unexpected abort"/imm32 + 753 68/push 0/imm32 + 754 # . . push ed->value + 755 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) + 756 # . . call + 757 e8/call check-ints-equal/disp32 + 758 # . . discard args + 759 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 760 # return if abort + 761 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) + 762 75/jump-if-not-equal $test-scan-next-byte-skips-whitespace:end/disp8 + 763 # check-ints-equal(eax, 0x61/a, msg) + 764 # . . push args + 765 68/push "F - test-scan-next-byte-skips-whitespace"/imm32 + 766 68/push 0x61/imm32/a + 767 50/push-eax + 768 # . . call + 769 e8/call check-ints-equal/disp32 + 770 # . . discard args + 771 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 772 $test-scan-next-byte-skips-whitespace:end: + 773 # . epilog + 774 # don't restore esp from ebp; manually reclaim locals + 775 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 776 5d/pop-to-ebp + 777 c3/return + 778 + 779 test-scan-next-byte-skips-comment: + 780 # - check that the first byte after a comment (and newline) is returned + 781 # This test uses exit-descriptors. Use ebp for setting up local variables. + 782 55/push-ebp + 783 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 784 # clear all streams + 785 # . clear-stream(_test-stream) + 786 # . . push args + 787 68/push _test-stream/imm32 + 788 # . . call + 789 e8/call clear-stream/disp32 + 790 # . . discard args + 791 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 792 # . clear-stream(_test-buffered-file+4) + 793 # . . push args + 794 b8/copy-to-eax _test-buffered-file/imm32 + 795 05/add-to-eax 4/imm32 + 796 50/push-eax + 797 # . . call + 798 e8/call clear-stream/disp32 + 799 # . . discard args + 800 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 801 # . clear-stream(_test-error-stream) + 802 # . . push args + 803 68/push _test-error-stream/imm32 + 804 # . . call + 805 e8/call clear-stream/disp32 + 806 # . . discard args + 807 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 808 # . clear-stream(_test-error-buffered-file+4) + 809 # . . push args + 810 b8/copy-to-eax _test-error-buffered-file/imm32 + 811 05/add-to-eax 4/imm32 + 812 50/push-eax + 813 # . . call + 814 e8/call clear-stream/disp32 + 815 # . . discard args + 816 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 817 # initialize '_test-stream' to input with leading comment + 818 # . write(_test-stream, comment) + 819 # . . push args + 820 68/push "#x\n"/imm32 + 821 68/push _test-stream/imm32 + 822 # . . call + 823 e8/call write/disp32 + 824 # . . discard args + 825 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 826 # . write(_test-stream, real text) + 827 # . . push args + 828 68/push "ab"/imm32 + 829 68/push _test-stream/imm32 + 830 # . . call + 831 e8/call write/disp32 + 832 # . . discard args + 833 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 834 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below + 835 # . var ed/ecx : exit-descriptor + 836 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp + 837 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx + 838 # . tailor-exit-descriptor(ed, 12) + 839 # . . push args + 840 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte + 841 51/push-ecx/ed + 842 # . . call + 843 e8/call tailor-exit-descriptor/disp32 + 844 # . . discard args + 845 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 846 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) + 847 # . . push args + 848 51/push-ecx/ed + 849 68/push _test-error-buffered-file/imm32 + 850 68/push _test-buffered-file/imm32 + 851 # . . call + 852 e8/call scan-next-byte/disp32 + 853 # registers except esp may be clobbered at this point + 854 # pop args to scan-next-byte + 855 # . . discard first 2 args + 856 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 857 # . . restore ed + 858 59/pop-to-ecx + 859 # check that scan-next-byte didn't abort + 860 # . check-ints-equal(ed->value, 0, msg) + 861 # . . push args + 862 68/push "F - test-scan-next-byte-skips-comment: unexpected abort"/imm32 + 863 68/push 0/imm32 + 864 # . . push ed->value + 865 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) + 866 # . . call + 867 e8/call check-ints-equal/disp32 + 868 # . . discard args + 869 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 870 # return if abort + 871 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) + 872 75/jump-if-not-equal $test-scan-next-byte-skips-comment:end/disp8 + 873 # check-ints-equal(eax, 0x61/a, msg) + 874 # . . push args + 875 68/push "F - test-scan-next-byte-skips-comment"/imm32 + 876 68/push 0x61/imm32/a + 877 50/push-eax + 878 # . . call + 879 e8/call check-ints-equal/disp32 + 880 # . . discard args + 881 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 882 $test-scan-next-byte-skips-comment:end: + 883 # . epilog + 884 # don't restore esp from ebp; manually reclaim locals + 885 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 886 5d/pop-to-ebp + 887 c3/return + 888 + 889 test-scan-next-byte-skips-comment-and-whitespace: + 890 # - check that the first byte after a comment and any further whitespace is returned + 891 # This test uses exit-descriptors. Use ebp for setting up local variables. + 892 55/push-ebp + 893 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + 894 # clear all streams + 895 # . clear-stream(_test-stream) + 896 # . . push args + 897 68/push _test-stream/imm32 + 898 # . . call + 899 e8/call clear-stream/disp32 + 900 # . . discard args + 901 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 902 # . clear-stream(_test-buffered-file+4) + 903 # . . push args + 904 b8/copy-to-eax _test-buffered-file/imm32 + 905 05/add-to-eax 4/imm32 + 906 50/push-eax + 907 # . . call + 908 e8/call clear-stream/disp32 + 909 # . . discard args + 910 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 911 # . clear-stream(_test-error-stream) + 912 # . . push args + 913 68/push _test-error-stream/imm32 + 914 # . . call + 915 e8/call clear-stream/disp32 + 916 # . . discard args + 917 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 918 # . clear-stream(_test-error-buffered-file+4) + 919 # . . push args + 920 b8/copy-to-eax _test-error-buffered-file/imm32 + 921 05/add-to-eax 4/imm32 + 922 50/push-eax + 923 # . . call + 924 e8/call clear-stream/disp32 + 925 # . . discard args + 926 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + 927 # initialize '_test-stream' to input with leading comment and more whitespace after newline + 928 # . write(_test-stream, comment) + 929 # . . push args + 930 68/push "#x\n"/imm32 + 931 68/push _test-stream/imm32 + 932 # . . call + 933 e8/call write/disp32 + 934 # . . discard args + 935 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 936 # . write(_test-stream, real text) + 937 # . . push args + 938 68/push " ab"/imm32 + 939 68/push _test-stream/imm32 + 940 # . . call + 941 e8/call write/disp32 + 942 # . . discard args + 943 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 944 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below + 945 # . var ed/ecx : exit-descriptor + 946 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp + 947 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx + 948 # . tailor-exit-descriptor(ed, 12) + 949 # . . push args + 950 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte + 951 51/push-ecx/ed + 952 # . . call + 953 e8/call tailor-exit-descriptor/disp32 + 954 # . . discard args + 955 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 956 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) + 957 # . . push args + 958 51/push-ecx/ed + 959 68/push _test-error-buffered-file/imm32 + 960 68/push _test-buffered-file/imm32 + 961 # . . call + 962 e8/call scan-next-byte/disp32 + 963 # registers except esp may be clobbered at this point + 964 # pop args to scan-next-byte + 965 # . . discard first 2 args + 966 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 967 # . . restore ed + 968 59/pop-to-ecx + 969 # check that scan-next-byte didn't abort + 970 # . check-ints-equal(ed->value, 0, msg) + 971 # . . push args + 972 68/push "F - test-scan-next-byte-skips-comment-and-whitespace: unexpected abort"/imm32 + 973 68/push 0/imm32 + 974 # . . push ed->value + 975 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) + 976 # . . call + 977 e8/call check-ints-equal/disp32 + 978 # . . discard args + 979 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 980 # return if abort + 981 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) + 982 75/jump-if-not-equal $test-scan-next-byte-skips-comment-and-whitespace:end/disp8 + 983 # check-ints-equal(eax, 0x61/a, msg) + 984 # . . push args + 985 68/push "F - test-scan-next-byte-skips-comment-and-whitespace"/imm32 + 986 68/push 0x61/imm32/a + 987 50/push-eax + 988 # . . call + 989 e8/call check-ints-equal/disp32 + 990 # . . discard args + 991 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp + 992 $test-scan-next-byte-skips-comment-and-whitespace:end: + 993 # . epilog + 994 # don't restore esp from ebp; manually reclaim locals + 995 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 996 5d/pop-to-ebp + 997 c3/return + 998 + 999 test-scan-next-byte-skips-whitespace-and-comment: +1000 # - check that the first byte after any whitespace and comments is returned +1001 # This test uses exit-descriptors. Use ebp for setting up local variables. +1002 55/push-ebp +1003 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1004 # clear all streams +1005 # . clear-stream(_test-stream) +1006 # . . push args +1007 68/push _test-stream/imm32 +1008 # . . call +1009 e8/call clear-stream/disp32 +1010 # . . discard args +1011 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1012 # . clear-stream(_test-buffered-file+4) +1013 # . . push args +1014 b8/copy-to-eax _test-buffered-file/imm32 +1015 05/add-to-eax 4/imm32 +1016 50/push-eax +1017 # . . call +1018 e8/call clear-stream/disp32 +1019 # . . discard args +1020 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1021 # . clear-stream(_test-error-stream) +1022 # . . push args +1023 68/push _test-error-stream/imm32 +1024 # . . call +1025 e8/call clear-stream/disp32 +1026 # . . discard args +1027 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1028 # . clear-stream(_test-error-buffered-file+4) +1029 # . . push args +1030 b8/copy-to-eax _test-error-buffered-file/imm32 +1031 05/add-to-eax 4/imm32 +1032 50/push-eax +1033 # . . call +1034 e8/call clear-stream/disp32 +1035 # . . discard args +1036 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1037 # initialize '_test-stream' to input with leading whitespace and comment +1038 # . write(_test-stream, comment) +1039 # . . push args +1040 68/push " #x\n"/imm32 +1041 68/push _test-stream/imm32 +1042 # . . call +1043 e8/call write/disp32 +1044 # . . discard args +1045 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1046 # . write(_test-stream, real text) +1047 # . . push args +1048 68/push "ab"/imm32 +1049 68/push _test-stream/imm32 +1050 # . . call +1051 e8/call write/disp32 +1052 # . . discard args +1053 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1054 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below +1055 # . var ed/ecx : exit-descriptor +1056 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp +1057 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1058 # . tailor-exit-descriptor(ed, 12) +1059 # . . push args +1060 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte +1061 51/push-ecx/ed +1062 # . . call +1063 e8/call tailor-exit-descriptor/disp32 +1064 # . . discard args +1065 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1066 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) +1067 # . . push args +1068 51/push-ecx/ed +1069 68/push _test-error-buffered-file/imm32 +1070 68/push _test-buffered-file/imm32 +1071 # . . call +1072 e8/call scan-next-byte/disp32 +1073 # registers except esp may be clobbered at this point +1074 # pop args to scan-next-byte +1075 # . . discard first 2 args +1076 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1077 # . . restore ed +1078 59/pop-to-ecx +1079 # check that scan-next-byte didn't abort +1080 # . check-ints-equal(ed->value, 0, msg) +1081 # . . push args +1082 68/push "F - test-scan-next-byte-skips-whitespace-and-comment: unexpected abort"/imm32 +1083 68/push 0/imm32 +1084 # . . push ed->value +1085 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) +1086 # . . call +1087 e8/call check-ints-equal/disp32 +1088 # . . discard args +1089 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1090 # return if abort +1091 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) +1092 75/jump-if-not-equal $test-scan-next-byte-skips-whitespace-and-comment:end/disp8 +1093 # check-ints-equal(eax, 0x61/a, msg) +1094 # . . push args +1095 68/push "F - test-scan-next-byte-skips-whitespace-and-comment"/imm32 +1096 68/push 0x61/imm32/a +1097 50/push-eax +1098 # . . call +1099 e8/call check-ints-equal/disp32 +1100 # . . discard args +1101 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1102 $test-scan-next-byte-skips-whitespace-and-comment:end: +1103 # . epilog +1104 # don't restore esp from ebp; manually reclaim locals +1105 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1106 5d/pop-to-ebp +1107 c3/return +1108 +1109 test-scan-next-byte-reads-final-byte: +1110 # - check that the final byte in input is returned +1111 # This test uses exit-descriptors. Use ebp for setting up local variables. +1112 55/push-ebp +1113 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1114 # clear all streams +1115 # . clear-stream(_test-stream) +1116 # . . push args +1117 68/push _test-stream/imm32 +1118 # . . call +1119 e8/call clear-stream/disp32 +1120 # . . discard args +1121 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1122 # . clear-stream(_test-buffered-file+4) +1123 # . . push args +1124 b8/copy-to-eax _test-buffered-file/imm32 +1125 05/add-to-eax 4/imm32 +1126 50/push-eax +1127 # . . call +1128 e8/call clear-stream/disp32 +1129 # . . discard args +1130 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1131 # . clear-stream(_test-error-stream) +1132 # . . push args +1133 68/push _test-error-stream/imm32 +1134 # . . call +1135 e8/call clear-stream/disp32 +1136 # . . discard args +1137 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1138 # . clear-stream(_test-error-buffered-file+4) +1139 # . . push args +1140 b8/copy-to-eax _test-error-buffered-file/imm32 +1141 05/add-to-eax 4/imm32 +1142 50/push-eax +1143 # . . call +1144 e8/call clear-stream/disp32 +1145 # . . discard args +1146 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1147 # initialize '_test-stream' to input with single character +1148 # . write(_test-stream, character) +1149 # . . push args +1150 68/push "a"/imm32 +1151 68/push _test-stream/imm32 +1152 # . . call +1153 e8/call write/disp32 +1154 # . . discard args +1155 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1156 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below +1157 # . var ed/ecx : exit-descriptor +1158 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp +1159 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1160 # . tailor-exit-descriptor(ed, 12) +1161 # . . push args +1162 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte +1163 51/push-ecx/ed +1164 # . . call +1165 e8/call tailor-exit-descriptor/disp32 +1166 # . . discard args +1167 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1168 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) +1169 # . . push args +1170 51/push-ecx/ed +1171 68/push _test-error-buffered-file/imm32 +1172 68/push _test-buffered-file/imm32 +1173 # . . call +1174 e8/call scan-next-byte/disp32 +1175 # registers except esp may be clobbered at this point +1176 # pop args to scan-next-byte +1177 # . . discard first 2 args +1178 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1179 # . . restore ed +1180 59/pop-to-ecx +1181 # check that scan-next-byte didn't abort +1182 # . check-ints-equal(ed->value, 0, msg) +1183 # . . push args +1184 68/push "F - test-scan-next-byte-reads-final-byte: unexpected abort"/imm32 +1185 68/push 0/imm32 +1186 # . . push ed->value +1187 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) +1188 # . . call +1189 e8/call check-ints-equal/disp32 +1190 # . . discard args +1191 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1192 # return if abort +1193 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) +1194 75/jump-if-not-equal $test-scan-next-byte-reads-final-byte:end/disp8 +1195 # check-ints-equal(eax, 0x61/a, msg) +1196 # . . push args +1197 68/push "F - test-scan-next-byte-reads-final-byte"/imm32 +1198 68/push 0x61/imm32/a +1199 50/push-eax +1200 # . . call +1201 e8/call check-ints-equal/disp32 +1202 # . . discard args +1203 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1204 $test-scan-next-byte-reads-final-byte:end: +1205 # . epilog +1206 # don't restore esp from ebp; manually reclaim locals +1207 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1208 5d/pop-to-ebp +1209 c3/return +1210 +1211 test-scan-next-byte-handles-Eof: +1212 # - check that the right sentinel value is returned when there's no data remaining to be read +1213 # This test uses exit-descriptors. Use ebp for setting up local variables. +1214 55/push-ebp +1215 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1216 # clear all streams +1217 # . clear-stream(_test-stream) +1218 # . . push args +1219 68/push _test-stream/imm32 +1220 # . . call +1221 e8/call clear-stream/disp32 +1222 # . . discard args +1223 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1224 # . clear-stream(_test-buffered-file+4) +1225 # . . push args +1226 b8/copy-to-eax _test-buffered-file/imm32 +1227 05/add-to-eax 4/imm32 +1228 50/push-eax +1229 # . . call +1230 e8/call clear-stream/disp32 +1231 # . . discard args +1232 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1233 # . clear-stream(_test-error-stream) +1234 # . . push args +1235 68/push _test-error-stream/imm32 +1236 # . . call +1237 e8/call clear-stream/disp32 +1238 # . . discard args +1239 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1240 # . clear-stream(_test-error-buffered-file+4) +1241 # . . push args +1242 b8/copy-to-eax _test-error-buffered-file/imm32 +1243 05/add-to-eax 4/imm32 +1244 50/push-eax +1245 # . . call +1246 e8/call clear-stream/disp32 +1247 # . . discard args +1248 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1249 # leave '_test-stream' empty +1250 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below +1251 # . var ed/ecx : exit-descriptor +1252 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp +1253 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1254 # . tailor-exit-descriptor(ed, 12) +1255 # . . push args +1256 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte +1257 51/push-ecx/ed +1258 # . . call +1259 e8/call tailor-exit-descriptor/disp32 +1260 # . . discard args +1261 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1262 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) +1263 # . . push args +1264 51/push-ecx/ed +1265 68/push _test-error-buffered-file/imm32 +1266 68/push _test-buffered-file/imm32 +1267 # . . call +1268 e8/call scan-next-byte/disp32 +1269 # registers except esp may be clobbered at this point +1270 # pop args to scan-next-byte +1271 # . . discard first 2 args +1272 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1273 # . . restore ed +1274 59/pop-to-ecx +1275 # check that scan-next-byte didn't abort +1276 # . check-ints-equal(ed->value, 0, msg) +1277 # . . push args +1278 68/push "F - test-scan-next-byte-handles-Eof: unexpected abort"/imm32 +1279 68/push 0/imm32 +1280 # . . push ed->value +1281 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) +1282 # . . call +1283 e8/call check-ints-equal/disp32 +1284 # . . discard args +1285 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1286 # return if abort +1287 81 7/subop/compare 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 0/imm32 # compare *(ecx+4) +1288 75/jump-if-not-equal $test-scan-next-byte-handles-Eof:end/disp8 +1289 # check-ints-equal(eax, Eof, msg) +1290 # . . push args +1291 68/push "F - test-scan-next-byte-handles-Eof"/imm32 +1292 68/push 0xffffffff/imm32/Eof +1293 50/push-eax +1294 # . . call +1295 e8/call check-ints-equal/disp32 +1296 # . . discard args +1297 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1298 $test-scan-next-byte-handles-Eof:end: +1299 # . epilog +1300 # don't restore esp from ebp; manually reclaim locals +1301 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1302 5d/pop-to-ebp +1303 c3/return +1304 +1305 test-scan-next-byte-aborts-on-invalid-byte: +1306 # - check that the a bad byte immediately aborts +1307 # This test uses exit-descriptors. Use ebp for setting up local variables. +1308 55/push-ebp +1309 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1310 # clear all streams +1311 # . clear-stream(_test-stream) +1312 # . . push args +1313 68/push _test-stream/imm32 +1314 # . . call +1315 e8/call clear-stream/disp32 +1316 # . . discard args +1317 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1318 # . clear-stream(_test-buffered-file+4) +1319 # . . push args +1320 b8/copy-to-eax _test-buffered-file/imm32 +1321 05/add-to-eax 4/imm32 +1322 50/push-eax +1323 # . . call +1324 e8/call clear-stream/disp32 +1325 # . . discard args +1326 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1327 # . clear-stream(_test-error-stream) +1328 # . . push args +1329 68/push _test-error-stream/imm32 +1330 # . . call +1331 e8/call clear-stream/disp32 +1332 # . . discard args +1333 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1334 # . clear-stream(_test-error-buffered-file+4) +1335 # . . push args +1336 b8/copy-to-eax _test-error-buffered-file/imm32 +1337 05/add-to-eax 4/imm32 +1338 50/push-eax +1339 # . . call +1340 e8/call clear-stream/disp32 +1341 # . . discard args +1342 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1343 # initialize '_test-stream' to "x" +1344 # . write(_test-stream, "x") +1345 # . . push args +1346 68/push "x"/imm32 +1347 68/push _test-stream/imm32 +1348 # . . call +1349 e8/call write/disp32 +1350 # . . discard args +1351 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1352 # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below +1353 # . var ed/ecx : exit-descriptor +1354 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp +1355 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx +1356 # . tailor-exit-descriptor(ed, 12) +1357 # . . push args +1358 68/push 0xc/imm32/nbytes-of-args-for-scan-next-byte +1359 51/push-ecx/ed +1360 # . . call +1361 e8/call tailor-exit-descriptor/disp32 +1362 # . . discard args +1363 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1364 # eax = scan-next-byte(_test-buffered-file, _test-error-buffered-file, ed) +1365 # . . push args +1366 51/push-ecx/ed +1367 68/push _test-error-buffered-file/imm32 +1368 68/push _test-buffered-file/imm32 +1369 # . . call +1370 e8/call scan-next-byte/disp32 +1371 # registers except esp may be clobbered at this point +1372 # pop args to scan-next-byte +1373 # . . discard first 2 args +1374 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1375 # . . restore ed +1376 59/pop-to-ecx +1377 # check that scan-next-byte aborted +1378 # . check-ints-equal(ed->value, 2, msg) +1379 # . . push args +1380 68/push "F - test-scan-next-byte-aborts-on-invalid-byte"/imm32 +1381 68/push 2/imm32 +1382 # . . push ed->value +1383 ff 6/subop/push 1/mod/*+disp8 1/rm32/ecx . . . . 4/disp8 . # push *(ecx+4) +1384 # . . call +1385 e8/call check-ints-equal/disp32 +1386 # . . discard args +1387 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1388 $test-scan-next-byte-aborts-on-invalid-byte:end: +1389 # . epilog +1390 # don't restore esp from ebp; manually reclaim locals +1391 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1392 5d/pop-to-ebp +1393 c3/return +1394 +1395 skip-until-newline: # in : (address buffered-file) -> <void> +1396 # pseudocode: +1397 # push eax +1398 # while true +1399 # eax = read-byte-buffered(in) +1400 # if (eax == Eof) break +1401 # if (eax == 0x0a) break +1402 # pop eax +1403 # . prolog +1404 55/push-ebp +1405 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp +1406 # . save registers +1407 50/push-eax +1408 $skip-until-newline:loop: +1409 # . eax = read-byte-buffered(in) +1410 # . . push args +1411 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) +1412 # . . call +1413 e8/call read-byte-buffered/disp32 +1414 # . . discard args +1415 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1416 # . if (eax == Eof) break +1417 3d/compare-eax-and 0xffffffff/imm32/Eof +1418 74/jump-if-equal $skip-until-newline:end/disp8 +1419 # . if (eax != 0xa/newline) loop +1420 3d/compare-eax-and 0xa/imm32/newline +1421 75/jump-if-not-equal $skip-until-newline:loop/disp8 +1422 $skip-until-newline:end: +1423 # . restore registers +1424 58/pop-to-eax +1425 # . epilog +1426 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp +1427 5d/pop-to-ebp +1428 c3/return +1429 +1430 test-skip-until-newline: +1431 # - check that the read pointer points after the newline +1432 # setup +1433 # . clear-stream(_test-stream) +1434 # . . push args +1435 68/push _test-stream/imm32 +1436 # . . call +1437 e8/call clear-stream/disp32 +1438 # . . discard args +1439 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1440 # . clear-stream(_test-buffered-file+4) +1441 # . . push args +1442 b8/copy-to-eax _test-buffered-file/imm32 +1443 05/add-to-eax 4/imm32 +1444 50/push-eax +1445 # . . call +1446 e8/call clear-stream/disp32 +1447 # . . discard args +1448 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1449 # initialize '_test-stream' to "abc\nde" +1450 # . write(_test-stream, "abc") +1451 # . . push args +1452 68/push "abc\n"/imm32 +1453 68/push _test-stream/imm32 +1454 # . . call +1455 e8/call write/disp32 +1456 # . . discard args +1457 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1458 # . write(_test-stream, "de") +1459 # . . push args +1460 68/push "de"/imm32 +1461 68/push _test-stream/imm32 +1462 # . . call +1463 e8/call write/disp32 +1464 # . . discard args +1465 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +1466 # skip-until-newline(_test-buffered-file) +1467 # . . push args +1468 68/push _test-buffered-file/imm32 +1469 # . . call +1470 e8/call skip-until-newline/disp32 +1471 # . . discard args +1472 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp +1473 # check-ints-equal(_test-buffered-file->read, 4, msg) +1474 # . . push args +1475 68/push "F - test-skip-until-newline"/imm32 +1476 68/push 4/imm32 +1477 b8/copy-to-eax _test-buffered-file/imm32 +1478 ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 8/disp8 . # push *(eax+8) +1479 # . . call +1480 e8/call check-ints-equal/disp32 +1481 # . . discard args +1482 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp +1483 # . end +1484 c3/return +1485 +1486 # . . vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0