From 695f9bf8d0a7d0a871b8ab75270ceb29715d9be3 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Thu, 25 Jul 2019 00:08:23 -0700 Subject: 5468 --- html/subx/067parse-hex.subx.html | 938 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 938 insertions(+) create mode 100644 html/subx/067parse-hex.subx.html (limited to 'html/subx/067parse-hex.subx.html') diff --git a/html/subx/067parse-hex.subx.html b/html/subx/067parse-hex.subx.html new file mode 100644 index 00000000..dd7e5d9e --- /dev/null +++ b/html/subx/067parse-hex.subx.html @@ -0,0 +1,938 @@ + + + + +Mu - subx/067parse-hex.subx + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/subx/067parse-hex.subx +
+  1 # some utilities for converting numbers from hex
+  2 # lowercase letters only for now
+  3 
+  4 == code
+  5 #   instruction                     effective address                                                   register    displacement    immediate
+  6 # . op          subop               mod             rm32          base        index         scale       r32
+  7 # . 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
+  8 
+  9 is-hex-int?:  # in : (address slice) -> EAX : boolean
+ 10     # . prolog
+ 11     55/push-EBP
+ 12     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+ 13     # . save registers
+ 14     51/push-ECX
+ 15     52/push-EDX
+ 16     53/push-EBX
+ 17     # ECX = s
+ 18     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
+ 19     # EDX = s->end
+ 20     8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           2/r32/EDX   4/disp8         .                 # copy *(ECX+4) to EDX
+ 21     # curr/ECX = s->start
+ 22     8b/copy                         0/mod/indirect  1/rm32/ECX    .           .             .           1/r32/ECX   .               .                 # copy *ECX to ECX
+ 23     # if s is empty return false
+ 24     b8/copy-to-EAX  0/imm32/false
+ 25     39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
+ 26     73/jump-if-greater-or-equal-unsigned  $is-hex-int?:end/disp8
+ 27     # skip past leading '-'
+ 28     # . if (*curr == '-') ++curr
+ 29     31/xor                          3/mod/direct    3/rm32/EBX    .           .             .           3/r32/EBX   .               .                 # clear EBX
+ 30     8a/copy-byte                    0/mod/indirect  1/rm32/ECX    .           .             .           3/r32/BL    .               .                 # copy byte at *ECX to BL
+ 31     81          7/subop/compare     3/mod/direct    3/rm32/EBX    .           .             .           .           .               0x2d/imm32/-      # compare EBX
+ 32     75/jump-if-not-equal  $is-hex-int?:initial-0/disp8
+ 33     # . ++curr
+ 34     41/increment-ECX
+ 35     # skip past leading '0x'
+ 36 $is-hex-int?:initial-0:
+ 37     # . if (*curr != '0') jump to loop
+ 38     31/xor                          3/mod/direct    3/rm32/EBX    .           .             .           3/r32/EBX   .               .                 # clear EBX
+ 39     8a/copy-byte                    0/mod/indirect  1/rm32/ECX    .           .             .           3/r32/BL    .               .                 # copy byte at *ECX to BL
+ 40     81          7/subop/compare     3/mod/direct    3/rm32/EBX    .           .             .           .           .               0x30/imm32/0      # compare EBX
+ 41     75/jump-if-not-equal  $is-hex-int?:loop/disp8
+ 42     # . ++curr
+ 43     41/increment-ECX
+ 44 $is-hex-int?:initial-0x:
+ 45     # . if (curr >= in->end) return true
+ 46     39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
+ 47     73/jump-if-greater-or-equal-unsigned  $is-hex-int?:true/disp8
+ 48     # . if (*curr != 'x') jump to loop  # the previous '0' is still valid so doesn't need to be checked again
+ 49     31/xor                          3/mod/direct    3/rm32/EBX    .           .             .           3/r32/EBX   .               .                 # clear EBX
+ 50     8a/copy-byte                    0/mod/indirect  1/rm32/ECX    .           .             .           3/r32/BL    .               .                 # copy byte at *ECX to BL
+ 51     81          7/subop/compare     3/mod/direct    3/rm32/EBX    .           .             .           .           .               0x78/imm32/x      # compare EBX
+ 52     75/jump-if-not-equal  $is-hex-int?:loop/disp8
+ 53     # . ++curr
+ 54     41/increment-ECX
+ 55 $is-hex-int?:loop:
+ 56     # if (curr >= in->end) return true
+ 57     39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
+ 58     73/jump-if-greater-or-equal-unsigned  $is-hex-int?:true/disp8
+ 59     # EAX = is-hex-digit?(*curr)
+ 60     # . . push args
+ 61     8a/copy-byte                    0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/AL    .               .                 # copy byte at *ECX to AL
+ 62     50/push-EAX
+ 63     # . . call
+ 64     e8/call  is-hex-digit?/disp32
+ 65     # . . discard args
+ 66     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+ 67     # if (EAX == false) return false
+ 68     3d/compare-EAX-and  0/imm32
+ 69     74/jump-if-equal  $is-hex-int?:end/disp8
+ 70     # ++curr
+ 71     41/increment-ECX
+ 72     # loop
+ 73     eb/jump  $is-hex-int?:loop/disp8
+ 74 $is-hex-int?:true:
+ 75     # return true
+ 76     b8/copy-to-EAX  1/imm32/true
+ 77 $is-hex-int?:end:
+ 78     # . restore registers
+ 79     5b/pop-to-EBX
+ 80     5a/pop-to-EDX
+ 81     59/pop-to-ECX
+ 82     # . epilog
+ 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-is-hex-int:
+ 88     # . prolog
+ 89     55/push-EBP
+ 90     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+ 91     # (EAX..ECX) = "34"
+ 92     b8/copy-to-EAX  "34"/imm32
+ 93     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+ 94     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
+ 95     05/add-to-EAX  4/imm32
+ 96     # var slice/ECX = {EAX, ECX}
+ 97     51/push-ECX
+ 98     50/push-EAX
+ 99     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+100     # EAX = is-hex-int?(slice)
+101     # . . push args
+102     51/push-ECX
+103     # . . call
+104     e8/call  is-hex-int?/disp32
+105     # . . discard args
+106     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+107     # check-ints-equal(EAX, 1, msg)
+108     # . . push args
+109     68/push  "F - test-is-hex-int"/imm32
+110     68/push  1/imm32/true
+111     50/push-EAX
+112     # . . call
+113     e8/call  check-ints-equal/disp32
+114     # . . discard args
+115     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+116     # . epilog
+117     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+118     5d/pop-to-EBP
+119     c3/return
+120 
+121 test-is-hex-int-handles-letters:
+122     # . prolog
+123     55/push-EBP
+124     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+125     # (EAX..ECX) = "34a"
+126     b8/copy-to-EAX  "34a"/imm32
+127     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+128     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
+129     05/add-to-EAX  4/imm32
+130     # var slice/ECX = {EAX, ECX}
+131     51/push-ECX
+132     50/push-EAX
+133     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+134     # EAX = is-hex-int?(slice)
+135     # . . push args
+136     51/push-ECX
+137     # . . call
+138     e8/call  is-hex-int?/disp32
+139     # . . discard args
+140     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+141     # check-ints-equal(EAX, 1, msg)
+142     # . . push args
+143     68/push  "F - test-is-hex-int-handles-letters"/imm32
+144     68/push  1/imm32/true
+145     50/push-EAX
+146     # . . call
+147     e8/call  check-ints-equal/disp32
+148     # . . discard args
+149     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+150     # . epilog
+151     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+152     5d/pop-to-EBP
+153     c3/return
+154 
+155 test-is-hex-int-with-trailing-char:
+156     # . prolog
+157     55/push-EBP
+158     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+159     # (EAX..ECX) = "34q"
+160     b8/copy-to-EAX  "34q"/imm32
+161     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+162     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
+163     05/add-to-EAX  4/imm32
+164     # var slice/ECX = {EAX, ECX}
+165     51/push-ECX
+166     50/push-EAX
+167     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+168     # EAX = is-hex-int?(slice)
+169     # . . push args
+170     51/push-ECX
+171     # . . call
+172     e8/call  is-hex-int?/disp32
+173     # . . discard args
+174     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+175     # check-ints-equal(EAX, 0, msg)
+176     # . . push args
+177     68/push  "F - test-is-hex-int-with-trailing-char"/imm32
+178     68/push  0/imm32/false
+179     50/push-EAX
+180     # . . call
+181     e8/call  check-ints-equal/disp32
+182     # . . discard args
+183     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+184     # . epilog
+185     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+186     5d/pop-to-EBP
+187     c3/return
+188 
+189 test-is-hex-int-with-leading-char:
+190     # . prolog
+191     55/push-EBP
+192     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+193     # (EAX..ECX) = "q34"
+194     b8/copy-to-EAX  "q34"/imm32
+195     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+196     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
+197     05/add-to-EAX  4/imm32
+198     # var slice/ECX = {EAX, ECX}
+199     51/push-ECX
+200     50/push-EAX
+201     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+202     # EAX = is-hex-int?(slice)
+203     # . . push args
+204     51/push-ECX
+205     # . . call
+206     e8/call  is-hex-int?/disp32
+207     # . . discard args
+208     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+209     # check-ints-equal(EAX, 0, msg)
+210     # . . push args
+211     68/push  "F - test-is-hex-int-with-leading-char"/imm32
+212     68/push  0/imm32/false
+213     50/push-EAX
+214     # . . call
+215     e8/call  check-ints-equal/disp32
+216     # . . discard args
+217     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+218     # . epilog
+219     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+220     5d/pop-to-EBP
+221     c3/return
+222 
+223 test-is-hex-int-empty:
+224     # . prolog
+225     55/push-EBP
+226     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+227     # var slice/ECX = ""
+228     68/push  0/imm32
+229     68/push  0/imm32
+230     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+231     # EAX = is-hex-int?(slice)
+232     # . . push args
+233     51/push-ECX
+234     # . . call
+235     e8/call  is-hex-int?/disp32
+236     # . . discard args
+237     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+238     # check-ints-equal(EAX, 0, msg)
+239     # . . push args
+240     68/push  "F - test-is-hex-int-empty"/imm32
+241     68/push  0/imm32/false
+242     50/push-EAX
+243     # . . call
+244     e8/call  check-ints-equal/disp32
+245     # . . discard args
+246     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+247     # . epilog
+248     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+249     5d/pop-to-EBP
+250     c3/return
+251 
+252 test-is-hex-int-handles-0x-prefix:
+253     # . prolog
+254     55/push-EBP
+255     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+256     # (EAX..ECX) = "0x3a"
+257     b8/copy-to-EAX  "0x3a"/imm32
+258     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+259     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
+260     05/add-to-EAX  4/imm32
+261     # var slice/ECX = {EAX, ECX}
+262     51/push-ECX
+263     50/push-EAX
+264     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+265     # EAX = is-hex-int?(slice)
+266     # . . push args
+267     51/push-ECX
+268     # . . call
+269     e8/call  is-hex-int?/disp32
+270     # . . discard args
+271     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+272     # check-ints-equal(EAX, 1, msg)
+273     # . . push args
+274     68/push  "F - test-is-hex-int-handles-0x-prefix"/imm32
+275     68/push  1/imm32/true
+276     50/push-EAX
+277     # . . call
+278     e8/call  check-ints-equal/disp32
+279     # . . discard args
+280     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+281     # . epilog
+282     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+283     5d/pop-to-EBP
+284     c3/return
+285 
+286 test-is-hex-int-handles-negative:
+287     # . prolog
+288     55/push-EBP
+289     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+290     # (EAX..ECX) = "-34a"
+291     b8/copy-to-EAX  "-34a"/imm32
+292     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+293     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
+294     05/add-to-EAX  4/imm32
+295     # var slice/ECX = {EAX, ECX}
+296     51/push-ECX
+297     50/push-EAX
+298     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+299     # EAX = is-hex-int?(slice)
+300     # . . push args
+301     51/push-ECX
+302     # . . call
+303     e8/call  is-hex-int?/disp32
+304     # . . discard args
+305     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+306     # check-ints-equal(EAX, 1, msg)
+307     # . . push args
+308     68/push  "F - test-is-hex-int-handles-negative"/imm32
+309     68/push  1/imm32/true
+310     50/push-EAX
+311     # . . call
+312     e8/call  check-ints-equal/disp32
+313     # . . discard args
+314     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+315     # . epilog
+316     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+317     5d/pop-to-EBP
+318     c3/return
+319 
+320 test-is-hex-int-handles-negative-0x-prefix:
+321     # . prolog
+322     55/push-EBP
+323     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+324     # (EAX..ECX) = "-0x3a"
+325     b8/copy-to-EAX  "-0x3a"/imm32
+326     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+327     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
+328     05/add-to-EAX  4/imm32
+329     # var slice/ECX = {EAX, ECX}
+330     51/push-ECX
+331     50/push-EAX
+332     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+333     # EAX = is-hex-int?(slice)
+334     # . . push args
+335     51/push-ECX
+336     # . . call
+337     e8/call  is-hex-int?/disp32
+338     # . . discard args
+339     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+340     # check-ints-equal(EAX, 1, msg)
+341     # . . push args
+342     68/push  "F - test-is-hex-int-handles-negative-0x-prefix"/imm32
+343     68/push  1/imm32/true
+344     50/push-EAX
+345     # . . call
+346     e8/call  check-ints-equal/disp32
+347     # . . discard args
+348     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+349     # . epilog
+350     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+351     5d/pop-to-EBP
+352     c3/return
+353 
+354 parse-hex-int:  # in : (address slice) -> result/EAX
+355     # . prolog
+356     55/push-EBP
+357     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+358     # . save registers
+359     51/push-ECX
+360     52/push-EDX
+361     53/push-EBX
+362     56/push-ESI
+363     # result/EBX = 0
+364     31/xor                          3/mod/direct    3/rm32/EBX    .           .             .           3/r32/EBX   .               .                 # clear EBX
+365     # ECX = s
+366     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
+367     # EDX = s->end
+368     8b/copy                         1/mod/*+disp8   1/rm32/ECX    .           .             .           2/r32/EDX   4/disp8         .                 # copy *(ECX+4) to EDX
+369     # curr/ECX = s->start
+370     8b/copy                         0/mod/indirect  1/rm32/ECX    .           .             .           1/r32/ECX   .               .                 # copy *ECX to ECX
+371     # negate?/ESI = false
+372     31/xor                          3/mod/direct    6/rm32/ESI    .           .             .           6/r32/ESI   .               .                 # clear ESI
+373 $parse-hex-int:negative:
+374     # . if (*curr == '-') negate = true
+375     31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
+376     8a/copy-byte                    0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/AL    .               .                 # copy byte at *ECX to AL
+377     3d/compare-EAX-and  0x2d/imm32/-
+378     75/jump-if-not-equal  $parse-hex-int:initial-0/disp8
+379     # . ++curr
+380     41/increment-ECX
+381     # . negate = true
+382     be/copy-to-ESI  1/imm32/true
+383 $parse-hex-int:initial-0:
+384     # skip past leading '0x'
+385     # . if (*curr != '0') jump to loop
+386     8a/copy-byte                    0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/AL    .               .                 # copy byte at *ECX to AL
+387     3d/compare-EAX-and  0x30/imm32/0
+388     75/jump-if-not-equal  $parse-hex-int:loop/disp8
+389     # . ++curr
+390     41/increment-ECX
+391 $parse-hex-int:initial-0x:
+392     # . if (curr >= in->end) return result
+393     39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
+394     73/jump-if-greater-or-equal-unsigned  $parse-hex-int:end/disp8
+395     # . if (*curr != 'x') jump to loop  # the previous '0' is still valid so doesn't need to be checked again
+396     31/xor                          3/mod/direct    0/rm32/EAX    .           .             .           0/r32/EAX   .               .                 # clear EAX
+397     8a/copy-byte                    0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/AL    .               .                 # copy byte at *ECX to AL
+398     3d/compare-EAX-and  0x78/imm32/x
+399     75/jump-if-not-equal  $parse-hex-int:loop/disp8
+400     # . ++curr
+401     41/increment-ECX
+402 $parse-hex-int:loop:
+403     # if (curr >= in->end) break
+404     39/compare                      3/mod/direct    1/rm32/ECX    .           .             .           2/r32/EDX   .               .                 # compare ECX with EDX
+405     73/jump-if-greater-or-equal-unsigned  $parse-hex-int:negate/disp8
+406     # EAX = from-hex-char(*curr)
+407     # . . copy arg to EAX
+408     8a/copy-byte                    0/mod/indirect  1/rm32/ECX    .           .             .           0/r32/AL    .               .                 # copy byte at *ECX to AL
+409     # . . call
+410     e8/call  from-hex-char/disp32
+411     # result = result * 16 + EAX
+412     c1/shift    4/subop/left        3/mod/direct    3/rm32/EBX    .           .             .           .           .               4/imm8            # shift EBX left by 4 bits
+413     01/add                          3/mod/direct    3/rm32/EBX    .           .             .           0/r32/EAX   .               .                 # add EAX to EBX
+414     # ++curr
+415     41/increment-ECX
+416     # loop
+417     eb/jump  $parse-hex-int:loop/disp8
+418 $parse-hex-int:negate:
+419     81          7/subop/compare     3/mod/direct    6/rm32/ESI    .           .             .           .           .               0/imm32           # compare ESI
+420     74/jump-if-equal  $parse-hex-int:end/disp8
+421     f7          3/subop/negate      3/mod/direct    3/rm32/EBX    .           .             .           .           .               .                 # negate EBX
+422 $parse-hex-int:end:
+423     89/copy                         3/mod/direct    0/rm32/EAX    .           .             .           3/r32/EBX   .               .                 # copy EBX to EAX
+424     # . restore registers
+425     5e/pop-to-ESI
+426     5b/pop-to-EBX
+427     5a/pop-to-EDX
+428     59/pop-to-ECX
+429     # . epilog
+430     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+431     5d/pop-to-EBP
+432     c3/return
+433 
+434 test-parse-hex-int-single-digit:
+435     # . prolog
+436     55/push-EBP
+437     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+438     # (EAX..ECX) = "a"
+439     b8/copy-to-EAX  "a"/imm32
+440     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+441     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
+442     05/add-to-EAX  4/imm32
+443     # var slice/ECX = {EAX, ECX}
+444     51/push-ECX
+445     50/push-EAX
+446     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+447     # EAX = parse-hex-int(slice)
+448     # . . push args
+449     51/push-ECX
+450     # . . call
+451     e8/call  parse-hex-int/disp32
+452     # . . discard args
+453     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+454     # check-ints-equal(EAX, 0xa, msg)
+455     # . . push args
+456     68/push  "F - test-parse-hex-int-single-digit"/imm32
+457     68/push  0xa/imm32
+458     50/push-EAX
+459     # . . call
+460     e8/call  check-ints-equal/disp32
+461     # . . discard args
+462     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+463     # . epilog
+464     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+465     5d/pop-to-EBP
+466     c3/return
+467 
+468 test-parse-hex-int-multi-digit:
+469     # . prolog
+470     55/push-EBP
+471     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+472     # (EAX..ECX) = "34a"
+473     b8/copy-to-EAX  "34a"/imm32
+474     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+475     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
+476     05/add-to-EAX  4/imm32
+477     # var slice/ECX = {EAX, ECX}
+478     51/push-ECX
+479     50/push-EAX
+480     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+481     # EAX = parse-hex-int(slice)
+482     # . . push args
+483     51/push-ECX
+484     # . . call
+485     e8/call  parse-hex-int/disp32
+486     # . . discard args
+487     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+488     # check-ints-equal(EAX, 0x34a, msg)
+489     # . . push args
+490     68/push  "F - test-parse-hex-int-multi-digit"/imm32
+491     68/push  0x34a/imm32
+492     50/push-EAX
+493     # . . call
+494     e8/call  check-ints-equal/disp32
+495     # . . discard args
+496     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+497     # . epilog
+498     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+499     5d/pop-to-EBP
+500     c3/return
+501 
+502 test-parse-hex-int-0x-prefix:
+503     # . prolog
+504     55/push-EBP
+505     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+506     # (EAX..ECX) = "0x34"
+507     b8/copy-to-EAX  "0x34"/imm32
+508     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+509     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
+510     05/add-to-EAX  4/imm32
+511     # var slice/ECX = {EAX, ECX}
+512     51/push-ECX
+513     50/push-EAX
+514     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+515     # EAX = parse-hex-int(slice)
+516     # . . push args
+517     51/push-ECX
+518     # . . call
+519     e8/call  parse-hex-int/disp32
+520     # . . discard args
+521     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+522     # check-ints-equal(EAX, 0x34a, msg)
+523     # . . push args
+524     68/push  "F - test-parse-hex-int-0x-prefix"/imm32
+525     68/push  0x34/imm32
+526     50/push-EAX
+527     # . . call
+528     e8/call  check-ints-equal/disp32
+529     # . . discard args
+530     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+531     # . epilog
+532     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+533     5d/pop-to-EBP
+534     c3/return
+535 
+536 test-parse-hex-int-zero:
+537     # . prolog
+538     55/push-EBP
+539     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+540     # (EAX..ECX) = "0"
+541     b8/copy-to-EAX  "0"/imm32
+542     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+543     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
+544     05/add-to-EAX  4/imm32
+545     # var slice/ECX = {EAX, ECX}
+546     51/push-ECX
+547     50/push-EAX
+548     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+549     # EAX = parse-hex-int(slice)
+550     # . . push args
+551     51/push-ECX
+552     # . . call
+553     e8/call  parse-hex-int/disp32
+554     # . . discard args
+555     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+556     # check-ints-equal(EAX, 0x34a, msg)
+557     # . . push args
+558     68/push  "F - test-parse-hex-int-zero"/imm32
+559     68/push  0/imm32
+560     50/push-EAX
+561     # . . call
+562     e8/call  check-ints-equal/disp32
+563     # . . discard args
+564     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+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-parse-hex-int-0-prefix:
+571     # . prolog
+572     55/push-EBP
+573     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+574     # (EAX..ECX) = "03"
+575     b8/copy-to-EAX  "03"/imm32
+576     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+577     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
+578     05/add-to-EAX  4/imm32
+579     # var slice/ECX = {EAX, ECX}
+580     51/push-ECX
+581     50/push-EAX
+582     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+583     # EAX = parse-hex-int(slice)
+584     # . . push args
+585     51/push-ECX
+586     # . . call
+587     e8/call  parse-hex-int/disp32
+588     # . . discard args
+589     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+590     # check-ints-equal(EAX, 0x3, msg)
+591     # . . push args
+592     68/push  "F - test-parse-hex-int-0-prefix"/imm32
+593     68/push  0x3/imm32
+594     50/push-EAX
+595     # . . call
+596     e8/call  check-ints-equal/disp32
+597     # . . discard args
+598     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+599     # . epilog
+600     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+601     5d/pop-to-EBP
+602     c3/return
+603 
+604 test-parse-hex-int-negative:
+605     # . prolog
+606     55/push-EBP
+607     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+608     # (EAX..ECX) = "-03"
+609     b8/copy-to-EAX  "-03"/imm32
+610     8b/copy                         0/mod/indirect  0/rm32/EAX    .           .             .           1/r32/ECX   .               .                 # copy *EAX to ECX
+611     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
+612     05/add-to-EAX  4/imm32
+613     # var slice/ECX = {EAX, ECX}
+614     51/push-ECX
+615     50/push-EAX
+616     89/copy                         3/mod/direct    1/rm32/ECX    .           .             .           4/r32/ESP   .               .                 # copy ESP to ECX
+617     # EAX = parse-hex-int(slice)
+618     # . . push args
+619     51/push-ECX
+620     # . . call
+621     e8/call  parse-hex-int/disp32
+622     # . . discard args
+623     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+624     # check-ints-equal(EAX, 0xfffffffd, msg)
+625     # . . push args
+626     68/push  "F - test-parse-hex-int-negative"/imm32
+627     68/push  0xfffffffd/imm32
+628     50/push-EAX
+629     # . . call
+630     e8/call  check-ints-equal/disp32
+631     # . . discard args
+632     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+633     # . epilog
+634     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+635     5d/pop-to-EBP
+636     c3/return
+637 
+638 is-hex-digit?:  # c : byte -> EAX : boolean
+639     # . prolog
+640     55/push-EBP
+641     89/copy                         3/mod/direct    5/rm32/EBP    .           .             .           4/r32/ESP   .               .                 # copy ESP to EBP
+642     # . save registers
+643     51/push-ECX
+644     # ECX = c
+645     8b/copy                         1/mod/*+disp8   5/rm32/EBP    .           .             .           1/r32/ECX   8/disp8         .                 # copy *(EBP+8) to ECX
+646     # return false if c < '0'
+647     b8/copy-to-EAX  0/imm32/false
+648     81          7/subop/compare     3/mod/direct    1/rm32/ECX    .           .             .           .           .               0x30/imm32        # compare ECX
+649     7c/jump-if-lesser  $is-hex-digit?:end/disp8
+650     # return false if c > 'f'
+651     81          7/subop/compare     3/mod/direct    1/rm32/ECX    .           .             .           .           .               0x66/imm32        # compare ECX
+652     7f/jump-if-greater  $is-hex-digit?:end/disp8
+653     # return true if c <= '9'
+654     b8/copy-to-EAX  1/imm32/true
+655     81          7/subop/compare     3/mod/direct    1/rm32/ECX    .           .             .           .           .               0x39/imm32        # compare ECX
+656     7e/jump-if-lesser-or-equal  $is-hex-digit?:end/disp8
+657     # return true if c >= 'a'
+658     81          7/subop/compare     3/mod/direct    1/rm32/ECX    .           .             .           .           .               0x61/imm32        # compare ECX
+659     7d/jump-if-greater-or-equal  $is-hex-digit?:end/disp8
+660     # otherwise return false
+661     b8/copy-to-EAX  0/imm32/false
+662 $is-hex-digit?:end:
+663     # . restore registers
+664     59/pop-to-ECX
+665     # . epilog
+666     89/copy                         3/mod/direct    4/rm32/ESP    .           .             .           5/r32/EBP   .               .                 # copy EBP to ESP
+667     5d/pop-to-EBP
+668     c3/return
+669 
+670 test-hex-below-0:
+671     # EAX = is-hex-digit?(0x2f)
+672     # . . push args
+673     68/push  0x2f/imm32
+674     # . . call
+675     e8/call  is-hex-digit?/disp32
+676     # . . discard args
+677     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+678     # check-ints-equal(EAX, 0, msg)
+679     # . . push args
+680     68/push  "F - test-hex-below-0"/imm32
+681     68/push  0/imm32/false
+682     50/push-EAX
+683     # . . call
+684     e8/call  check-ints-equal/disp32
+685     # . . discard args
+686     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+687     c3/return
+688 
+689 test-hex-0-to-9:
+690     # EAX = is-hex-digit?(0x30)
+691     # . . push args
+692     68/push  0x30/imm32
+693     # . . call
+694     e8/call  is-hex-digit?/disp32
+695     # . . discard args
+696     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+697     # check-ints-equal(EAX, 1, msg)
+698     # . . push args
+699     68/push  "F - test-hex-at-0"/imm32
+700     68/push  1/imm32/true
+701     50/push-EAX
+702     # . . call
+703     e8/call  check-ints-equal/disp32
+704     # . . discard args
+705     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+706     # EAX = is-hex-digit?(0x39)
+707     # . . push args
+708     68/push  0x39/imm32
+709     # . . call
+710     e8/call  is-hex-digit?/disp32
+711     # . . discard args
+712     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+713     # check-ints-equal(EAX, 1, msg)
+714     # . . push args
+715     68/push  "F - test-hex-at-9"/imm32
+716     68/push  1/imm32/true
+717     50/push-EAX
+718     # . . call
+719     e8/call  check-ints-equal/disp32
+720     # . . discard args
+721     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+722     c3/return
+723 
+724 test-hex-above-9-to-a:
+725     # EAX = is-hex-digit?(0x3a)
+726     # . . push args
+727     68/push  0x3a/imm32
+728     # . . call
+729     e8/call  is-hex-digit?/disp32
+730     # . . discard args
+731     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+732     # check-ints-equal(EAX, 0, msg)
+733     # . . push args
+734     68/push  "F - test-hex-above-9-to-a"/imm32
+735     68/push  0/imm32/false
+736     50/push-EAX
+737     # . . call
+738     e8/call  check-ints-equal/disp32
+739     # . . discard args
+740     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+741     c3/return
+742 
+743 test-hex-a-to-f:
+744     # EAX = is-hex-digit?(0x61)
+745     # . . push args
+746     68/push  0x61/imm32
+747     # . . call
+748     e8/call  is-hex-digit?/disp32
+749     # . . discard args
+750     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+751     # check-ints-equal(EAX, 1, msg)
+752     # . . push args
+753     68/push  "F - test-hex-at-a"/imm32
+754     68/push  1/imm32/true
+755     50/push-EAX
+756     # . . call
+757     e8/call  check-ints-equal/disp32
+758     # . . discard args
+759     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+760     # EAX = is-hex-digit?(0x66)
+761     # . . push args
+762     68/push  0x66/imm32
+763     # . . call
+764     e8/call  is-hex-digit?/disp32
+765     # . . discard args
+766     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+767     # check-ints-equal(EAX, 1, msg)
+768     # . . push args
+769     68/push  "F - test-hex-at-f"/imm32
+770     68/push  1/imm32/true
+771     50/push-EAX
+772     # . . call
+773     e8/call  check-ints-equal/disp32
+774     # . . discard args
+775     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+776     c3/return
+777 
+778 test-hex-above-f:
+779     # EAX = is-hex-digit?(0x67)
+780     # . . push args
+781     68/push  0x67/imm32
+782     # . . call
+783     e8/call  is-hex-digit?/disp32
+784     # . . discard args
+785     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+786     # check-ints-equal(EAX, 0, msg)
+787     # . . push args
+788     68/push  "F - test-hex-above-f"/imm32
+789     68/push  0/imm32/false
+790     50/push-EAX
+791     # . . call
+792     e8/call  check-ints-equal/disp32
+793     # . . discard args
+794     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               0xc/imm32         # add to ESP
+795     c3/return
+796 
+797 from-hex-char:  # in/EAX : byte -> out/EAX : nibble
+798 $from-hex-char:check0:
+799     # if (EAX < '0') goto abort
+800     3d/compare-EAX-with  0x30/imm32/0
+801     7c/jump-if-lesser  $from-hex-char:abort/disp8
+802 $from-hex-char:check1:
+803     # if (EAX > 'f') goto abort
+804     3d/compare-EAX-with  0x66/imm32/f
+805     7f/jump-if-greater  $from-hex-char:abort/disp8
+806 $from-hex-char:check2:
+807     # if (EAX > '9') goto next check
+808     3d/compare-EAX-with  0x39/imm32/9
+809     7f/jump-if-greater  $from-hex-char:check3/disp8
+810 $from-hex-char:digit:
+811     # return EAX - '0'
+812     2d/subtract-from-EAX  0x30/imm32/0
+813     c3/return
+814 $from-hex-char:check3:
+815     # if (EAX < 'a') goto abort
+816     3d/compare-EAX-with  0x61/imm32/a
+817     7c/jump-if-lesser  $from-hex-char:abort/disp8
+818 $from-hex-char:letter:
+819     # return EAX - ('a'-10)
+820     2d/subtract-from-EAX  0x57/imm32/a-10
+821     c3/return
+822 
+823 $from-hex-char:abort:
+824     # . _write(2/stderr, error)
+825     # . . push args
+826     68/push  "invalid hex char: "/imm32
+827     68/push  2/imm32/stderr
+828     # . . call
+829     e8/call  _write/disp32
+830     # . . discard args
+831     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+832     # . clear-stream(Stderr+4)
+833     # . . save EAX
+834     50/push-EAX
+835     # . . push args
+836     b8/copy-to-EAX  Stderr/imm32
+837     05/add-to-EAX  4/imm32
+838     50/push-EAX
+839     # . . call
+840     e8/call  clear-stream/disp32
+841     # . . discard args
+842     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+843     # . . restore EAX
+844     58/pop-to-EAX
+845     # . print-int32-buffered(Stderr, EAX)
+846     # . . push args
+847     50/push-EAX
+848     68/push  Stderr/imm32
+849     # . . call
+850     e8/call  print-int32-buffered/disp32
+851     # . . discard args
+852     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+853     # . flush(Stderr)
+854     # . . push args
+855     68/push  Stderr/imm32
+856     # . . call
+857     e8/call  flush/disp32
+858     # . . discard args
+859     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               4/imm32           # add to ESP
+860     # . _write(2/stderr, "\n")
+861     # . . push args
+862     68/push  "\n"/imm32
+863     68/push  2/imm32/stderr
+864     # . . call
+865     e8/call  _write/disp32
+866     # . . discard args
+867     81          0/subop/add         3/mod/direct    4/rm32/ESP    .           .             .           .           .               8/imm32           # add to ESP
+868     # . syscall(exit, 1)
+869     bb/copy-to-EBX  1/imm32
+870     b8/copy-to-EAX  1/imm32/exit
+871     cd/syscall  0x80/imm8
+872     # never gets here
+873 
+874 # . . vim:nowrap:textwidth=0
+
+ + + -- cgit 1.4.1-2-gfad0