594 lines
29 KiB
Plaintext
594 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 : (address stream), s : (address string) -> eax : boolean
|
|
# . prolog
|
|
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
|
|
# maxf/edx = 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
|
|
# currf/esi = 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
|
|
# if (f->write != s->length) return false
|
|
$stream-data-equal?:compare-lengths:
|
|
39/compare 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # compare *edi and eax
|
|
75/jump-if-not-equal $stream-data-equal?:false/disp8
|
|
# currs/edi = s->data
|
|
81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi
|
|
# eax = ecx = 0
|
|
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
|
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-greater-or-equal-unsigned $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-not-equal $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
|
|
# . epilog
|
|
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:
|
|
# . prolog
|
|
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
|
|
# . epilog
|
|
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:
|
|
# . prolog
|
|
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
|
|
# . epilog
|
|
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-length-check:
|
|
# . prolog
|
|
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-length-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
|
|
# . epilog
|
|
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 : (address stream), s : (address string), msg : (address string)
|
|
# . prolog
|
|
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
|
|
# . epilog
|
|
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 : (address stream), s : (address string) -> eax : boolean
|
|
# pseudocode:
|
|
# currf = f->read # bound: f->write
|
|
# currs = 0 # bound : s->length
|
|
# while true
|
|
# if currf >= f->write
|
|
# return currs >= s->length
|
|
# if f[currf] == '\n'
|
|
# ++currf
|
|
# return currs >= s->length
|
|
# if (currs >= s->length) 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->length
|
|
# while true
|
|
# if (currf >= f->write) break
|
|
# if (f[currf] == '\n') break
|
|
# if (currs >= s->length) 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->length
|
|
# 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
|
|
#
|
|
# . prolog
|
|
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
|
|
# currf/ecx = 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
|
|
# currs/edx = 0
|
|
31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx
|
|
# eax = ebx = 0
|
|
31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax
|
|
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-greater-or-equal $next-stream-line-equal?:break/disp8
|
|
# AL = *(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 (eax == '\n') break
|
|
3d/compare-eax-and 0xa/imm32/newline
|
|
74/jump-if-equal $next-stream-line-equal?:break/disp8
|
|
# if (currs >= s->length) return false
|
|
3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi
|
|
7d/jump-if-greater-or-equal $next-stream-line-equal?:false/disp8
|
|
# BL = *(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 (eax != ebx) return false
|
|
39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx
|
|
75/jump-if-not-equal $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->length) return true
|
|
3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi
|
|
7c/jump-if-lesser $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
|
|
# . epilog
|
|
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:
|
|
# . prolog
|
|
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
|
|
# . epilog
|
|
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:
|
|
# . prolog
|
|
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
|
|
# . epilog
|
|
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:
|
|
# . prolog
|
|
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
|
|
# . epilog
|
|
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:
|
|
# . prolog
|
|
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
|
|
# . epilog
|
|
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:
|
|
# . prolog
|
|
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
|
|
# . epilog
|
|
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:
|
|
# . prolog
|
|
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
|
|
# . epilog
|
|
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
|