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