So far it's unclear how to do this in a series of small commits. Still nibbling around the edges. In this commit we standardize some terminology: The length of an array or stream is denominated in the high-level elements. The _size_ is denominated in bytes. The thing we encode into the type is always the size, not the length. There's still an open question of what to do about the Mu `length` operator. I'd like to modify it to provide the length. Currently it provides the size. If I can't fix that I'll rename it.
596 lines
29 KiB
Plaintext
596 lines
29 KiB
Plaintext
# some primitives for checking stream contents
|
|
|
|
== code
|
|
# instruction effective address register displacement immediate
|
|
# . op subop mod rm32 base index scale r32
|
|
# . 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
|
|
|
|
# compare all the data in a stream (ignoring the read pointer)
|
|
stream-data-equal?: # f: (addr stream byte), s: (addr array byte) -> eax: boolean
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# . save registers
|
|
51/push-ecx
|
|
52/push-edx
|
|
56/push-esi
|
|
57/push-edi
|
|
# esi = f
|
|
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
|
# eax = f->write
|
|
8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax
|
|
# var maxf/edx: (addr byte) = &f->data[f->write]
|
|
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
|
|
# var currf/esi: (addr byte) = f->data
|
|
81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to esi
|
|
# edi = s
|
|
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
|
|
$stream-data-equal?:compare-sizes:
|
|
# if (f->write != s->size) return false
|
|
39/compare 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # compare *edi and eax
|
|
75/jump-if-!= $stream-data-equal?:false/disp8
|
|
# var currs/edi: (addr byte) = s->data
|
|
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
|
|
# var eax: byte = 0
|
|
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
|
# var ecx: byte = 0
|
|
31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx
|
|
$stream-data-equal?:loop:
|
|
# if (currf >= maxf) return true
|
|
39/compare 3/mod/direct 6/rm32/esi . . . 2/r32/edx . . # compare esi with edx
|
|
73/jump-if-addr>= $stream-data-equal?:true/disp8
|
|
# AL = *currs
|
|
8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL
|
|
# CL = *curr
|
|
8a/copy-byte 0/mod/indirect 7/rm32/edi . . . 1/r32/CL . . # copy byte at *edi to CL
|
|
# if (eax != ecx) return false
|
|
39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax and ecx
|
|
75/jump-if-!= $stream-data-equal?:false/disp8
|
|
# ++f
|
|
46/increment-esi
|
|
# ++curr
|
|
47/increment-edi
|
|
eb/jump $stream-data-equal?:loop/disp8
|
|
$stream-data-equal?:false:
|
|
b8/copy-to-eax 0/imm32
|
|
eb/jump $stream-data-equal?:end/disp8
|
|
$stream-data-equal?:true:
|
|
b8/copy-to-eax 1/imm32
|
|
$stream-data-equal?:end:
|
|
# . restore registers
|
|
5f/pop-to-edi
|
|
5e/pop-to-esi
|
|
5a/pop-to-edx
|
|
59/pop-to-ecx
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
test-stream-data-equal:
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# clear-stream(_test-stream)
|
|
# . . push args
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call clear-stream/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
|
# write(_test-stream, "Abc")
|
|
# . . push args
|
|
68/push "Abc"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call write/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# eax = stream-data-equal?(_test-stream, "Abc")
|
|
# . . push args
|
|
68/push "Abc"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call stream-data-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 1, msg)
|
|
# . . push args
|
|
68/push "F - test-stream-data-equal"/imm32
|
|
68/push 1/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
test-stream-data-equal-2:
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# clear-stream(_test-stream)
|
|
# . . push args
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call clear-stream/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
|
# write(_test-stream, "Abc")
|
|
# . . push args
|
|
68/push "Abc"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call write/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# eax = stream-data-equal?(_test-stream, "Abd")
|
|
# . . push args
|
|
68/push "Abd"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call stream-data-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 0, msg)
|
|
# . . push args
|
|
68/push "F - test-stream-data-equal-2"/imm32
|
|
68/push 0/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
test-stream-data-equal-size-check:
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# clear-stream(_test-stream)
|
|
# . . push args
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call clear-stream/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
|
# write(_test-stream, "Abc")
|
|
# . . push args
|
|
68/push "Abc"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call write/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# eax = stream-data-equal?(_test-stream, "Abcd")
|
|
# . . push args
|
|
68/push "Abcd"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call stream-data-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 0, msg)
|
|
# . . push args
|
|
68/push "F - test-stream-data-equal-size-check"/imm32
|
|
68/push 0/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
# helper for later tests
|
|
check-stream-equal: # f: (addr stream byte), s: (addr array byte), msg: (addr array byte)
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# . save registers
|
|
50/push-eax
|
|
# eax = stream-data-equal?(f, s)
|
|
# . . push args
|
|
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12)
|
|
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8)
|
|
# . . call
|
|
e8/call stream-data-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 1, msg)
|
|
# . . push args
|
|
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16)
|
|
68/push 1/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
$check-stream-equal:end:
|
|
# . restore registers
|
|
58/pop-to-eax
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
# scan the next line until newline starting from f->read and compare it with
|
|
# 's' (ignoring the trailing newline)
|
|
# on success, set f->read to after the next newline
|
|
# on failure, leave f->read unmodified
|
|
# this function is usually used only in tests, so we repeatedly write f->read
|
|
next-stream-line-equal?: # f: (addr stream byte), s: (addr array byte) -> eax: boolean
|
|
# pseudocode:
|
|
# currf = f->read # bound: f->write
|
|
# currs = 0 # bound: s->size
|
|
# while true
|
|
# if currf >= f->write
|
|
# return currs >= s->size
|
|
# if f[currf] == '\n'
|
|
# ++currf
|
|
# return currs >= s->size
|
|
# if (currs >= s->size) return false # the current line of f still has data to match
|
|
# if (f[currf] != s[currs]) return false
|
|
# ++currf
|
|
# ++currs
|
|
#
|
|
# collapsing the two branches that can return true:
|
|
# currf = f->read # bound: f->write
|
|
# currs = 0 # bound: s->size
|
|
# while true
|
|
# if (currf >= f->write) break
|
|
# if (f[currf] == '\n') break
|
|
# if (currs >= s->size) return false # the current line of f still has data to match
|
|
# if (f[currf] != s[currs]) return false
|
|
# ++currf
|
|
# ++currs
|
|
# ++currf # skip '\n'
|
|
# return currs >= s->size
|
|
# Here the final `++currf` is sometimes unnecessary (if we're already at the end of the stream)
|
|
#
|
|
# registers:
|
|
# f: esi
|
|
# s: edi
|
|
# currf: ecx
|
|
# currs: edx
|
|
# f[currf]: eax
|
|
# s[currs]: ebx
|
|
#
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# . save registers
|
|
51/push-ecx
|
|
52/push-edx
|
|
56/push-esi
|
|
57/push-edi
|
|
# esi = f
|
|
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi
|
|
# var currf/ecx: int = f->read
|
|
8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx
|
|
# edi = s
|
|
8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi
|
|
# var currs/edx: int = 0
|
|
31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx
|
|
# var c1/eax: byte = 0
|
|
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
|
# var c2/ebx: byte = 0
|
|
31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx
|
|
$next-stream-line-equal?:loop:
|
|
# if (currf >= f->write) break
|
|
3b/compare 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # compare ecx with *esi
|
|
7d/jump-if->= $next-stream-line-equal?:break/disp8
|
|
# c1 = f->data[f->read]
|
|
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
|
|
# if (c1 == '\n') break
|
|
3d/compare-eax-and 0xa/imm32/newline
|
|
74/jump-if-= $next-stream-line-equal?:break/disp8
|
|
# if (currs >= s->size) return false
|
|
3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi
|
|
7d/jump-if->= $next-stream-line-equal?:false/disp8
|
|
# c2 = s->data[currs]
|
|
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
|
|
# if (c1 != c2) return false
|
|
39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx
|
|
75/jump-if-!= $next-stream-line-equal?:false/disp8
|
|
# ++currf
|
|
41/increment-ecx
|
|
# ++currs
|
|
42/increment-edx
|
|
eb/jump $next-stream-line-equal?:loop/disp8
|
|
$next-stream-line-equal?:break:
|
|
# ++currf
|
|
41/increment-ecx
|
|
# if (currs >= s->size) return true
|
|
3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi
|
|
7c/jump-if-< $next-stream-line-equal?:false/disp8
|
|
$next-stream-line-equal?:true:
|
|
b8/copy-to-eax 1/imm32
|
|
# persist f->read on success
|
|
89/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy ecx to *(esi+4)
|
|
eb/jump $next-stream-line-equal?:end/disp8
|
|
$next-stream-line-equal?:false:
|
|
b8/copy-to-eax 0/imm32
|
|
$next-stream-line-equal?:end:
|
|
# . restore registers
|
|
5f/pop-to-edi
|
|
5e/pop-to-esi
|
|
5a/pop-to-edx
|
|
59/pop-to-ecx
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
test-next-stream-line-equal-stops-at-newline:
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# clear-stream(_test-stream)
|
|
# . . push args
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call clear-stream/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
|
# write(_test-stream, "Abc\ndef")
|
|
# . . push args
|
|
68/push "Abc\ndef"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call write/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# eax = next-stream-line-equal?(_test-stream, "Abc")
|
|
# . . push args
|
|
68/push "Abc"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call next-stream-line-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 1, msg)
|
|
# . . push args
|
|
68/push "F - test-next-stream-line-equal-stops-at-newline"/imm32
|
|
68/push 1/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
test-next-stream-line-equal-stops-at-newline-2:
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# clear-stream(_test-stream)
|
|
# . . push args
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call clear-stream/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
|
# write(_test-stream, "Abc\ndef")
|
|
# . . push args
|
|
68/push "Abc\ndef"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call write/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# eax = next-stream-line-equal?(_test-stream, "def")
|
|
# . . push args
|
|
68/push "def"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call next-stream-line-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 0, msg)
|
|
# . . push args
|
|
68/push "F - test-next-stream-line-equal-stops-at-newline-2"/imm32
|
|
68/push 0/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
test-next-stream-line-equal-skips-newline:
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# clear-stream(_test-stream)
|
|
# . . push args
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call clear-stream/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
|
# write(_test-stream, "Abc\ndef\n")
|
|
# . . push args
|
|
68/push "Abc\ndef\n"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call write/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# next-stream-line-equal?(_test-stream, "Abc")
|
|
# . . push args
|
|
68/push "Abc"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call next-stream-line-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# eax = next-stream-line-equal?(_test-stream, "def")
|
|
# . . push args
|
|
68/push "def"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call next-stream-line-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 1, msg)
|
|
# . . push args
|
|
68/push "F - test-next-stream-line-equal-skips-newline"/imm32
|
|
68/push 1/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
test-next-stream-line-equal-handles-final-line:
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# clear-stream(_test-stream)
|
|
# . . push args
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call clear-stream/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
|
# write(_test-stream, "Abc\ndef")
|
|
# . . push args
|
|
68/push "Abc\ndef"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call write/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# next-stream-line-equal?(_test-stream, "Abc")
|
|
# . . push args
|
|
68/push "Abc"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call next-stream-line-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# eax = next-stream-line-equal?(_test-stream, "def")
|
|
# . . push args
|
|
68/push "def"/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call next-stream-line-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 1, msg)
|
|
# . . push args
|
|
68/push "F - test-next-stream-line-equal-skips-newline"/imm32
|
|
68/push 1/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
test-next-stream-line-equal-always-fails-after-Eof:
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# clear-stream(_test-stream)
|
|
# . . push args
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call clear-stream/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp
|
|
# write nothing
|
|
# eax = next-stream-line-equal?(_test-stream, "")
|
|
# . . push args
|
|
68/push ""/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call next-stream-line-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 0, msg)
|
|
# . . push args
|
|
68/push "F - test-next-stream-line-equal-always-fails-after-Eof"/imm32
|
|
68/push 1/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# eax = next-stream-line-equal?(_test-stream, "")
|
|
# . . push args
|
|
68/push ""/imm32
|
|
68/push _test-stream/imm32
|
|
# . . call
|
|
e8/call next-stream-line-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 0, msg)
|
|
# . . push args
|
|
68/push "F - test-next-stream-line-equal-always-fails-after-Eof/2"/imm32
|
|
68/push 1/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
# helper for later tests
|
|
check-next-stream-line-equal:
|
|
# . prologue
|
|
55/push-ebp
|
|
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
|
# . save registers
|
|
50/push-eax
|
|
# eax = next-stream-line-equal?(f, s)
|
|
# . . push args
|
|
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12)
|
|
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8)
|
|
# . . call
|
|
e8/call next-stream-line-equal?/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
|
# check-ints-equal(eax, 1, msg)
|
|
# . . push args
|
|
ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0x10/disp8 . # push *(ebp+16)
|
|
68/push 1/imm32
|
|
50/push-eax
|
|
# . . call
|
|
e8/call check-ints-equal/disp32
|
|
# . . discard args
|
|
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
|
# . restore registers
|
|
58/pop-to-eax
|
|
# . epilogue
|
|
89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp
|
|
5d/pop-to-ebp
|
|
c3/return
|
|
|
|
# . . vim:nowrap:textwidth=0
|