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