7522 - bring back a few tests in .subx files
Even though baremetal has tests in SubX, they can only run in Mu programs since the test harness is currently in a Mu layer. Baremetal isn't really intended for running SubX programs at the moment. Is this a step down the slippery slope towards C compilers that I complained about in http://akkartik.name/akkartik-convivial-20200607.pdf?
This commit is contained in:
parent
6e36ce06dd
commit
8ed27ce431
|
@ -1,3 +1,10 @@
|
|||
# write: write to in-memory streams
|
||||
#
|
||||
# A stream looks like this:
|
||||
# read: int # index at which to read next
|
||||
# write: int # index at which writes go
|
||||
# data: (array byte) # prefixed by size as usual
|
||||
|
||||
== code
|
||||
# instruction effective address register displacement immediate
|
||||
# . op subop mod rm32 base index scale r32
|
||||
|
@ -10,8 +17,6 @@ write: # f: (addr stream byte), s: (addr array byte)
|
|||
# if (s == 0) return
|
||||
81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 0/imm32 # compare *(ebp+12)
|
||||
74/jump-if-= $write:end/disp8
|
||||
# TODO: write to file
|
||||
# otherwise, treat 'f' as a stream to append to
|
||||
# . save registers
|
||||
50/push-eax
|
||||
51/push-ecx
|
||||
|
@ -49,7 +54,88 @@ $write:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
# TODO: bring in tests once we have check-ints-equal
|
||||
test-write-single:
|
||||
# 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, "Ab")
|
||||
# . . push args
|
||||
68/push "Ab"/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
|
||||
# check-ints-equal(*_test-stream->data, 41/A 62/b 00 00, msg)
|
||||
# . . push args
|
||||
68/push "F - test-write-single"/imm32
|
||||
68/push 0x006241/imm32/Ab
|
||||
# . . push *_test-stream->data
|
||||
b8/copy-to-eax _test-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 0xc/disp8 . # push *(eax+12)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
||||
# end
|
||||
c3/return
|
||||
|
||||
test-write-appends:
|
||||
# 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, "C")
|
||||
# . . push args
|
||||
68/push "C"/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
|
||||
# write(_test-stream, "D")
|
||||
# . . push args
|
||||
68/push "D"/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
|
||||
# check-ints-equal(*_test-stream->data, 43/C 44/D 00 00, msg)
|
||||
# . . push args
|
||||
68/push "F - test-write-appends"/imm32
|
||||
68/push 0x00004443/imm32/C-D
|
||||
# . . push *_test-stream->data
|
||||
b8/copy-to-eax _test-stream/imm32
|
||||
ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 0xc/disp8 . # push *(eax+12)
|
||||
# . . call
|
||||
e8/call check-ints-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
||||
# end
|
||||
c3/return
|
||||
|
||||
== data
|
||||
|
||||
_test-stream: # (stream byte)
|
||||
# current write index
|
||||
0/imm32
|
||||
# current read index
|
||||
0/imm32
|
||||
# size
|
||||
0x10/imm32
|
||||
# data (2 lines x 8 bytes/line)
|
||||
00 00 00 00 00 00 00 00
|
||||
00 00 00 00 00 00 00 00
|
||||
|
||||
== code
|
||||
|
||||
# 3-argument variant of _append
|
||||
_append-3: # out: (addr byte), outend: (addr byte), s: (addr array byte) -> num_bytes_appended/eax
|
||||
|
|
595
baremetal/109stream-equal.subx
Normal file
595
baremetal/109stream-equal.subx
Normal file
|
@ -0,0 +1,595 @@
|
|||
# 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) -> result/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) -> result/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: # 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 = 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
|
|
@ -3,8 +3,6 @@
|
|||
# . 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
|
||||
|
||||
# TODO: read-byte-buffered
|
||||
|
||||
# Return next byte value in eax, with top 3 bytes cleared.
|
||||
# Abort on reaching end of stream.
|
||||
read-byte: # s: (addr stream byte) -> result/eax: byte
|
||||
|
|
|
@ -35,4 +35,34 @@ $append-byte:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
test-append-byte-single:
|
||||
# - check that append-byte writes to first byte of 'file'
|
||||
# setup
|
||||
# . 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
|
||||
# append-byte(_test-stream, 'A')
|
||||
# . . push args
|
||||
68/push 0x41/imm32
|
||||
68/push _test-stream/imm32
|
||||
# . . call
|
||||
e8/call append-byte/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# check-stream-equal(_test-stream, "A", msg)
|
||||
# . . push args
|
||||
68/push "F - test-append-byte-single"/imm32
|
||||
68/push "A"/imm32
|
||||
68/push _test-stream/imm32
|
||||
# . . call
|
||||
e8/call check-stream-equal/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0xc/imm32 # add to esp
|
||||
# . end
|
||||
c3/return
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
|
@ -50,4 +50,34 @@ $zero-out:end:
|
|||
5d/pop-to-ebp
|
||||
c3/return
|
||||
|
||||
test-zero-out:
|
||||
# . prologue
|
||||
55/push-ebp
|
||||
89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp
|
||||
# region/ecx = 34, 35, 36, 37
|
||||
68/push 0x37363534/imm32
|
||||
89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx
|
||||
# zero-out(ecx, 3)
|
||||
# . . push args
|
||||
68/push 3/imm32/size
|
||||
51/push-ecx
|
||||
# . . call
|
||||
e8/call zero-out/disp32
|
||||
# . . discard args
|
||||
81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp
|
||||
# first 3 bytes cleared, fourth left alone
|
||||
# . check-ints-equal(*ecx, 0x37000000, msg)
|
||||
# . . push args
|
||||
68/push "F - test-zero-out"/imm32
|
||||
68/push 0x37000000/imm32
|
||||
ff 6/subop/push 0/mod/indirect 1/rm32/ecx . . . . . . # push *ecx
|
||||
# . . 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
|
||||
|
||||
# . . vim:nowrap:textwidth=0
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
#!/bin/sh
|
||||
# Translate given SubX files to 'baremetal', a raw disk image that can boot and
|
||||
# run without any OS.
|
||||
#
|
||||
# A couple of gotchas:
|
||||
# * Many phases here have no error-checking. Perhaps I should use a
|
||||
# version of translate_subx_debug for baremetal.
|
||||
# * Don't pass in numbered .subx files without translated .mu files. Our test
|
||||
# harness is in test.mu, and only Mu programs can run tests in baremetal.
|
||||
|
||||
set -e
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user