move comment to a clearer location
[mu.git] / 109stream-equal.subx
blob556afd91fa628b956fd803604fd8ed6b5834feae
1 # some primitives for checking stream contents
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
8 # compare all the data in a stream (ignoring the read pointer)
9 stream-data-equal?:  # f: (addr stream byte), s: (addr array byte) -> result/eax: boolean
10     # . prologue
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     56/push-esi
17     57/push-edi
18     # esi = f
19     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
20     # eax = f->write
21     8b/copy                         0/mod/indirect  6/rm32/esi    .           .             .           0/r32/eax   .               .                 # copy *esi to eax
22     # var maxf/edx: (addr byte) = &f->data[f->write]
23     8d/copy-address                 1/mod/*+disp8   4/rm32/sib    6/base/esi  0/index/eax   .           2/r32/edx   0xc/disp8       .                 # copy esi+eax+12 to edx
24     # var currf/esi: (addr byte) = f->data
25     81          0/subop/add         3/mod/direct    6/rm32/esi    .           .             .           .           .               0xc/imm32         # add to esi
26     # edi = s
27     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
28 $stream-data-equal?:compare-sizes:
29     # if (f->write != s->size) return false
30     39/compare                      0/mod/indirect  7/rm32/edi    .           .             .           0/r32/eax   .               .                 # compare *edi and eax
31     75/jump-if-!=  $stream-data-equal?:false/disp8
32     # var currs/edi: (addr byte) = s->data
33     81          0/subop/add         3/mod/direct    7/rm32/edi    .           .             .           .           .               4/imm32           # add to edi
34     # var eax: byte = 0
35     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
36     # var ecx: byte = 0
37     31/xor                          3/mod/direct    1/rm32/ecx    .           .             .           1/r32/ecx   .               .                 # clear ecx
38 $stream-data-equal?:loop:
39     # if (currf >= maxf) return true
40     39/compare                      3/mod/direct    6/rm32/esi    .           .             .           2/r32/edx   .               .                 # compare esi with edx
41     73/jump-if-addr>=  $stream-data-equal?:true/disp8
42     # AL = *currs
43     8a/copy-byte                    0/mod/indirect  6/rm32/esi    .           .             .           0/r32/AL    .               .                 # copy byte at *esi to AL
44     # CL = *curr
45     8a/copy-byte                    0/mod/indirect  7/rm32/edi    .           .             .           1/r32/CL    .               .                 # copy byte at *edi to CL
46     # if (eax != ecx) return false
47     39/compare                      3/mod/direct    0/rm32/eax    .           .             .           1/r32/ecx   .               .                 # compare eax and ecx
48     75/jump-if-!=  $stream-data-equal?:false/disp8
49     # ++f
50     46/increment-esi
51     # ++curr
52     47/increment-edi
53     eb/jump $stream-data-equal?:loop/disp8
54 $stream-data-equal?:false:
55     b8/copy-to-eax  0/imm32
56     eb/jump  $stream-data-equal?:end/disp8
57 $stream-data-equal?:true:
58     b8/copy-to-eax  1/imm32
59 $stream-data-equal?:end:
60     # . restore registers
61     5f/pop-to-edi
62     5e/pop-to-esi
63     5a/pop-to-edx
64     59/pop-to-ecx
65     # . epilogue
66     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
67     5d/pop-to-ebp
68     c3/return
70 test-stream-data-equal:
71     # . prologue
72     55/push-ebp
73     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
74     # clear-stream(_test-stream)
75     # . . push args
76     68/push  _test-stream/imm32
77     # . . call
78     e8/call  clear-stream/disp32
79     # . . discard args
80     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
81     # write(_test-stream, "Abc")
82     # . . push args
83     68/push  "Abc"/imm32
84     68/push  _test-stream/imm32
85     # . . call
86     e8/call  write/disp32
87     # . . discard args
88     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
89     # eax = stream-data-equal?(_test-stream, "Abc")
90     # . . push args
91     68/push  "Abc"/imm32
92     68/push  _test-stream/imm32
93     # . . call
94     e8/call  stream-data-equal?/disp32
95     # . . discard args
96     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
97     # check-ints-equal(eax, 1, msg)
98     # . . push args
99     68/push  "F - test-stream-data-equal"/imm32
100     68/push  1/imm32
101     50/push-eax
102     # . . call
103     e8/call  check-ints-equal/disp32
104     # . . discard args
105     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
106     # . epilogue
107     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
108     5d/pop-to-ebp
109     c3/return
111 test-stream-data-equal-2:
112     # . prologue
113     55/push-ebp
114     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
115     # clear-stream(_test-stream)
116     # . . push args
117     68/push  _test-stream/imm32
118     # . . call
119     e8/call  clear-stream/disp32
120     # . . discard args
121     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
122     # write(_test-stream, "Abc")
123     # . . push args
124     68/push  "Abc"/imm32
125     68/push  _test-stream/imm32
126     # . . call
127     e8/call  write/disp32
128     # . . discard args
129     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
130     # eax = stream-data-equal?(_test-stream, "Abd")
131     # . . push args
132     68/push  "Abd"/imm32
133     68/push  _test-stream/imm32
134     # . . call
135     e8/call  stream-data-equal?/disp32
136     # . . discard args
137     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
138     # check-ints-equal(eax, 0, msg)
139     # . . push args
140     68/push  "F - test-stream-data-equal-2"/imm32
141     68/push  0/imm32
142     50/push-eax
143     # . . call
144     e8/call  check-ints-equal/disp32
145     # . . discard args
146     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
147     # . epilogue
148     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
149     5d/pop-to-ebp
150     c3/return
152 test-stream-data-equal-size-check:
153     # . prologue
154     55/push-ebp
155     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
156     # clear-stream(_test-stream)
157     # . . push args
158     68/push  _test-stream/imm32
159     # . . call
160     e8/call  clear-stream/disp32
161     # . . discard args
162     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
163     # write(_test-stream, "Abc")
164     # . . push args
165     68/push  "Abc"/imm32
166     68/push  _test-stream/imm32
167     # . . call
168     e8/call  write/disp32
169     # . . discard args
170     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
171     # eax = stream-data-equal?(_test-stream, "Abcd")
172     # . . push args
173     68/push  "Abcd"/imm32
174     68/push  _test-stream/imm32
175     # . . call
176     e8/call  stream-data-equal?/disp32
177     # . . discard args
178     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
179     # check-ints-equal(eax, 0, msg)
180     # . . push args
181     68/push  "F - test-stream-data-equal-size-check"/imm32
182     68/push  0/imm32
183     50/push-eax
184     # . . call
185     e8/call  check-ints-equal/disp32
186     # . . discard args
187     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
188     # . epilogue
189     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
190     5d/pop-to-ebp
191     c3/return
193 # helper for tests
194 check-stream-equal:  # f: (addr stream byte), s: (addr array byte), msg: (addr array byte)
195     # . prologue
196     55/push-ebp
197     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
198     # . save registers
199     50/push-eax
200     # eax = stream-data-equal?(f, s)
201     # . . push args
202     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
203     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
204     # . . call
205     e8/call  stream-data-equal?/disp32
206     # . . discard args
207     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
208     # check-ints-equal(eax, 1, msg)
209     # . . push args
210     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0x10/disp8      .                 # push *(ebp+16)
211     68/push  1/imm32
212     50/push-eax
213     # . . call
214     e8/call  check-ints-equal/disp32
215     # . . discard args
216     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
217 $check-stream-equal:end:
218     # . restore registers
219     58/pop-to-eax
220     # . epilogue
221     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
222     5d/pop-to-ebp
223     c3/return
225 # scan the next line until newline starting from f->read and compare it with
226 # 's' (ignoring the trailing newline)
227 # on success, set f->read to after the next newline
228 # on failure, leave f->read unmodified
229 # this function is usually used only in tests, so we repeatedly write f->read
230 next-stream-line-equal?:  # f: (addr stream byte), s: (addr array byte) -> result/eax: boolean
231     # pseudocode:
232     #   currf = f->read  # bound: f->write
233     #   currs = 0  # bound: s->size
234     #   while true
235     #     if currf >= f->write
236     #       return currs >= s->size
237     #     if f[currf] == '\n'
238     #       ++currf
239     #       return currs >= s->size
240     #     if (currs >= s->size) return false  # the current line of f still has data to match
241     #     if (f[currf] != s[currs]) return false
242     #     ++currf
243     #     ++currs
244     #
245     # collapsing the two branches that can return true:
246     #   currf = f->read  # bound: f->write
247     #   currs = 0  # bound: s->size
248     #   while true
249     #     if (currf >= f->write) break
250     #     if (f[currf] == '\n') break
251     #     if (currs >= s->size) return false  # the current line of f still has data to match
252     #     if (f[currf] != s[currs]) return false
253     #     ++currf
254     #     ++currs
255     #   ++currf  # skip '\n'
256     #   return currs >= s->size
257     # Here the final `++currf` is sometimes unnecessary (if we're already at the end of the stream)
258     #
259     # registers:
260     #   f: esi
261     #   s: edi
262     #   currf: ecx
263     #   currs: edx
264     #   f[currf]: eax
265     #   s[currs]: ebx
266     #
267     # . prologue
268     55/push-ebp
269     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
270     # . save registers
271     51/push-ecx
272     52/push-edx
273     56/push-esi
274     57/push-edi
275     # esi = f
276     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           6/r32/esi   8/disp8         .                 # copy *(ebp+8) to esi
277     # var currf/ecx: int = f->read
278     8b/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy *(esi+4) to ecx
279     # edi = s
280     8b/copy                         1/mod/*+disp8   5/rm32/ebp    .           .             .           7/r32/edi   0xc/disp8       .                 # copy *(ebp+12) to edi
281     # var currs/edx: int = 0
282     31/xor                          3/mod/direct    2/rm32/edx    .           .             .           2/r32/edx   .               .                 # clear edx
283     # var c1/eax: byte = 0
284     31/xor                          3/mod/direct    0/rm32/eax    .           .             .           0/r32/eax   .               .                 # clear eax
285     # var c2/ebx: byte = 0
286     31/xor                          3/mod/direct    3/rm32/ebx    .           .             .           3/r32/ebx   .               .                 # clear ebx
287 $next-stream-line-equal?:loop:
288     # if (currf >= f->write) break
289     3b/compare                      0/mod/indirect  6/rm32/esi    .           .             .           1/r32/ecx   .               .                 # compare ecx with *esi
290     7d/jump-if->=  $next-stream-line-equal?:break/disp8
291     # c1 = f->data[f->read]
292     8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    6/base/esi  1/index/ecx   .           0/r32/AL    0xc/disp8       .                 # copy byte at *(esi+ecx+12) to AL
293     # if (c1 == '\n') break
294     3d/compare-eax-and  0xa/imm32/newline
295     74/jump-if-=  $next-stream-line-equal?:break/disp8
296     # if (currs >= s->size) return false
297     3b/compare                      0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # compare edx with *edi
298     7d/jump-if->=  $next-stream-line-equal?:false/disp8
299     # c2 = s->data[currs]
300     8a/copy-byte                    1/mod/*+disp8   4/rm32/sib    7/base/edi  2/index/edx   .           3/r32/BL    4/disp8         .                 # copy byte at *(edi+edx+4) to BL
301     # if (c1 != c2) return false
302     39/compare                      3/mod/direct    0/rm32/eax    .           .             .           3/r32/ebx   .               .                 # compare eax and ebx
303     75/jump-if-!=  $next-stream-line-equal?:false/disp8
304     # ++currf
305     41/increment-ecx
306     # ++currs
307     42/increment-edx
308     eb/jump $next-stream-line-equal?:loop/disp8
309 $next-stream-line-equal?:break:
310     # ++currf
311     41/increment-ecx
312     # if (currs >= s->size) return true
313     3b/compare                      0/mod/indirect  7/rm32/edi    .           .             .           2/r32/edx   .               .                 # compare edx with *edi
314     7c/jump-if-<  $next-stream-line-equal?:false/disp8
315 $next-stream-line-equal?:true:
316     b8/copy-to-eax  1/imm32
317     # persist f->read on success
318     89/copy                         1/mod/*+disp8   6/rm32/esi    .           .             .           1/r32/ecx   4/disp8         .                 # copy ecx to *(esi+4)
319     eb/jump  $next-stream-line-equal?:end/disp8
320 $next-stream-line-equal?:false:
321     b8/copy-to-eax  0/imm32
322 $next-stream-line-equal?:end:
323     # . restore registers
324     5f/pop-to-edi
325     5e/pop-to-esi
326     5a/pop-to-edx
327     59/pop-to-ecx
328     # . epilogue
329     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
330     5d/pop-to-ebp
331     c3/return
333 test-next-stream-line-equal-stops-at-newline:
334     # . prologue
335     55/push-ebp
336     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
337     # clear-stream(_test-stream)
338     # . . push args
339     68/push  _test-stream/imm32
340     # . . call
341     e8/call  clear-stream/disp32
342     # . . discard args
343     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
344     # write(_test-stream, "Abc\ndef")
345     # . . push args
346     68/push  "Abc\ndef"/imm32
347     68/push  _test-stream/imm32
348     # . . call
349     e8/call  write/disp32
350     # . . discard args
351     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
352     # eax = next-stream-line-equal?(_test-stream, "Abc")
353     # . . push args
354     68/push  "Abc"/imm32
355     68/push  _test-stream/imm32
356     # . . call
357     e8/call  next-stream-line-equal?/disp32
358     # . . discard args
359     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
360     # check-ints-equal(eax, 1, msg)
361     # . . push args
362     68/push  "F - test-next-stream-line-equal-stops-at-newline"/imm32
363     68/push  1/imm32
364     50/push-eax
365     # . . call
366     e8/call  check-ints-equal/disp32
367     # . . discard args
368     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
369     # . epilogue
370     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
371     5d/pop-to-ebp
372     c3/return
374 test-next-stream-line-equal-stops-at-newline-2:
375     # . prologue
376     55/push-ebp
377     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
378     # clear-stream(_test-stream)
379     # . . push args
380     68/push  _test-stream/imm32
381     # . . call
382     e8/call  clear-stream/disp32
383     # . . discard args
384     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
385     # write(_test-stream, "Abc\ndef")
386     # . . push args
387     68/push  "Abc\ndef"/imm32
388     68/push  _test-stream/imm32
389     # . . call
390     e8/call  write/disp32
391     # . . discard args
392     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
393     # eax = next-stream-line-equal?(_test-stream, "def")
394     # . . push args
395     68/push  "def"/imm32
396     68/push  _test-stream/imm32
397     # . . call
398     e8/call  next-stream-line-equal?/disp32
399     # . . discard args
400     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
401     # check-ints-equal(eax, 0, msg)
402     # . . push args
403     68/push  "F - test-next-stream-line-equal-stops-at-newline-2"/imm32
404     68/push  0/imm32
405     50/push-eax
406     # . . call
407     e8/call  check-ints-equal/disp32
408     # . . discard args
409     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
410     # . epilogue
411     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
412     5d/pop-to-ebp
413     c3/return
415 test-next-stream-line-equal-skips-newline:
416     # . prologue
417     55/push-ebp
418     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
419     # clear-stream(_test-stream)
420     # . . push args
421     68/push  _test-stream/imm32
422     # . . call
423     e8/call  clear-stream/disp32
424     # . . discard args
425     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
426     # write(_test-stream, "Abc\ndef\n")
427     # . . push args
428     68/push  "Abc\ndef\n"/imm32
429     68/push  _test-stream/imm32
430     # . . call
431     e8/call  write/disp32
432     # . . discard args
433     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
434     # next-stream-line-equal?(_test-stream, "Abc")
435     # . . push args
436     68/push  "Abc"/imm32
437     68/push  _test-stream/imm32
438     # . . call
439     e8/call  next-stream-line-equal?/disp32
440     # . . discard args
441     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
442     # eax = next-stream-line-equal?(_test-stream, "def")
443     # . . push args
444     68/push  "def"/imm32
445     68/push  _test-stream/imm32
446     # . . call
447     e8/call  next-stream-line-equal?/disp32
448     # . . discard args
449     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
450     # check-ints-equal(eax, 1, msg)
451     # . . push args
452     68/push  "F - test-next-stream-line-equal-skips-newline"/imm32
453     68/push  1/imm32
454     50/push-eax
455     # . . call
456     e8/call  check-ints-equal/disp32
457     # . . discard args
458     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
459     # . epilogue
460     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
461     5d/pop-to-ebp
462     c3/return
464 test-next-stream-line-equal-handles-final-line:
465     # . prologue
466     55/push-ebp
467     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
468     # clear-stream(_test-stream)
469     # . . push args
470     68/push  _test-stream/imm32
471     # . . call
472     e8/call  clear-stream/disp32
473     # . . discard args
474     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
475     # write(_test-stream, "Abc\ndef")
476     # . . push args
477     68/push  "Abc\ndef"/imm32
478     68/push  _test-stream/imm32
479     # . . call
480     e8/call  write/disp32
481     # . . discard args
482     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
483     # next-stream-line-equal?(_test-stream, "Abc")
484     # . . push args
485     68/push  "Abc"/imm32
486     68/push  _test-stream/imm32
487     # . . call
488     e8/call  next-stream-line-equal?/disp32
489     # . . discard args
490     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
491     # eax = next-stream-line-equal?(_test-stream, "def")
492     # . . push args
493     68/push  "def"/imm32
494     68/push  _test-stream/imm32
495     # . . call
496     e8/call  next-stream-line-equal?/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, 1, msg)
500     # . . push args
501     68/push  "F - test-next-stream-line-equal-skips-newline"/imm32
502     68/push  1/imm32
503     50/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     # . epilogue
509     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
510     5d/pop-to-ebp
511     c3/return
513 test-next-stream-line-equal-always-fails-after-Eof:
514     # . prologue
515     55/push-ebp
516     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
517     # clear-stream(_test-stream)
518     # . . push args
519     68/push  _test-stream/imm32
520     # . . call
521     e8/call  clear-stream/disp32
522     # . . discard args
523     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               4/imm32           # add to esp
524     # write nothing
525     # eax = next-stream-line-equal?(_test-stream, "")
526     # . . push args
527     68/push  ""/imm32
528     68/push  _test-stream/imm32
529     # . . call
530     e8/call  next-stream-line-equal?/disp32
531     # . . discard args
532     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
533     # check-ints-equal(eax, 0, msg)
534     # . . push args
535     68/push  "F - test-next-stream-line-equal-always-fails-after-Eof"/imm32
536     68/push  1/imm32
537     50/push-eax
538     # . . call
539     e8/call  check-ints-equal/disp32
540     # . . discard args
541     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
542     # eax = next-stream-line-equal?(_test-stream, "")
543     # . . push args
544     68/push  ""/imm32
545     68/push  _test-stream/imm32
546     # . . call
547     e8/call  next-stream-line-equal?/disp32
548     # . . discard args
549     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
550     # check-ints-equal(eax, 0, msg)
551     # . . push args
552     68/push  "F - test-next-stream-line-equal-always-fails-after-Eof/2"/imm32
553     68/push  1/imm32
554     50/push-eax
555     # . . call
556     e8/call  check-ints-equal/disp32
557     # . . discard args
558     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
559     # . epilogue
560     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
561     5d/pop-to-ebp
562     c3/return
564 # helper for later tests
565 check-next-stream-line-equal:  # f: (addr stream byte), s: (addr array byte), msg: (addr array byte)
566     # . prologue
567     55/push-ebp
568     89/copy                         3/mod/direct    5/rm32/ebp    .           .             .           4/r32/esp   .               .                 # copy esp to ebp
569     # . save registers
570     50/push-eax
571     # eax = next-stream-line-equal?(f, s)
572     # . . push args
573     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0xc/disp8       .                 # push *(ebp+12)
574     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           8/disp8         .                 # push *(ebp+8)
575     # . . call
576     e8/call  next-stream-line-equal?/disp32
577     # . . discard args
578     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               8/imm32           # add to esp
579     # check-ints-equal(eax, 1, msg)
580     # . . push args
581     ff          6/subop/push        1/mod/*+disp8   5/rm32/ebp    .           .             .           .           0x10/disp8      .                 # push *(ebp+16)
582     68/push  1/imm32
583     50/push-eax
584     # . . call
585     e8/call  check-ints-equal/disp32
586     # . . discard args
587     81          0/subop/add         3/mod/direct    4/rm32/esp    .           .             .           .           .               0xc/imm32         # add to esp
588     # . restore registers
589     58/pop-to-eax
590     # . epilogue
591     89/copy                         3/mod/direct    4/rm32/esp    .           .             .           5/r32/ebp   .               .                 # copy ebp to esp
592     5d/pop-to-ebp
593     c3/return
595 # . . vim:nowrap:textwidth=0