From 09492d3867b5da6d0b2f21b139d097cd481a8fa1 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Wed, 10 Apr 2019 21:18:55 -0700 Subject: 5077 --- html/subx/apps/subx-common.subx.html | 314 +++++++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 html/subx/apps/subx-common.subx.html (limited to 'html/subx/apps/subx-common.subx.html') diff --git a/html/subx/apps/subx-common.subx.html b/html/subx/apps/subx-common.subx.html new file mode 100644 index 00000000..01e40369 --- /dev/null +++ b/html/subx/apps/subx-common.subx.html @@ -0,0 +1,314 @@ + + + + +Mu - subx/apps/subx-common.subx + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/subx/apps/subx-common.subx +
+  1 # some common helpers shared by phases of the SubX converter
+  2 
+  3 == code
+  4 #   instruction                     effective address                                                   register    displacement    immediate
+  5 # . op          subop               mod             rm32          base        index         scale       r32
+  6 # . 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
+  7 
+  8 # (re)compute the bounds of the next word in the line
+  9 # return empty string on reaching end of file
+ 10 next-word:  # line : (address stream byte), out : (address slice)
+ 11     # . prolog
+ 12     55/push-EBP
+ 13     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+ 14     # . save registers
+ 15     50/push-EAX
+ 16     51/push-ECX
+ 17     56/push-ESI
+ 18     57/push-EDI
+ 19     # ESI = line
+ 20     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           6/r32/ESI   8/disp8         .                 # copy *(EBP+8) to ESI
+ 21     # EDI = out
+ 22     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           7/r32/EDI   0xc/disp8       .                 # copy *(EBP+12) to EDI
+ 23     # skip-chars-matching(line, ' ')
+ 24     # . . push args
+ 25     68/push  0x20/imm32/space
+ 26     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+ 27     # . . call
+ 28     e8/call  skip-chars-matching/disp32
+ 29     # . . discard args
+ 30     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+ 31 $next-word:check0:
+ 32     # if (line->read >= line->write) clear out and return
+ 33     # . EAX = line->read
+ 34     8b/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           0/r32/EAX   4/disp8         .                 # copy *(ESI+4) to EAX
+ 35     # . if (EAX < line->write) goto next check
+ 36     3b/compare                      0/mod/indirect  6/rm32/ESI    .           .             .           0/r32/EAX   .               .                 # compare EAX with *ESI
+ 37     7c/jump-if-lesser  $next-word:check1/disp8
+ 38     # . return out = {0, 0}
+ 39     c7          0/subop/copy        0/mod/direct    7/rm32/EDI    .           .             .           .           .               0/imm32           # copy to *EDI
+ 40     c7          0/subop/copy        1/mod/*+disp8   7/rm32/EDI    .           .             .           .           4/disp8         0/imm32           # copy to *(EDI+4)
+ 41     eb/jump  $next-word:end/disp8
+ 42 $next-word:check1:
+ 43     # out->start = &line->data[line->read]
+ 44     8b/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   4/disp8         .                 # copy *(ESI+4) to ECX
+ 45     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    6/base/ESI  1/index/ECX   .           0/r32/EAX   0xc/disp8       .                 # copy ESI+ECX+12 to EAX
+ 46     89/copy                         0/mod/indirect  7/rm32/EDI    .           .             .           0/r32/EAX   .               .                 # copy EAX to *EDI
+ 47     # if (line->data[line->read] == '#') out->end = &line->data[line->write]), skip rest of stream and return
+ 48     # . EAX = line->data[line->read]
+ 49     31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
+ 50     8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/ESI  1/index/ECX   .           0/r32/AL    0xc/disp8       .                 # copy byte at *(ESI+ECX+12) to AL
+ 51     # . compare
+ 52     3d/compare-EAX-and  0x23/imm32/pound
+ 53     75/jump-if-not-equal  $next-word:not-comment/disp8
+ 54     # . out->end = &line->data[line->write]
+ 55     8b/copy                         0/mod/indirect  6/rm32/ESI    .           .             .           0/r32/EAX   .               .                 # copy *ESI to EAX
+ 56     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    6/base/ESI  0/index/EAX   .           0/r32/EAX   0xc/disp8       .                 # copy ESI+EAX+12 to EAX
+ 57     89/copy                         1/mod/*+disp8   7/rm32/EDI    .           .             .           0/r32/EAX   4/disp8         .                 # copy EAX to *(EDI+4)
+ 58     # . line->read = line->write
+ 59     89/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           0/r32/EAX   4/disp8         .                 # copy EAX to *(ESI+4)
+ 60     # . return
+ 61     eb/jump  $next-word:end/disp8
+ 62 $next-word:not-comment:
+ 63     # otherwise skip-chars-not-matching-whitespace(line)  # including trailing newline
+ 64     # . . push args
+ 65     ff          6/subop/push        1/mod/*+disp8   5/rm32/EBP    .           .             .           .           8/disp8         .                 # push *(EBP+8)
+ 66     # . . call
+ 67     e8/call  skip-chars-not-matching-whitespace/disp32
+ 68     # . . discard args
+ 69     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+ 70     # out->end = &line->data[line->read]
+ 71     8b/copy                         1/mod/*+disp8   6/rm32/ESI    .           .             .           1/r32/ECX   4/disp8         .                 # copy *(ESI+4) to ECX
+ 72     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    6/base/ESI  1/index/ECX   .           0/r32/EAX   0xc/disp8       .                 # copy ESI+ECX+12 to EAX
+ 73     89/copy                         1/mod/*+disp8   7/rm32/EDI    .           .             .           0/r32/EAX   4/disp8         .                 # copy EAX to *(EDI+4)
+ 74 $next-word:end:
+ 75     # . restore registers
+ 76     5f/pop-to-EDI
+ 77     5e/pop-to-ESI
+ 78     59/pop-to-ECX
+ 79     58/pop-to-EAX
+ 80     # . epilog
+ 81     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+ 82     5d/pop-to-EBP
+ 83     c3/return
+ 84 
+ 85 test-next-word:
+ 86     # . prolog
+ 87     55/push-EBP
+ 88     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+ 89     # setup
+ 90     # . clear-stream(_test-stream)
+ 91     # . . push args
+ 92     68/push  _test-stream/imm32
+ 93     # . . call
+ 94     e8/call  clear-stream/disp32
+ 95     # . . discard args
+ 96     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+ 97     # var slice/ECX = {0, 0}
+ 98     68/push  0/imm32/end
+ 99     68/push  0/imm32/start
+100     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+101     # write(_test-stream, "  ab")
+102     # . . push args
+103     68/push  "  ab"/imm32
+104     68/push  _test-stream/imm32
+105     # . . call
+106     e8/call  write/disp32
+107     # . . discard args
+108     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+109     # next-word(_test-stream, slice)
+110     # . . push args
+111     51/push-ECX
+112     68/push  _test-stream/imm32
+113     # . . call
+114     e8/call  next-word/disp32
+115     # . . discard args
+116     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+117     # check-ints-equal(slice->start - _test-stream->data, 2, msg)
+118     # . check-ints-equal(slice->start - _test-stream, 14, msg)
+119     # . . push args
+120     68/push  "F - test-next-word: start"/imm32
+121     68/push  0xe/imm32
+122     # . . push slice->start - _test-stream
+123     8b/copy                         0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/EAX   .               .                 # copy *ECX to EAX
+124     81          5/subop/subtract    3/mod/direct    0/rm32/EAX    .           .             .           .           .               _test-stream/imm32 # subtract from EAX
+125     50/push-EAX
+126     # . . call
+127     e8/call  check-ints-equal/disp32
+128     # . . discard args
+129     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+130     # check-ints-equal(slice->end - _test-stream->data, 4, msg)
+131     # . check-ints-equal(slice->end - _test-stream, 16, msg)
+132     # . . push args
+133     68/push  "F - test-next-word: end"/imm32
+134     68/push  0x10/imm32
+135     # . . push slice->end - _test-stream
+136     8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           0/r32/EAX   4/disp8         .                 # copy *(ECX+4) to EAX
+137     81          5/subop/subtract    3/mod/direct    0/rm32/EAX    .           .             .           .           .               _test-stream/imm32 # subtract from EAX
+138     50/push-EAX
+139     # . . call
+140     e8/call  check-ints-equal/disp32
+141     # . . discard args
+142     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+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 test-next-word-returns-whole-comment:
+149     # . prolog
+150     55/push-EBP
+151     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+152     # setup
+153     # . clear-stream(_test-stream)
+154     # . . push args
+155     68/push  _test-stream/imm32
+156     # . . call
+157     e8/call  clear-stream/disp32
+158     # . . discard args
+159     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+160     # var slice/ECX = {0, 0}
+161     68/push  0/imm32/end
+162     68/push  0/imm32/start
+163     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+164     # write(_test-stream, "  # a")
+165     # . . push args
+166     68/push  "  # a"/imm32
+167     68/push  _test-stream/imm32
+168     # . . call
+169     e8/call  write/disp32
+170     # . . discard args
+171     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+172     # next-word(_test-stream, slice)
+173     # . . push args
+174     51/push-ECX
+175     68/push  _test-stream/imm32
+176     # . . call
+177     e8/call  next-word/disp32
+178     # . . discard args
+179     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+180     # check-ints-equal(slice->start - _test-stream->data, 2, msg)
+181     # . check-ints-equal(slice->start - _test-stream, 14, msg)
+182     # . . push args
+183     68/push  "F - test-next-word-returns-whole-comment: start"/imm32
+184     68/push  0xe/imm32
+185     # . . push slice->start - _test-stream
+186     8b/copy                         0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/EAX   .               .                 # copy *ECX to EAX
+187     81          5/subop/subtract    3/mod/direct    0/rm32/EAX    .           .             .           .           .               _test-stream/imm32 # subtract from EAX
+188     50/push-EAX
+189     # . . call
+190     e8/call  check-ints-equal/disp32
+191     # . . discard args
+192     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+193     # check-ints-equal(slice->end - _test-stream->data, 5, msg)
+194     # . check-ints-equal(slice->end - _test-stream, 17, msg)
+195     # . . push args
+196     68/push  "F - test-next-word-returns-whole-comment: end"/imm32
+197     68/push  0x11/imm32
+198     # . . push slice->end - _test-stream
+199     8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           0/r32/EAX   4/disp8         .                 # copy *(ECX+4) to EAX
+200     81          5/subop/subtract    3/mod/direct    0/rm32/EAX    .           .             .           .           .               _test-stream/imm32 # subtract from EAX
+201     50/push-EAX
+202     # . . call
+203     e8/call  check-ints-equal/disp32
+204     # . . discard args
+205     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+206     # . epilog
+207     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+208     5d/pop-to-EBP
+209     c3/return
+210 
+211 test-next-word-returns-empty-string-on-eof:
+212     # . prolog
+213     55/push-EBP
+214     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+215     # setup
+216     # . clear-stream(_test-stream)
+217     # . . push args
+218     68/push  _test-stream/imm32
+219     # . . call
+220     e8/call  clear-stream/disp32
+221     # . . discard args
+222     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+223     # var slice/ECX = {0, 0}
+224     68/push  0/imm32/end
+225     68/push  0/imm32/start
+226     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+227     # write nothing to _test-stream
+228     # next-word(_test-stream, slice)
+229     # . . push args
+230     51/push-ECX
+231     68/push  _test-stream/imm32
+232     # . . call
+233     e8/call  next-word/disp32
+234     # . . discard args
+235     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+236     # check-ints-equal(slice->end - slice->start, 0, msg)
+237     # . . push args
+238     68/push  "F - test-next-word-returns-empty-string-on-eof"/imm32
+239     68/push  0/imm32
+240     # . . push slice->end - slice->start
+241     8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           0/r32/EAX   4/disp8         .                 # copy *(ECX+4) to EAX
+242     2b/subtract                     0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/EAX   .               .                 # subtract *ECX from EAX
+243     50/push-EAX
+244     # . . call
+245     e8/call  check-ints-equal/disp32
+246     # . . discard args
+247     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+248     # . epilog
+249     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+250     5d/pop-to-EBP
+251     c3/return
+
+ + + -- cgit 1.4.1-2-gfad0