From 257ca35ab4aa706fe45062324d2ec7327236827b Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Thu, 6 Dec 2018 00:16:01 -0800 Subject: 4845 Making progress on hex1 (http://web.archive.org/web/20061108010907/http://www.rano.org/bcompiler.html) --- html/subx/apps/hex.subx.html | 892 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 892 insertions(+) create mode 100644 html/subx/apps/hex.subx.html (limited to 'html/subx/apps/hex.subx.html') diff --git a/html/subx/apps/hex.subx.html b/html/subx/apps/hex.subx.html new file mode 100644 index 00000000..ddfefd90 --- /dev/null +++ b/html/subx/apps/hex.subx.html @@ -0,0 +1,892 @@ + + + + +Mu - subx/apps/hex.subx + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/subx/apps/hex.subx +
+  1 # Read a text file containing whitespace-separated ascii hex bytes from stdin,
+  2 # and convert them into a binary file.
+  3 #
+  4 # To run (from the subx/ directory):
+  5 #   $ ./subx translate *.subx apps/hex.subx -o apps/hex
+  6 #   $ echo '80 81 82  # comment'  |./subx run apps/hex  |xxd -
+  7 # Expected output:
+  8 #   09000000: 8081 82
+  9 #
+ 10 # Only hex bytes and comments are permitted. Outside of comments all words
+ 11 # must be exactly 2 characters long and contain only characters [0-9a-f]. No
+ 12 # uppercase hex.
+ 13 
+ 14 == code
+ 15 #   instruction                     effective address                                                   register    displacement    immediate
+ 16 # . op          subop               mod             rm32          base        index         scale       r32
+ 17 # . 1-3 bytes   3 bits              2 bits          3 bits        3 bits      3 bits        2 bits      2 bits      0/1/2/4 bytes   0/1/2/4 bytes
+ 18 
+ 19     # for debugging: run a single test
+ 20 #?     e8/call test-skip-until-newline/disp32
+ 21 #?     8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
+ 22 #?     eb/jump  $main:end/disp8
+ 23 
+ 24 # main: run tests if necessary, convert stdin if not
+ 25     # . prolog
+ 26     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+ 27     # - if argc > 1 and argv[1] == "test" then return run_tests()
+ 28     # . argc > 1
+ 29     81          7/subop/compare     1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0/disp8         1/imm32           # compare *EBP
+ 30     7e/jump-if-lesser-or-equal  $run-main/disp8
+ 31     # . argv[1] == "test"
+ 32     # . . push args
+ 33     68/push  "test"/imm32
+ 34     ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0x8/disp8       .                 # push *(EBP+8)
+ 35     # . . call
+ 36     e8/call  kernel-string-equal/disp32
+ 37     # . . discard args
+ 38     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+ 39     # . check result
+ 40     3d/compare-EAX  1/imm32
+ 41     75/jump-if-not-equal  $run-main/disp8
+ 42     # . run-tests()
+ 43 #?     e8/call test-hex-below-0/disp32
+ 44 #?     e8/call test-scan-next-byte/disp32
+ 45 #?     e8/call test-scan-next-byte-skips-comment/disp32
+ 46     e8/call  run-tests/disp32
+ 47     8b/copy                         0/mod/indirect  5/rm32/.disp32            .             .           3/r32/EBX   Num-test-failures/disp32          # copy *Num-test-failures to EBX
+ 48     eb/jump  $main:end/disp8
+ 49 $run-main:
+ 50     # - otherwise convert stdin
+ 51     # var ed/EAX : exit-descriptor
+ 52     81          5/subop/subtract    3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # subtract from ESP
+ 53     8d/copy-address                 0/mod/indirect  4/rm32/sib    4/base/ESP  4/index/none  .           0/r32/EAX   .               .                 # copy ESP to EAX
+ 54     # configure ed to really exit()
+ 55     # . ed->target = 0
+ 56     c7/copy                         0/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # copy to *EAX
+ 57     # return convert(Stdin, 1/stdout, 2/stderr, ed)
+ 58     # . . push args
+ 59     50/push-EAX/ed
+ 60     68/push  2/imm32/stderr
+ 61     68/push  1/imm32/stdout
+ 62     68/push  Stdin/imm32
+ 63     # . . call
+ 64     e8/call  convert/disp32
+ 65     # . . discard args
+ 66     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0x10/imm32        # add to ESP
+ 67     # . syscall(exit, 0)
+ 68     bb/copy-to-EBX  0/imm32
+ 69 $main:end:
+ 70     b8/copy-to-EAX  1/imm32/exit
+ 71     cd/syscall  0x80/imm8
+ 72 
+ 73 # the main entry point
+ 74 convert:  # in : (address buffered-file), out : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> <void>
+ 75     # pseudocode:
+ 76     #   repeatedly
+ 77     #     EAX = convert-next-hex-byte(in, err, ed)
+ 78     #     if EAX == 0xffffffff break  # eof
+ 79     #     write-byte(out, EAX)
+ 80     #   flush(out)
+ 81     #
+ 82     # . prolog
+ 83     55/push-EBP
+ 84     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+ 85     # . save registers
+ 86     # var buf/ECX : (address stream) on the stack
+ 87     # It occupies 1KB.
+ 88     81          5/subop/subtract    3/mod/direct    4/rm32/ESP    .           .             .           .           .               0x400/imm32       # subtract from ESP
+ 89     8d/copy-address                 0/mod/indirect  4/rm32/sib    4/base/ESP  4/index/none  .           1/r32/ECX   .               .                 # copy ESP to ECX
+ 90     # initialize the stream
+ 91     # . length = 1KB - 12 bytes for 'read', 'write' and 'length' fields.
+ 92     c7/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           .           8/disp8         0x3f4/imm32       # copy to *(ECX+8)
+ 93     # . clear-stream(buf)
+ 94     # . . push args
+ 95     51/push-ECX
+ 96     # . . call
+ 97     e8/call  clear-stream/disp32
+ 98     # . . discard args
+ 99     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+100 $convert:loop:
+101     # . restore registers
+102     # . epilog
+103     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+104     5d/pop-to-EBP
+105     c3/return
+106 
+107 # read bytes from 'in' until a sequence of two lowercase hex characters (0-9, a-f)
+108 # skip spaces and newlines
+109 # on '#' skip bytes until newline
+110 # raise an error and abort on all other unexpected bytes
+111 # return the binary value of the two hex characters in EAX
+112 # return 0xffffffff on end of file
+113 convert-next-hex-byte:  # in : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> byte-or-eof/EAX
+114     # pseudocode:
+115     #   EAX = scan-next-byte(in, err, ed)
+116     #   if (EAX == 0xffffffff) return
+117     #   ECX = EAX
+118     #   EAX = scan-next-byte(in, err, ed)
+119     #   if (EAX == 0xffffffff) error("partial byte found")
+120     #   ECX = (ECX << 8) | EAX
+121     #   return
+122     #
+123     # . prolog
+124     55/push-EBP
+125     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+126     # . save registers
+127     # var buf/ECX : (address stream) on the stack
+128     # It occupies 1KB.
+129     81          5/subop/subtract    3/mod/direct    4/rm32/ESP    .           .             .           .           .               0x400/imm32       # subtract from ESP
+130     8d/copy-address                 0/mod/indirect  4/rm32/sib    4/base/ESP  4/index/none  .           1/r32/ECX   .               .                 # copy ESP to ECX
+131     # initialize the stream
+132     # . length = 1KB - 12 bytes for 'read', 'write' and 'length' fields.
+133     c7/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           .           8/disp8         0x3f4/imm32       # copy to *(ECX+8)
+134     # . clear-stream(buf)
+135     # . . push args
+136     51/push-ECX
+137     # . . call
+138     e8/call  clear-stream/disp32
+139     # . . discard args
+140     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+141 $convert:loop:
+142     # . restore registers
+143     # . epilog
+144     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+145     5d/pop-to-EBP
+146     c3/return
+147 
+148 # read whitespace until a hex byte, and return it
+149 # return 0xffffffff if file ends without finding a hex byte
+150 # on '#' skip all bytes until newline
+151 # abort on any other byte
+152 scan-next-byte:  # in : (address buffered-file), err : (address buffered-file), ed : (address exit-descriptor) -> byte-or-eof/EAX
+153     # pseudocode:
+154     #   repeatedly
+155     #     EAX = read-byte(in)
+156     #     if is-hex-lowercase-byte?(EAX) return EAX
+157     #     if EAX == 0x20 continue
+158     #     if EAX == '#' skip-until-newline(in)
+159     #     else error-byte(ed, err, "unexpected byte: " EAX)
+160     #   return 0xffffffff
+161     #
+162     # . prolog
+163     55/push-EBP
+164     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+165     # . save registers
+166 $scan-next-byte:loop:
+167     # EAX = read-byte(in)
+168     # . . push args
+169     ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0x8/disp8       .                 # push *(EBP+8)
+170     # . . call
+171     e8/call  read-byte/disp32
+172     # . . discard args
+173     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+174     # if is-hex-lowercase-byte?(EAX) return EAX
+175     # . save EAX for now
+176     50/push-EAX
+177     # . is-hex-lowercase-byte?(EAX)
+178     # . . push args
+179     50/push-EAX
+180     # . . call
+181     e8/call  is-hex-lowercase-byte?/disp32
+182     # . . discard args
+183     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+184     # . compare with 'false'
+185     81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0/imm32           # compare EAX
+186     # . restore EAX (does not affect flags)
+187     58/pop-to-EAX
+188     # . check whether to return
+189     75/jump-if-not-equal  $scan-next-byte:end/disp8
+190 $scan-next-byte:check1:
+191     # if EAX == ' ' continue
+192     81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0x20/imm32        # compare EAX
+193     74/jump-if-equal  $scan-next-byte:loop/disp8
+194 $aa:
+195     # if EAX == '\t' continue
+196     81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0x9/imm32         # compare EAX
+197     74/jump-if-equal  $scan-next-byte:loop/disp8
+198 $bb:
+199     # if EAX == '\n' continue
+200     81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0xa/imm32         # compare EAX
+201     74/jump-if-equal  $scan-next-byte:loop/disp8
+202 $scan-next-byte:check2:
+203     # if EAX == '#' skip-until-newline(in)
+204     3d/compare-with-EAX  0x23/imm32
+205     75/jump-if-not-equal  $scan-next-byte:check3/disp8
+206 $cc:
+207     # . skip-until-newline(in)
+208     # . . push args
+209     ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0x8/disp8       .                 # push *(EBP+8)
+210     # . . call
+211     e8/call  skip-until-newline/disp32
+212     # . . discard args
+213     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+214     eb/jump  $scan-next-byte:loop/disp8
+215 $scan-next-byte:check3:
+216 # TODO: error-byte takes a buffered-file, not a (fd or (address stream))
+217     # otherwise error-byte(ed, err, msg, EAX)
+218     # . . push args
+219     50/push-EAX
+220     68/push  "scan-next-byte: invalid byte"/imm32
+221     ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0xc/disp8       .                 # push *(EBP+12)
+222     ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0x10/disp8      .                 # push *(EBP+16)
+223     # . . call
+224     e8/call  error-byte/disp32  # never returns
+225 $scan-next-byte:end:
+226     # . restore registers
+227     # . epilog
+228     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+229     5d/pop-to-EBP
+230     c3/return
+231 
+232 test-scan-next-byte:
+233     # - check that the first two bytes of the input are assembled into the resulting number
+234     # setup
+235     # . clear-stream(_test-stream)
+236     # . . push args
+237     68/push  _test-stream/imm32
+238     # . . call
+239     e8/call  clear-stream/disp32
+240     # . . discard args
+241     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+242     # . clear-stream(_test-buffered-file+4)
+243     # . . push args
+244     b8/copy-to-EAX  _test-buffered-file/imm32
+245     05/add-to-EAX  4/imm32
+246     50/push-EAX
+247     # . . call
+248     e8/call  clear-stream/disp32
+249     # . . discard args
+250     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+251     # initialize '_test-stream' to "abc"
+252     # . write(_test-stream, "abc")
+253     # . . push args
+254     68/push  "abc"/imm32
+255     68/push  _test-stream/imm32
+256     # . . call
+257     e8/call  write/disp32
+258     # . . discard args
+259     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+260     # scan-next-byte(_test-buffered-file)
+261     # . . push args
+262     68/push  _test-buffered-file/imm32
+263     # . . call
+264     e8/call  scan-next-byte/disp32
+265     # . . discard args
+266     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+267     # check-ints-equal(EAX, 0x61/a, msg)
+268     # . . push args
+269     68/push  "F - test-scan-next-byte"/imm32
+270     68/push  0x61/imm32/a
+271     50/push-EAX
+272     # . . call
+273     e8/call  check-ints-equal/disp32
+274     # . . discard args
+275     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+276     # . end
+277     c3/return
+278 
+279 test-scan-next-byte-skips-whitespace:
+280     # - check that the first two bytes of the input are assembled into the resulting number
+281     # setup
+282     # . clear-stream(_test-stream)
+283     # . . push args
+284     68/push  _test-stream/imm32
+285     # . . call
+286     e8/call  clear-stream/disp32
+287     # . . discard args
+288     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+289     # . clear-stream(_test-buffered-file+4)
+290     # . . push args
+291     b8/copy-to-EAX  _test-buffered-file/imm32
+292     05/add-to-EAX  4/imm32
+293     50/push-EAX
+294     # . . call
+295     e8/call  clear-stream/disp32
+296     # . . discard args
+297     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+298     # initialize '_test-stream' to input with leading whitespace
+299     # . write(_test-stream, text)
+300     # . . push args
+301     68/push  "  abc"/imm32
+302     68/push  _test-stream/imm32
+303     # . . call
+304     e8/call  write/disp32
+305     # . . discard args
+306     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+307     # scan-next-byte(_test-buffered-file)
+308     # . . push args
+309     68/push  _test-buffered-file/imm32
+310     # . . call
+311     e8/call  scan-next-byte/disp32
+312     # . . discard args
+313     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+314     # check-ints-equal(EAX, 0x61/a, msg)
+315     # . . push args
+316     68/push  "F - test-scan-next-byte-skips-whitespace"/imm32
+317     68/push  0x61/imm32/a
+318     50/push-EAX
+319     # . . call
+320     e8/call  check-ints-equal/disp32
+321     # . . discard args
+322     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+323     # . end
+324     c3/return
+325 
+326 test-scan-next-byte-skips-comment:
+327     # - check that the first two bytes of the input are assembled into the resulting number
+328     # setup
+329     # . clear-stream(_test-stream)
+330     # . . push args
+331     68/push  _test-stream/imm32
+332     # . . call
+333     e8/call  clear-stream/disp32
+334     # . . discard args
+335     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+336     # . clear-stream(_test-buffered-file+4)
+337     # . . push args
+338     b8/copy-to-EAX  _test-buffered-file/imm32
+339     05/add-to-EAX  4/imm32
+340     50/push-EAX
+341     # . . call
+342     e8/call  clear-stream/disp32
+343     # . . discard args
+344     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+345     # initialize '_test-stream' to input with leading comment
+346     # . write(_test-stream, comment)
+347     # . . push args
+348     68/push  "#x"/imm32
+349     68/push  _test-stream/imm32
+350     # . . call
+351     e8/call  write/disp32
+352     # . . discard args
+353     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+354     # . write(_test-stream, Newline)
+355     # . . push args
+356     68/push  Newline/imm32
+357     68/push  _test-stream/imm32
+358     # . . call
+359     e8/call  write/disp32
+360     # . . discard args
+361     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+362     # . write(_test-stream, real text)
+363     # . . push args
+364     68/push  "ab"/imm32
+365     68/push  _test-stream/imm32
+366     # . . call
+367     e8/call  write/disp32
+368     # . . discard args
+369     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+370     # scan-next-byte(_test-buffered-file)
+371     # . . push args
+372     68/push  _test-buffered-file/imm32
+373     # . . call
+374     e8/call  scan-next-byte/disp32
+375     # . . discard args
+376     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+377     # check-ints-equal(EAX, 0x61/a, msg)
+378     # . . push args
+379     68/push  "F - test-scan-next-byte-skips-comment"/imm32
+380     68/push  0x61/imm32/a
+381     50/push-EAX
+382     # . . call
+383     e8/call  check-ints-equal/disp32
+384     # . . discard args
+385     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+386     # . end
+387     c3/return
+388 
+389 test-scan-next-byte-skips-comment-and-whitespace:
+390     # - check that the first two bytes of the input are assembled into the resulting number
+391     # setup
+392     # . clear-stream(_test-stream)
+393     # . . push args
+394     68/push  _test-stream/imm32
+395     # . . call
+396     e8/call  clear-stream/disp32
+397     # . . discard args
+398     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+399     # . clear-stream(_test-buffered-file+4)
+400     # . . push args
+401     b8/copy-to-EAX  _test-buffered-file/imm32
+402     05/add-to-EAX  4/imm32
+403     50/push-EAX
+404     # . . call
+405     e8/call  clear-stream/disp32
+406     # . . discard args
+407     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+408     # initialize '_test-stream' to input with leading comment and more whitespace after newline
+409     # . write(_test-stream, comment)
+410     # . . push args
+411     68/push  "#x"/imm32
+412     68/push  _test-stream/imm32
+413     # . . call
+414     e8/call  write/disp32
+415     # . . discard args
+416     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+417     # . write(_test-stream, Newline)
+418     # . . push args
+419     68/push  Newline/imm32
+420     68/push  _test-stream/imm32
+421     # . . call
+422     e8/call  write/disp32
+423     # . . discard args
+424     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+425     # . write(_test-stream, real text)
+426     # . . push args
+427     68/push  " ab"/imm32
+428     68/push  _test-stream/imm32
+429     # . . call
+430     e8/call  write/disp32
+431     # . . discard args
+432     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+433     # scan-next-byte(_test-buffered-file)
+434     # . . push args
+435     68/push  _test-buffered-file/imm32
+436     # . . call
+437     e8/call  scan-next-byte/disp32
+438     # . . discard args
+439     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+440     # check-ints-equal(EAX, 0x61/a, msg)
+441     # . . push args
+442     68/push  "F - test-scan-next-byte-skips-comment"/imm32
+443     68/push  0x61/imm32/a
+444     50/push-EAX
+445     # . . call
+446     e8/call  check-ints-equal/disp32
+447     # . . discard args
+448     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+449     # . end
+450     c3/return
+451 
+452 test-scan-next-byte-skips-whitespace-and-comment:
+453     # - check that the first two bytes of the input are assembled into the resulting number
+454     # setup
+455     # . clear-stream(_test-stream)
+456     # . . push args
+457     68/push  _test-stream/imm32
+458     # . . call
+459     e8/call  clear-stream/disp32
+460     # . . discard args
+461     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+462     # . clear-stream(_test-buffered-file+4)
+463     # . . push args
+464     b8/copy-to-EAX  _test-buffered-file/imm32
+465     05/add-to-EAX  4/imm32
+466     50/push-EAX
+467     # . . call
+468     e8/call  clear-stream/disp32
+469     # . . discard args
+470     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+471     # initialize '_test-stream' to input with leading whitespace and comment
+472     # . write(_test-stream, comment)
+473     # . . push args
+474     68/push  " #x"/imm32
+475     68/push  _test-stream/imm32
+476     # . . call
+477     e8/call  write/disp32
+478     # . . discard args
+479     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+480     # . write(_test-stream, Newline)
+481     # . . push args
+482     68/push  Newline/imm32
+483     68/push  _test-stream/imm32
+484     # . . call
+485     e8/call  write/disp32
+486     # . . discard args
+487     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+488     # . write(_test-stream, real text)
+489     # . . push args
+490     68/push  "ab"/imm32
+491     68/push  _test-stream/imm32
+492     # . . call
+493     e8/call  write/disp32
+494     # . . discard args
+495     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+496     # scan-next-byte(_test-buffered-file)
+497     # . . push args
+498     68/push  _test-buffered-file/imm32
+499     # . . call
+500     e8/call  scan-next-byte/disp32
+501     # . . discard args
+502     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+503     # check-ints-equal(EAX, 0x61/a, msg)
+504     # . . push args
+505     68/push  "F - test-scan-next-byte-skips-comment"/imm32
+506     68/push  0x61/imm32/a
+507     50/push-EAX
+508     # . . call
+509     e8/call  check-ints-equal/disp32
+510     # . . discard args
+511     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+512     # . end
+513     c3/return
+514 
+515 test-scan-next-byte-reads-final-byte:
+516     # - check that the first two bytes of the input are assembled into the resulting number
+517     # setup
+518     # . clear-stream(_test-stream)
+519     # . . push args
+520     68/push  _test-stream/imm32
+521     # . . call
+522     e8/call  clear-stream/disp32
+523     # . . discard args
+524     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+525     # . clear-stream(_test-buffered-file+4)
+526     # . . push args
+527     b8/copy-to-EAX  _test-buffered-file/imm32
+528     05/add-to-EAX  4/imm32
+529     50/push-EAX
+530     # . . call
+531     e8/call  clear-stream/disp32
+532     # . . discard args
+533     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+534     # initialize '_test-stream' to input with single character
+535     # . write(_test-stream, character)
+536     # . . push args
+537     68/push  "a"/imm32
+538     68/push  _test-stream/imm32
+539     # . . call
+540     e8/call  write/disp32
+541     # . . discard args
+542     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+543     # scan-next-byte(_test-buffered-file)
+544     # . . push args
+545     68/push  _test-buffered-file/imm32
+546     # . . call
+547     e8/call  scan-next-byte/disp32
+548     # . . discard args
+549     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+550     # check-ints-equal(EAX, 0x61/a, msg)
+551     # . . push args
+552     68/push  "F - test-scan-next-byte-skips-comment"/imm32
+553     68/push  0x61/imm32/a
+554     50/push-EAX
+555     # . . call
+556     e8/call  check-ints-equal/disp32
+557     # . . discard args
+558     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+559     # . end
+560     c3/return
+561 
+562 is-hex-lowercase-byte?:  # c : byte -> bool/EAX
+563     # . prolog
+564     55/push-EBP
+565     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+566     # . save registers
+567     51/push-ECX
+568     # ECX = c
+569     8b/copy                         1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           1/r32/ECX   0x8/disp8       .                 # copy *(EBP+8) to ECX
+570     # return false if c < '0'
+571     b8/copy-to-EAX  0/imm32/false
+572     81          7/subop/compare     3/mod/direct    1/rm32/ECX    .           .             .           .           .               0x30/imm32        # compare ECX
+573     7c/jump-if-lesser  $is-hex-lowercase-byte?:end/disp8
+574     # return false if c > 'f'
+575     81          7/subop/compare     3/mod/direct    1/rm32/ECX    .           .             .           .           .               0x66/imm32        # compare ECX
+576     7f/jump-if-greater  $is-hex-lowercase-byte?:end/disp8
+577     # return true if c <= '9'
+578     b8/copy-to-EAX  1/imm32/true
+579     81          7/subop/compare     3/mod/direct    1/rm32/ECX    .           .             .           .           .               0x39/imm32        # compare ECX
+580     7e/jump-if-lesser-or-equal  $is-hex-lowercase-byte?:end/disp8
+581     # return true if c >= 'a'
+582     81          7/subop/compare     3/mod/direct    1/rm32/ECX    .           .             .           .           .               0x61/imm32        # compare ECX
+583     7d/jump-if-greater-or-equal  $is-hex-lowercase-byte?:end/disp8
+584     # otherwise return false
+585     b8/copy-to-EAX  0/imm32/false
+586 $is-hex-lowercase-byte?:end:
+587     # . restore registers
+588     59/pop-to-ECX
+589     # . epilog
+590     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+591     5d/pop-to-EBP
+592     c3/return
+593 
+594 test-hex-below-0:
+595     # is-hex-lowercase-byte?(0x2f)
+596     # . . push args
+597     68/push  0x2f/imm32
+598     # . . call
+599     e8/call  is-hex-lowercase-byte?/disp32
+600     # . . discard args
+601     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+602     # check-ints-equal(EAX, 0, msg)
+603     # . . push args
+604     68/push  "F - test-hex-below-0"/imm32
+605     68/push  0/imm32/false
+606     50/push-EAX
+607     # . . call
+608     e8/call  check-ints-equal/disp32
+609     # . . discard args
+610     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+611     c3/return
+612 
+613 test-hex-0-to-9:
+614     # is-hex-lowercase-byte?(0x30)
+615     # . . push args
+616     68/push  0x30/imm32
+617     # . . call
+618     e8/call  is-hex-lowercase-byte?/disp32
+619     # . . discard args
+620     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+621     # check-ints-equal(EAX, 1, msg)
+622     # . . push args
+623     68/push  "F - test-hex-at-0"/imm32
+624     68/push  1/imm32/true
+625     50/push-EAX
+626     # . . call
+627     e8/call  check-ints-equal/disp32
+628     # . . discard args
+629     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+630     # is-hex-lowercase-byte?(0x39)
+631     # . . push args
+632     68/push  0x39/imm32
+633     # . . call
+634     e8/call  is-hex-lowercase-byte?/disp32
+635     # . . discard args
+636     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+637     # check-ints-equal(EAX, 1, msg)
+638     # . . push args
+639     68/push  "F - test-hex-at-9"/imm32
+640     68/push  1/imm32/true
+641     50/push-EAX
+642     # . . call
+643     e8/call  check-ints-equal/disp32
+644     # . . discard args
+645     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+646     c3/return
+647 
+648 test-hex-above-9-to-a:
+649     # is-hex-lowercase-byte?(0x3a)
+650     # . . push args
+651     68/push  0x3a/imm32
+652     # . . call
+653     e8/call  is-hex-lowercase-byte?/disp32
+654     # . . discard args
+655     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+656     # check-ints-equal(EAX, 0, msg)
+657     # . . push args
+658     68/push  "F - test-hex-above-9-to-a"/imm32
+659     68/push  0/imm32/false
+660     50/push-EAX
+661     # . . call
+662     e8/call  check-ints-equal/disp32
+663     # . . discard args
+664     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+665     c3/return
+666 
+667 test-hex-a-to-f:
+668     # is-hex-lowercase-byte?(0x61)
+669     # . . push args
+670     68/push  0x61/imm32
+671     # . . call
+672     e8/call  is-hex-lowercase-byte?/disp32
+673     # . . discard args
+674     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+675     # check-ints-equal(EAX, 1, msg)
+676     # . . push args
+677     68/push  "F - test-hex-at-a"/imm32
+678     68/push  1/imm32/true
+679     50/push-EAX
+680     # . . call
+681     e8/call  check-ints-equal/disp32
+682     # . . discard args
+683     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+684     # is-hex-lowercase-byte?(0x66)
+685     # . . push args
+686     68/push  0x66/imm32
+687     # . . call
+688     e8/call  is-hex-lowercase-byte?/disp32
+689     # . . discard args
+690     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+691     # check-ints-equal(EAX, 1, msg)
+692     # . . push args
+693     68/push  "F - test-hex-at-f"/imm32
+694     68/push  1/imm32/true
+695     50/push-EAX
+696     # . . call
+697     e8/call  check-ints-equal/disp32
+698     # . . discard args
+699     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+700     c3/return
+701 
+702 test-hex-above-f:
+703     # is-hex-lowercase-byte?(0x67)
+704     # . . push args
+705     68/push  0x67/imm32
+706     # . . call
+707     e8/call  is-hex-lowercase-byte?/disp32
+708     # . . discard args
+709     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+710     # check-ints-equal(EAX, 0, msg)
+711     # . . push args
+712     68/push  "F - test-hex-above-f"/imm32
+713     68/push  0/imm32/false
+714     50/push-EAX
+715     # . . call
+716     e8/call  check-ints-equal/disp32
+717     # . . discard args
+718     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+719     c3/return
+720 
+721 skip-until-newline:  # in : (address buffered-file) -> <void>
+722     # pseudocode:
+723     #   push EAX
+724     #   repeatedly:
+725     #     EAX = read-byte(in)
+726     #     if EAX == 0xffffffff break
+727     #     if EAX == 0x0a break
+728     #   pop EAX
+729     # . prolog
+730     55/push-EBP
+731     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+732     # . save registers
+733     50/push-EAX
+734 $skip-until-newline:loop:
+735     # . EAX = read-byte(in)
+736     # . . push args
+737     ff          6/subop/push        1/mod/*+disp8   4/rm32/sib    5/base/EBP  4/index/none  .           .           0x8/disp8       .                 # push *(EBP+8)
+738     # . . call
+739     e8/call  read-byte/disp32
+740     # . . discard args
+741     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+742     # . if EAX == 0xffffffff break
+743     81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0xffffffff/imm32  # compare EAX
+744     74/jump-if-equal  $skip-until-newline:end/disp8
+745 $aa:
+746     # . if EAX != 0xa/newline loop
+747     81          7/subop/compare     3/mod/direct    0/rm32/EAX    .           .             .           .           .               0xa/imm32         # compare EAX
+748     75/jump-if-not-equal  $skip-until-newline:loop/disp8
+749 $skip-until-newline:end:
+750     # . restore registers
+751     58/pop-to-EAX
+752     # . epilog
+753     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+754     5d/pop-to-EBP
+755     c3/return
+756 
+757 test-skip-until-newline:
+758     # - check that the read pointer points after the newline
+759     # setup
+760     # . clear-stream(_test-stream)
+761     # . . push args
+762     68/push  _test-stream/imm32
+763     # . . call
+764     e8/call  clear-stream/disp32
+765     # . . discard args
+766     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+767     # . clear-stream(_test-buffered-file+4)
+768     # . . push args
+769     b8/copy-to-EAX  _test-buffered-file/imm32
+770     05/add-to-EAX  4/imm32
+771     50/push-EAX
+772     # . . call
+773     e8/call  clear-stream/disp32
+774     # . . discard args
+775     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+776     # initialize '_test-stream' to "abc\nde"
+777     # . write(_test-stream, "abc")
+778     # . . push args
+779     68/push  "abc"/imm32
+780     68/push  _test-stream/imm32
+781     # . . call
+782     e8/call  write/disp32
+783     # . . discard args
+784     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+785     # . write(_test-stream, Newline)
+786     # . . push args
+787     68/push  Newline/imm32
+788     68/push  _test-stream/imm32
+789     # . . call
+790     e8/call  write/disp32
+791     # . . discard args
+792     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+793     # . write(_test-stream, "de")
+794     # . . push args
+795     68/push  "de"/imm32
+796     68/push  _test-stream/imm32
+797     # . . call
+798     e8/call  write/disp32
+799     # . . discard args
+800     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+801     # skip-until-newline(_test-buffered-file)
+802     # . . push args
+803     68/push  _test-buffered-file/imm32
+804     # . . call
+805     e8/call  skip-until-newline/disp32
+806     # . . discard args
+807     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+808     # check-ints-equal(_test-buffered-file->read, 4, msg)
+809     # . . push args
+810     68/push  "F - test-skip-until-newline"/imm32
+811     68/push  4/imm32
+812     b8/copy-to-EAX  _test-buffered-file/imm32
+813     ff          6/subop/push        1/mod/*+disp8   0/rm32/EAX    .           .             .           .           8/disp8         .                 # push *(EAX+8)
+814     # . . call
+815     e8/call  check-ints-equal/disp32
+816     # . . discard args
+817     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+818     # . end
+819     c3/return
+820 
+821 == data
+822 
+823 # . . vim:nowrap:textwidth=0
+
+ + + -- cgit 1.4.1-2-gfad0