From 3350c34a74844e21ea69077e01efff3bae64bdcd Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 23 Mar 2021 17:31:08 -0700 Subject: . --- html/linux/127next-word.subx.html | 425 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 html/linux/127next-word.subx.html (limited to 'html/linux/127next-word.subx.html') diff --git a/html/linux/127next-word.subx.html b/html/linux/127next-word.subx.html new file mode 100644 index 00000000..ab525e3c --- /dev/null +++ b/html/linux/127next-word.subx.html @@ -0,0 +1,425 @@ + + + + +Mu - linux/127next-word.subx + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/127next-word.subx +
+  1 # Tokenize by whitespace.
+  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 (surrounded by whitespace,
+  9 # treating '#' comments as a single word)
+ 10 # return empty string on reaching end of file
+ 11 next-word:  # line: (addr stream byte), out: (addr slice)
+ 12     # . prologue
+ 13     55/push-ebp
+ 14     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+ 15     # . save registers
+ 16     50/push-eax
+ 17     51/push-ecx
+ 18     56/push-esi
+ 19     57/push-edi
+ 20     # esi = line
+ 21     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
+ 22     # edi = out
+ 23     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
+ 24     # skip-chars-matching-whitespace(line)
+ 25     # . . push args
+ 26     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+ 27     # . . call
+ 28     e8/call  skip-chars-matching-whitespace/disp32
+ 29     # . . discard args
+ 30     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/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-<  $next-word:check-for-comment/disp8
+ 38     # . return out
+ 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:check-for-comment:
+ 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-!=  $next-word:regular-word/disp8
+ 54 $next-word:comment:
+ 55     # . out->end = &line->data[line->write]
+ 56     8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           0/r32/eax   .               .                 # copy *esi to eax
+ 57     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
+ 58     89/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           0/r32/eax   4/disp8         .                 # copy eax to *(edi+4)
+ 59     # . line->read = line->write
+ 60     8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           0/r32/eax   .               .                 # copy *esi to eax
+ 61     89/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           0/r32/eax   4/disp8         .                 # copy eax to *(esi+4)
+ 62     # . return
+ 63     eb/jump  $next-word:end/disp8
+ 64 $next-word:regular-word:
+ 65     # otherwise skip-chars-not-matching-whitespace(line)  # including trailing newline
+ 66     # . . push args
+ 67     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+ 68     # . . call
+ 69     e8/call  skip-chars-not-matching-whitespace/disp32
+ 70     # . . discard args
+ 71     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 72     # out->end = &line->data[line->read]
+ 73     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
+ 74     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
+ 75     89/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           0/r32/eax   4/disp8         .                 # copy eax to *(edi+4)
+ 76 $next-word:end:
+ 77     # . restore registers
+ 78     5f/pop-to-edi
+ 79     5e/pop-to-esi
+ 80     59/pop-to-ecx
+ 81     58/pop-to-eax
+ 82     # . epilogue
+ 83     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+ 84     5d/pop-to-ebp
+ 85     c3/return
+ 86 
+ 87 test-next-word:
+ 88     # . prologue
+ 89     55/push-ebp
+ 90     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+ 91     # setup
+ 92     # . clear-stream(_test-stream)
+ 93     # . . push args
+ 94     68/push  _test-stream/imm32
+ 95     # . . call
+ 96     e8/call  clear-stream/disp32
+ 97     # . . discard args
+ 98     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 99     # var slice/ecx: slice
+100     68/push  0/imm32/end
+101     68/push  0/imm32/start
+102     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+103     # write(_test-stream, "  ab")
+104     # . . push args
+105     68/push  "  ab"/imm32
+106     68/push  _test-stream/imm32
+107     # . . call
+108     e8/call  write/disp32
+109     # . . discard args
+110     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+111     # next-word(_test-stream, slice)
+112     # . . push args
+113     51/push-ecx
+114     68/push  _test-stream/imm32
+115     # . . call
+116     e8/call  next-word/disp32
+117     # . . discard args
+118     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+119     # check-ints-equal(slice->start - _test-stream->data, 2, msg)
+120     # . check-ints-equal(slice->start - _test-stream, 14, msg)
+121     # . . push args
+122     68/push  "F - test-next-word: start"/imm32
+123     68/push  0xe/imm32
+124     # . . push slice->start - _test-stream
+125     8b/copy                         0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # copy *ecx to eax
+126     81          5/subop/subtract    3/mod/direct    0/rm32/eax    .           .             .           .           .               _test-stream/imm32 # subtract from eax
+127     50/push-eax
+128     # . . call
+129     e8/call  check-ints-equal/disp32
+130     # . . discard args
+131     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+132     # check-ints-equal(slice->end - _test-stream->data, 4, msg)
+133     # . check-ints-equal(slice->end - _test-stream, 16, msg)
+134     # . . push args
+135     68/push  "F - test-next-word: end"/imm32
+136     68/push  0x10/imm32
+137     # . . push slice->end - _test-stream
+138     8b/copy                         1/mod/*+disp8   1/rm32/ecx    .           .             .           0/r32/eax   4/disp8         .                 # copy *(ecx+4) to eax
+139     81          5/subop/subtract    3/mod/direct    0/rm32/eax    .           .             .           .           .               _test-stream/imm32 # subtract from eax
+140     50/push-eax
+141     # . . call
+142     e8/call  check-ints-equal/disp32
+143     # . . discard args
+144     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+145     # . epilogue
+146     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+147     5d/pop-to-ebp
+148     c3/return
+149 
+150 test-next-word-returns-whole-comment:
+151     # . prologue
+152     55/push-ebp
+153     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+154     # setup
+155     # . clear-stream(_test-stream)
+156     # . . push args
+157     68/push  _test-stream/imm32
+158     # . . call
+159     e8/call  clear-stream/disp32
+160     # . . discard args
+161     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+162     # var slice/ecx: slice
+163     68/push  0/imm32/end
+164     68/push  0/imm32/start
+165     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+166     # write(_test-stream, "  # a")
+167     # . . push args
+168     68/push  "  # a"/imm32
+169     68/push  _test-stream/imm32
+170     # . . call
+171     e8/call  write/disp32
+172     # . . discard args
+173     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+174     # next-word(_test-stream, slice)
+175     # . . push args
+176     51/push-ecx
+177     68/push  _test-stream/imm32
+178     # . . call
+179     e8/call  next-word/disp32
+180     # . . discard args
+181     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+182     # check-ints-equal(slice->start - _test-stream->data, 2, msg)
+183     # . check-ints-equal(slice->start - _test-stream, 14, msg)
+184     # . . push args
+185     68/push  "F - test-next-word-returns-whole-comment: start"/imm32
+186     68/push  0xe/imm32
+187     # . . push slice->start - _test-stream
+188     8b/copy                         0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # copy *ecx to eax
+189     81          5/subop/subtract    3/mod/direct    0/rm32/eax    .           .             .           .           .               _test-stream/imm32 # subtract from eax
+190     50/push-eax
+191     # . . call
+192     e8/call  check-ints-equal/disp32
+193     # . . discard args
+194     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+195     # check-ints-equal(slice->end - _test-stream->data, 5, msg)
+196     # . check-ints-equal(slice->end - _test-stream, 17, msg)
+197     # . . push args
+198     68/push  "F - test-next-word-returns-whole-comment: end"/imm32
+199     68/push  0x11/imm32
+200     # . . push slice->end - _test-stream
+201     8b/copy                         1/mod/*+disp8   1/rm32/ecx    .           .             .           0/r32/eax   4/disp8         .                 # copy *(ecx+4) to eax
+202     81          5/subop/subtract    3/mod/direct    0/rm32/eax    .           .             .           .           .               _test-stream/imm32 # subtract from eax
+203     50/push-eax
+204     # . . call
+205     e8/call  check-ints-equal/disp32
+206     # . . discard args
+207     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+208     # . epilogue
+209     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+210     5d/pop-to-ebp
+211     c3/return
+212 
+213 test-next-word-returns-empty-string-on-eof:
+214     # . prologue
+215     55/push-ebp
+216     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+217     # setup
+218     # . clear-stream(_test-stream)
+219     # . . push args
+220     68/push  _test-stream/imm32
+221     # . . call
+222     e8/call  clear-stream/disp32
+223     # . . discard args
+224     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+225     # var slice/ecx: slice
+226     68/push  0/imm32/end
+227     68/push  0/imm32/start
+228     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+229     # write nothing to _test-stream
+230     # next-word(_test-stream, slice)
+231     # . . push args
+232     51/push-ecx
+233     68/push  _test-stream/imm32
+234     # . . call
+235     e8/call  next-word/disp32
+236     # . . discard args
+237     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+238     # check-ints-equal(slice->end - slice->start, 0, msg)
+239     # . . push args
+240     68/push  "F - test-next-word-returns-empty-string-on-eof"/imm32
+241     68/push  0/imm32
+242     # . . push slice->end - slice->start
+243     8b/copy                         1/mod/*+disp8   1/rm32/ecx    .           .             .           0/r32/eax   4/disp8         .                 # copy *(ecx+4) to eax
+244     2b/subtract                     0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # subtract *ecx from eax
+245     50/push-eax
+246     # . . call
+247     e8/call  check-ints-equal/disp32
+248     # . . discard args
+249     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+250     # . epilogue
+251     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+252     5d/pop-to-ebp
+253     c3/return
+254 
+255 test-next-word-returns-empty-string-on-newline:
+256     # . prologue
+257     55/push-ebp
+258     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+259     # setup
+260     # . clear-stream(_test-stream)
+261     # . . push args
+262     68/push  _test-stream/imm32
+263     # . . call
+264     e8/call  clear-stream/disp32
+265     # . . discard args
+266     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+267     # var slice/ecx: slice
+268     68/push  0/imm32/end
+269     68/push  0/imm32/start
+270     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+271     # write some whitespace and a newline
+272     # . . push args
+273     68/push  "  \n"/imm32
+274     68/push  _test-stream/imm32
+275     # . . call
+276     e8/call  write/disp32
+277     # . . discard args
+278     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+279     # next-word(_test-stream, slice)
+280     # . . push args
+281     51/push-ecx
+282     68/push  _test-stream/imm32
+283     # . . call
+284     e8/call  next-word/disp32
+285     # . . discard args
+286     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+287     # check-ints-equal(slice->end - slice->start, 0, msg)
+288     # . . push args
+289     68/push  "F - test-next-word-returns-empty-string-on-newline"/imm32
+290     68/push  0/imm32
+291     # . . push slice->end - slice->start
+292     8b/copy                         1/mod/*+disp8   1/rm32/ecx    .           .             .           0/r32/eax   4/disp8         .                 # copy *(ecx+4) to eax
+293     2b/subtract                     0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # subtract *ecx from eax
+294     50/push-eax
+295     # . . call
+296     e8/call  check-ints-equal/disp32
+297     # . . discard args
+298     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+299     # . epilogue
+300     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+301     5d/pop-to-ebp
+302     c3/return
+303 
+304 # (re)compute the bounds of the next word in the line (separated by whitespace)
+305 # return empty string on reaching end of file
+306 next-raw-word:  # line: (addr stream byte), out: (addr slice)
+307     # . prologue
+308     55/push-ebp
+309     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+310     # . save registers
+311     50/push-eax
+312     51/push-ecx
+313     56/push-esi
+314     57/push-edi
+315     # esi = line
+316     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
+317     # edi = out
+318     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
+319     # skip-chars-matching-whitespace(line)
+320     # . . push args
+321     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+322     # . . call
+323     e8/call  skip-chars-matching-whitespace/disp32
+324     # . . discard args
+325     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+326 $next-raw-word:check0:
+327     # if (line->read >= line->write) clear out and return
+328     # . eax = line->read
+329     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           0/r32/eax   4/disp8         .                 # copy *(esi+4) to eax
+330     # . if (eax < line->write) goto next check
+331     3b/compare                      0/mod/indirect  6/rm32/esi    .           .             .           0/r32/eax   .               .                 # compare eax with *esi
+332     7c/jump-if-<  $next-raw-word:word-exists/disp8
+333     # . return out
+334     c7          0/subop/copy        0/mod/direct    7/rm32/edi    .           .             .           .           .               0/imm32           # copy to *edi
+335     c7          0/subop/copy        1/mod/*+disp8   7/rm32/edi    .           .             .           .           4/disp8         0/imm32           # copy to *(edi+4)
+336     eb/jump  $next-raw-word:end/disp8
+337 $next-raw-word:word-exists:
+338     # out->start = &line->data[line->read]
+339     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
+340     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
+341     89/copy                         0/mod/indirect  7/rm32/edi    .           .             .           0/r32/eax   .               .                 # copy eax to *edi
+342     # skip-chars-not-matching-whitespace(line)  # including trailing newline
+343     # . . push args
+344     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
+345     # . . call
+346     e8/call  skip-chars-not-matching-whitespace/disp32
+347     # . . discard args
+348     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+349     # out->end = &line->data[line->read]
+350     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
+351     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
+352     89/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           0/r32/eax   4/disp8         .                 # copy eax to *(edi+4)
+353 $next-raw-word:end:
+354     # . restore registers
+355     5f/pop-to-edi
+356     5e/pop-to-esi
+357     59/pop-to-ecx
+358     58/pop-to-eax
+359     # . epilogue
+360     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+361     5d/pop-to-ebp
+362     c3/return
+
+ + + -- cgit 1.4.1-2-gfad0