From 4a4a392dc7c81b301ad6b760525c5549f2f6644c Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Fri, 20 Sep 2019 11:19:30 -0700 Subject: 5683 --- html/077subx-words.subx.html | 694 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 694 insertions(+) create mode 100644 html/077subx-words.subx.html (limited to 'html/077subx-words.subx.html') diff --git a/html/077subx-words.subx.html b/html/077subx-words.subx.html new file mode 100644 index 00000000..3a3d97fb --- /dev/null +++ b/html/077subx-words.subx.html @@ -0,0 +1,694 @@ + + + + +Mu - 077subx-words.subx + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/077subx-words.subx +
+  1 # Helpers for parsing SubX words, with their rules for hex, labels and metadata.
+  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 has-metadata?:  # word : (address slice), s : (address string) -> eax : boolean
+  9     # pseudocode:
+ 10     #   var twig : &slice = next-token-from-slice(word->start, word->end, '/')  # skip name
+ 11     #   curr = twig->end
+ 12     #   while true
+ 13     #     twig = next-token-from-slice(curr, word->end, '/')
+ 14     #     if (twig.empty()) break
+ 15     #     if (slice-equal?(twig, s)) return true
+ 16     #     curr = twig->end
+ 17     #   return false
+ 18     # . prolog
+ 19     55/push-ebp
+ 20     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+ 21     # . save registers
+ 22     51/push-ecx
+ 23     52/push-edx
+ 24     56/push-esi
+ 25     57/push-edi
+ 26     # esi = word
+ 27     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
+ 28     # edx = word->end
+ 29     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           2/r32/edx   4/disp8         .                 # copy *(esi+4) to edx
+ 30     # var twig/edi : (address slice) = {0, 0}
+ 31     68/push  0/imm32/end
+ 32     68/push  0/imm32/start
+ 33     89/copy                         3/mod/direct    7/rm32/edi    .           .             .           4/r32/esp   .               .                 # copy esp to edi
+ 34     # next-token-from-slice(word->start, word->end, '/', twig)
+ 35     # . . push args
+ 36     57/push-edi
+ 37     68/push  0x2f/imm32/slash
+ 38     52/push-edx
+ 39     ff          6/subop/push        0/mod/indirect  6/rm32/esi    .           .             .           .           .               .                 # push *esi
+ 40     # . . call
+ 41     e8/call  next-token-from-slice/disp32
+ 42     # . . discard args
+ 43     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0x10/imm32        # add to esp
+ 44     # curr/ecx = twig->end
+ 45     8b/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(edi+4) to ecx
+ 46 $has-metadata?:loop:
+ 47     # next-token-from-slice(curr, word->end, '/', twig)
+ 48     # . . push args
+ 49     57/push-edi
+ 50     68/push  0x2f/imm32/slash
+ 51     52/push-edx
+ 52     51/push-ecx
+ 53     # . . call
+ 54     e8/call  next-token-from-slice/disp32
+ 55     # . . discard args
+ 56     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0x10/imm32        # add to esp
+ 57     # if (slice-empty?(twig)) return false
+ 58     # . eax = slice-empty?(twig)
+ 59     # . . push args
+ 60     57/push-edi
+ 61     # . . call
+ 62     e8/call  slice-empty?/disp32
+ 63     # . . discard args
+ 64     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+ 65     # . if (eax != 0) return false
+ 66     3d/compare-eax-and  0/imm32
+ 67     75/jump-if-not-equal  $has-metadata?:false/disp8
+ 68     # if (slice-equal?(twig, s)) return true
+ 69     # . eax = slice-equal?(twig, s)
+ 70     # . . push args
+ 71     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
+ 72     57/push-edi
+ 73     # . . call
+ 74     e8/call  slice-equal?/disp32
+ 75     # . . discard args
+ 76     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 77     # . if (eax != 0) return true
+ 78     3d/compare-eax-and  0/imm32
+ 79     75/jump-if-not-equal  $has-metadata?:true/disp8
+ 80     # curr = twig->end
+ 81     8b/copy                         1/mod/*+disp8   7/rm32/edi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(edi+4) to ecx
+ 82     eb/jump  $has-metadata?:loop/disp8
+ 83 $has-metadata?:true:
+ 84     b8/copy-to-eax  1/imm32/true
+ 85     eb/jump  $has-metadata?:end/disp8
+ 86 $has-metadata?:false:
+ 87     b8/copy-to-eax  0/imm32/false
+ 88 $has-metadata?:end:
+ 89     # . reclaim locals
+ 90     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+ 91     # . restore registers
+ 92     5f/pop-to-edi
+ 93     5e/pop-to-esi
+ 94     5a/pop-to-edx
+ 95     59/pop-to-ecx
+ 96     # . epilog
+ 97     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+ 98     5d/pop-to-ebp
+ 99     c3/return
+100 
+101 test-has-metadata-true:
+102     # . prolog
+103     55/push-ebp
+104     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+105     # (eax..ecx) = "ab/imm32"
+106     b8/copy-to-eax  "ab/imm32"/imm32
+107     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+108     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+109     05/add-to-eax  4/imm32
+110     # var in/esi : (address slice) = {eax, ecx}
+111     51/push-ecx
+112     50/push-eax
+113     89/copy                         3/mod/direct    6/rm32/esi    .           .             .           4/r32/esp   .               .                 # copy esp to esi
+114     # eax = has-metadata?(esi, "imm32")
+115     # . . push args
+116     68/push  "imm32"/imm32
+117     56/push-esi
+118     # . . call
+119     e8/call  has-metadata?/disp32
+120     # . . discard args
+121     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+122     # check-ints-equal(eax, 1, msg)
+123     # . . push args
+124     68/push  "F - test-has-metadata-true"/imm32
+125     68/push  1/imm32/true
+126     50/push-eax
+127     # . . call
+128     e8/call  check-ints-equal/disp32
+129     # . . discard args
+130     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+131     # . epilog
+132     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+133     5d/pop-to-ebp
+134     c3/return
+135 
+136 test-has-metadata-false:
+137     # . prolog
+138     55/push-ebp
+139     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+140     # (eax..ecx) = "ab/c"
+141     b8/copy-to-eax  "ab/c"/imm32
+142     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+143     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+144     05/add-to-eax  4/imm32
+145     # var in/esi : (address slice) = {eax, ecx}
+146     51/push-ecx
+147     50/push-eax
+148     89/copy                         3/mod/direct    6/rm32/esi    .           .             .           4/r32/esp   .               .                 # copy esp to esi
+149     # eax = has-metadata?(esi, "d")
+150     # . . push args
+151     68/push  "d"/imm32
+152     56/push-esi
+153     # . . call
+154     e8/call  has-metadata?/disp32
+155     # . . discard args
+156     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+157     # check-ints-equal(eax, 0, msg)
+158     # . . push args
+159     68/push  "F - test-has-metadata-false"/imm32
+160     68/push  0/imm32/false
+161     50/push-eax
+162     # . . call
+163     e8/call  check-ints-equal/disp32
+164     # . . discard args
+165     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+166     # . epilog
+167     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+168     5d/pop-to-ebp
+169     c3/return
+170 
+171 test-has-metadata-ignore-name:
+172     # . prolog
+173     55/push-ebp
+174     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+175     # (eax..ecx) = "a/b"
+176     b8/copy-to-eax  "a/b"/imm32
+177     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+178     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+179     05/add-to-eax  4/imm32
+180     # var in/esi : (address slice) = {eax, ecx}
+181     51/push-ecx
+182     50/push-eax
+183     89/copy                         3/mod/direct    6/rm32/esi    .           .             .           4/r32/esp   .               .                 # copy esp to esi
+184     # eax = has-metadata?(esi, "a")
+185     # . . push args
+186     68/push  "a"/imm32
+187     56/push-esi
+188     # . . call
+189     e8/call  has-metadata?/disp32
+190     # . . discard args
+191     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+192     # check-ints-equal(eax, 0, msg)
+193     # . . push args
+194     68/push  "F - test-has-metadata-ignore-name"/imm32
+195     68/push  0/imm32/false
+196     50/push-eax
+197     # . . call
+198     e8/call  check-ints-equal/disp32
+199     # . . discard args
+200     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+201     # . epilog
+202     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+203     5d/pop-to-ebp
+204     c3/return
+205 
+206 test-has-metadata-multiple-true:
+207     # . prolog
+208     55/push-ebp
+209     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+210     # (eax..ecx) = "a/b/c"
+211     b8/copy-to-eax  "a/b/c"/imm32
+212     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+213     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+214     05/add-to-eax  4/imm32
+215     # var in/esi : (address slice) = {eax, ecx}
+216     51/push-ecx
+217     50/push-eax
+218     89/copy                         3/mod/direct    6/rm32/esi    .           .             .           4/r32/esp   .               .                 # copy esp to esi
+219     # eax = has-metadata?(esi, "c")
+220     # . . push args
+221     68/push  "c"/imm32
+222     56/push-esi
+223     # . . call
+224     e8/call  has-metadata?/disp32
+225     # . . discard args
+226     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+227     # check-ints-equal(eax, 1, msg)
+228     # . . push args
+229     68/push  "F - test-has-metadata-multiple-true"/imm32
+230     68/push  1/imm32/true
+231     50/push-eax
+232     # . . call
+233     e8/call  check-ints-equal/disp32
+234     # . . discard args
+235     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+236     # . epilog
+237     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+238     5d/pop-to-ebp
+239     c3/return
+240 
+241 test-has-metadata-multiple-false:
+242     # . prolog
+243     55/push-ebp
+244     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+245     # (eax..ecx) = "a/b/c"
+246     b8/copy-to-eax  "a/b/c"/imm32
+247     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+248     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+249     05/add-to-eax  4/imm32
+250     # var in/esi : (address slice) = {eax, ecx}
+251     51/push-ecx
+252     50/push-eax
+253     89/copy                         3/mod/direct    6/rm32/esi    .           .             .           4/r32/esp   .               .                 # copy esp to esi
+254     # eax = has-metadata?(esi, "d")
+255     # . . push args
+256     68/push  "d"/imm32
+257     56/push-esi
+258     # . . call
+259     e8/call  has-metadata?/disp32
+260     # . . discard args
+261     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
+262     # check-ints-equal(eax, 0, msg)
+263     # . . push args
+264     68/push  "F - test-has-metadata-multiple-false"/imm32
+265     68/push  0/imm32/false
+266     50/push-eax
+267     # . . call
+268     e8/call  check-ints-equal/disp32
+269     # . . discard args
+270     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+271     # . epilog
+272     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+273     5d/pop-to-ebp
+274     c3/return
+275 
+276 # conditions for 'valid' names that are not at risk of looking like hex numbers
+277 # keep in sync with the rules in labels.cc
+278 #: - if it starts with a digit, it's treated as a number. If it can't be
+279 #:   parsed as hex it will raise an error.
+280 #: - if it starts with '-' it's treated as a number.
+281 #: - if it starts with '0x' it's treated as a number. (redundant)
+282 #: - if it's two characters long, it can't be a name. Either it's a hex
+283 #:   byte, or it raises an error.
+284 is-valid-name?:  # in : (address slice) -> eax : boolean
+285     # . prolog
+286     55/push-ebp
+287     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+288     # . save registers
+289     51/push-ecx
+290     56/push-esi
+291     # esi = in
+292     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
+293     # start/ecx = in->start
+294     8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # copy *esi to ecx
+295     # end/eax = in->end
+296     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           0/r32/eax   4/disp8         .                 # copy *(esi+4) to eax
+297 $is-valid-name?:check0:
+298     # if (start >= end) return false
+299     39/compare                      3/mod/direct    1/rm32/ecx    .           .             .           0/r32/eax   .               .                 # compare ecx with eax
+300     73/jump-if-greater-or-equal-unsigned  $is-valid-name?:false/disp8
+301 $is-valid-name?:check1:
+302     # eax -= ecx
+303     29/subtract                     3/mod/direct    0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # subtract ecx from eax
+304     # if (eax == 2) return false
+305     3d/compare-eax-and  2/imm32
+306     74/jump-if-equal  $is-valid-name?:false/disp8
+307 $is-valid-name?:check2:
+308     # c/eax = *ecx
+309     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
+310     8a/copy-byte                    0/mod/indirect  1/rm32/ecx    .           .             .           0/r32/AL    .               .                 # copy byte at *ecx to AL
+311     # if (c == "-") return false
+312     3d/compare-eax-and  2d/imm32/-
+313     74/jump-if-equal  $is-valid-name?:false/disp8
+314 $is-valid-name?:check3a:
+315     # if (c < "0") return true
+316     3d/compare-eax-with  30/imm32/0
+317     7c/jump-if-lesser  $is-valid-name?:true/disp8
+318 $is-valid-name?:check3b:
+319     # if (c > "9") return true
+320     3d/compare-eax-with  39/imm32/9
+321     7f/jump-if-greater  $is-valid-name?:true/disp8
+322 $is-valid-name?:false:
+323     # return false
+324     b8/copy-to-eax  0/imm32/false
+325     eb/jump  $is-valid-name?:end/disp8
+326 $is-valid-name?:true:
+327     # return true
+328     b8/copy-to-eax  1/imm32/true
+329 $is-valid-name?:end:
+330     # . restore registers
+331     5e/pop-to-esi
+332     59/pop-to-ecx
+333     # . epilog
+334     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+335     5d/pop-to-ebp
+336     c3/return
+337 
+338 test-is-valid-name-digit-prefix:
+339     # . prolog
+340     55/push-ebp
+341     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+342     # (eax..ecx) = "34"
+343     b8/copy-to-eax  "34"/imm32
+344     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+345     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+346     05/add-to-eax  4/imm32
+347     # var slice/ecx = {eax, ecx}
+348     51/push-ecx
+349     50/push-eax
+350     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+351     # eax = is-valid-name?(slice)
+352     # . . push args
+353     51/push-ecx
+354     # . . call
+355     e8/call  is-valid-name?/disp32
+356     # . . discard args
+357     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+358     # check-ints-equal(eax, 0, msg)
+359     # . . push args
+360     68/push  "F - test-is-valid-name-digit-prefix"/imm32
+361     68/push  0/imm32/false
+362     50/push-eax
+363     # . . call
+364     e8/call  check-ints-equal/disp32
+365     # . . discard args
+366     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+367     # . epilog
+368     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+369     5d/pop-to-ebp
+370     c3/return
+371 
+372 test-is-valid-name-negative-prefix:
+373     # . prolog
+374     55/push-ebp
+375     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+376     # (eax..ecx) = "-0x34"
+377     b8/copy-to-eax  "-0x34"/imm32
+378     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+379     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+380     05/add-to-eax  4/imm32
+381     # var slice/ecx = {eax, ecx}
+382     51/push-ecx
+383     50/push-eax
+384     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+385     # eax = is-valid-name?(slice)
+386     # . . push args
+387     51/push-ecx
+388     # . . call
+389     e8/call  is-valid-name?/disp32
+390     # . . discard args
+391     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+392     # check-ints-equal(eax, 0, msg)
+393     # . . push args
+394     68/push  "F - test-is-valid-name-negative-prefix"/imm32
+395     68/push  0/imm32/false
+396     50/push-eax
+397     # . . call
+398     e8/call  check-ints-equal/disp32
+399     # . . discard args
+400     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+401     # . epilog
+402     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+403     5d/pop-to-ebp
+404     c3/return
+405 
+406 test-is-valid-name-0x-prefix:
+407     # . prolog
+408     55/push-ebp
+409     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+410     # (eax..ecx) = "0x34"
+411     b8/copy-to-eax  "0x34"/imm32
+412     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+413     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+414     05/add-to-eax  4/imm32
+415     # var slice/ecx = {eax, ecx}
+416     51/push-ecx
+417     50/push-eax
+418     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+419     # eax = is-valid-name?(slice)
+420     # . . push args
+421     51/push-ecx
+422     # . . call
+423     e8/call  is-valid-name?/disp32
+424     # . . discard args
+425     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+426     # check-ints-equal(eax, 0, msg)
+427     # . . push args
+428     68/push  "F - test-is-valid-name-0x-prefix"/imm32
+429     68/push  0/imm32/false
+430     50/push-eax
+431     # . . call
+432     e8/call  check-ints-equal/disp32
+433     # . . discard args
+434     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+435     # . epilog
+436     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+437     5d/pop-to-ebp
+438     c3/return
+439 
+440 test-is-valid-name-starts-with-pre-digit:
+441     # . prolog
+442     55/push-ebp
+443     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+444     # (eax..ecx) = "/03"
+445     b8/copy-to-eax  "/03"/imm32
+446     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+447     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+448     05/add-to-eax  4/imm32
+449     # var slice/ecx = {eax, ecx}
+450     51/push-ecx
+451     50/push-eax
+452     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+453     # eax = is-valid-name?(slice)
+454     # . . push args
+455     51/push-ecx
+456     # . . call
+457     e8/call  is-valid-name?/disp32
+458     # . . discard args
+459     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+460     # check-ints-equal(eax, 1, msg)
+461     # . . push args
+462     68/push  "F - test-is-valid-name-starts-with-pre-digit"/imm32
+463     68/push  1/imm32/true
+464     50/push-eax
+465     # . . call
+466     e8/call  check-ints-equal/disp32
+467     # . . discard args
+468     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+469     # . epilog
+470     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+471     5d/pop-to-ebp
+472     c3/return
+473 
+474 test-is-valid-name-starts-with-post-digit:
+475     # . prolog
+476     55/push-ebp
+477     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+478     # (eax..ecx) = "q34"
+479     b8/copy-to-eax  "q34"/imm32
+480     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+481     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+482     05/add-to-eax  4/imm32
+483     # var slice/ecx = {eax, ecx}
+484     51/push-ecx
+485     50/push-eax
+486     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+487     # eax = is-valid-name?(slice)
+488     # . . push args
+489     51/push-ecx
+490     # . . call
+491     e8/call  is-valid-name?/disp32
+492     # . . discard args
+493     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+494     # check-ints-equal(eax, 1, msg)
+495     # . . push args
+496     68/push  "F - test-is-valid-name-starts-with-post-digit"/imm32
+497     68/push  1/imm32/true
+498     50/push-eax
+499     # . . call
+500     e8/call  check-ints-equal/disp32
+501     # . . discard args
+502     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+503     # . epilog
+504     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+505     5d/pop-to-ebp
+506     c3/return
+507 
+508 test-is-valid-name-starts-with-digit:
+509     # . prolog
+510     55/push-ebp
+511     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+512     # (eax..ecx) = "0x34"
+513     b8/copy-to-eax  "0x34"/imm32
+514     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+515     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+516     05/add-to-eax  4/imm32
+517     # var slice/ecx = {eax, ecx}
+518     51/push-ecx
+519     50/push-eax
+520     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+521     # eax = is-valid-name?(slice)
+522     # . . push args
+523     51/push-ecx
+524     # . . call
+525     e8/call  is-valid-name?/disp32
+526     # . . discard args
+527     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+528     # check-ints-equal(eax, 0, msg)
+529     # . . push args
+530     68/push  "F - test-is-valid-name-starts-with-digit"/imm32
+531     68/push  0/imm32/false
+532     50/push-eax
+533     # . . call
+534     e8/call  check-ints-equal/disp32
+535     # . . discard args
+536     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+537     # . epilog
+538     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+539     5d/pop-to-ebp
+540     c3/return
+541 
+542 is-label?: # word : (address slice) -> eax : boolean
+543     # . prolog
+544     55/push-ebp
+545     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+546     # . save registers
+547     51/push-ecx
+548     # ecx = word
+549     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           1/r32/ecx   8/disp8         .                 # copy *(ebp+8) to ecx
+550     # ecx = word->end
+551     8b/copy                         1/mod/*+disp8   1/rm32/ecx    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(ecx+4) to ecx
+552     # return *(word->end - 1) == ':'
+553     # . eax = 0
+554     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
+555     # . eax = *((char *) word->end - 1)
+556     8a/copy-byte                    1/mod/*+disp8   1/rm32/ecx    .           .             .           0/r32/AL    -1/disp8         .                 # copy byte at *(ecx-1) to AL
+557     # . return (eax == ':')
+558     3d/compare-eax-and  0x3a/imm32/colon
+559     b8/copy-to-eax  1/imm32/true
+560     74/jump-if-equal  $is-label?:end/disp8
+561     b8/copy-to-eax  0/imm32/false
+562 $is-label?:end:
+563     # . restore registers
+564     59/pop-to-ecx
+565     # . epilog
+566     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+567     5d/pop-to-ebp
+568     c3/return
+569 
+570 test-is-label?:
+571     # . prolog
+572     55/push-ebp
+573     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
+574 $test-is-label?:true:
+575     # (eax..ecx) = "AAA:"
+576     b8/copy-to-eax  "AAA:"/imm32
+577     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+578     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+579     05/add-to-eax  4/imm32
+580     # var slice/ecx = {eax, ecx}
+581     51/push-ecx
+582     50/push-eax
+583     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+584     # is-label?(slice/ecx)
+585     # . . push args
+586     51/push-ecx
+587     # . . call
+588     e8/call  is-label?/disp32
+589     # . . discard args
+590     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+591     # check-ints-equal(eax, 1, msg)
+592     # . . push args
+593     68/push  "F - test-is-label?:true"/imm32
+594     68/push  1/imm32
+595     50/push-eax
+596     # . . call
+597     e8/call  check-ints-equal/disp32
+598     # . . discard args
+599     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+600 $test-is-label?:false:
+601     # (eax..ecx) = "AAA"
+602     b8/copy-to-eax  "AAA"/imm32
+603     8b/copy                         0/mod/indirect  0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # copy *eax to ecx
+604     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    0/base/eax  1/index/ecx   .           1/r32/ecx   4/disp8         .                 # copy eax+ecx+4 to ecx
+605     05/add-to-eax  4/imm32
+606     # var slice/ecx = {eax, ecx}
+607     51/push-ecx
+608     50/push-eax
+609     89/copy                         3/mod/direct    1/rm32/ecx    .           .             .           4/r32/esp   .               .                 # copy esp to ecx
+610     # is-label?(slice/ecx)
+611     # . . push args
+612     51/push-ecx
+613     # . . call
+614     e8/call  is-label?/disp32
+615     # . . discard args
+616     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
+617     # check-ints-equal(eax, 0, msg)
+618     # . . push args
+619     68/push  "F - test-is-label?:false"/imm32
+620     68/push  0/imm32
+621     50/push-eax
+622     # . . call
+623     e8/call  check-ints-equal/disp32
+624     # . . discard args
+625     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
+626     # . epilog
+627     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
+628     5d/pop-to-ebp
+629     c3/return
+630 
+631 # . . vim:nowrap:textwidth=0
+
+ + + -- cgit 1.4.1-2-gfad0