updates to survey - part of compute-offsets implemented

This commit is contained in:
nc 2019-07-03 22:26:17 -04:00
parent 34cf8a7034
commit 87ef858628
4 changed files with 393 additions and 254 deletions

View File

@ -5835,252 +5835,6 @@ test-convert-instruction-handles-imm8-operand:
5d/pop-to-EBP
c3/return
# (re)compute the bounds of the next word in the line
# return empty string on reaching end of file
next-word: # line : (address stream byte), out : (address slice)
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# . save registers
50/push-EAX
51/push-ECX
56/push-ESI
57/push-EDI
# ESI = line
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI
# EDI = out
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 0xc/disp8 . # copy *(EBP+12) to EDI
# skip-chars-matching(line, ' ')
# . . push args
68/push 0x20/imm32/space
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8)
# . . call
e8/call skip-chars-matching/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
$next-word:check0:
# if (line->read >= line->write) clear out and return
# . EAX = line->read
8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy *(ESI+4) to EAX
# . if (EAX < line->write) goto next check
3b/compare 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # compare EAX with *ESI
7c/jump-if-lesser $next-word:check-for-comment/disp8
# . return out = {0, 0}
c7 0/subop/copy 0/mod/direct 7/rm32/EDI . . . . . 0/imm32 # copy to *EDI
c7 0/subop/copy 1/mod/*+disp8 7/rm32/EDI . . . . 4/disp8 0/imm32 # copy to *(EDI+4)
eb/jump $next-word:end/disp8
$next-word:check-for-comment:
# out->start = &line->data[line->read]
8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 1/r32/ECX 4/disp8 . # copy *(ESI+4) to ECX
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 1/index/ECX . 0/r32/EAX 0xc/disp8 . # copy ESI+ECX+12 to EAX
89/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to *EDI
# if (line->data[line->read] == '#') out->end = &line->data[line->write]), skip rest of stream and return
# . EAX = line->data[line->read]
31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX
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
# . compare
3d/compare-EAX-and 0x23/imm32/pound
75/jump-if-not-equal $next-word:regular-word/disp8
$next-word:comment:
# . out->end = &line->data[line->write]
8b/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy *ESI to EAX
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 0/index/EAX . 0/r32/EAX 0xc/disp8 . # copy ESI+EAX+12 to EAX
89/copy 1/mod/*+disp8 7/rm32/EDI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EDI+4)
# . line->read = line->write
89/copy 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(ESI+4)
# . return
eb/jump $next-word:end/disp8
$next-word:regular-word:
# otherwise skip-chars-not-matching-whitespace(line) # including trailing newline
# . . push args
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8)
# . . call
e8/call skip-chars-not-matching-whitespace/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# out->end = &line->data[line->read]
8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 1/r32/ECX 4/disp8 . # copy *(ESI+4) to ECX
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 1/index/ECX . 0/r32/EAX 0xc/disp8 . # copy ESI+ECX+12 to EAX
89/copy 1/mod/*+disp8 7/rm32/EDI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EDI+4)
$next-word:end:
# . restore registers
5f/pop-to-EDI
5e/pop-to-ESI
59/pop-to-ECX
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
test-next-word:
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# 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
# var slice/ECX = {0, 0}
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
# 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
# next-word(_test-stream, slice)
# . . push args
51/push-ECX
68/push _test-stream/imm32
# . . call
e8/call next-word/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(slice->start - _test-stream->data, 2, msg)
# . check-ints-equal(slice->start - _test-stream, 14, msg)
# . . push args
68/push "F - test-next-word: start"/imm32
68/push 0xe/imm32
# . . push slice->start - _test-stream
8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX
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-ints-equal(slice->end - _test-stream->data, 4, msg)
# . check-ints-equal(slice->end - _test-stream, 16, msg)
# . . push args
68/push "F - test-next-word: end"/imm32
68/push 0x10/imm32
# . . push slice->end - _test-stream
8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX
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-word-returns-whole-comment:
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# 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
# var slice/ECX = {0, 0}
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
# write(_test-stream, " # a")
# . . push args
68/push " # a"/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-word(_test-stream, slice)
# . . push args
51/push-ECX
68/push _test-stream/imm32
# . . call
e8/call next-word/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(slice->start - _test-stream->data, 2, msg)
# . check-ints-equal(slice->start - _test-stream, 14, msg)
# . . push args
68/push "F - test-next-word-returns-whole-comment: start"/imm32
68/push 0xe/imm32
# . . push slice->start - _test-stream
8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX
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-ints-equal(slice->end - _test-stream->data, 5, msg)
# . check-ints-equal(slice->end - _test-stream, 17, msg)
# . . push args
68/push "F - test-next-word-returns-whole-comment: end"/imm32
68/push 0x11/imm32
# . . push slice->end - _test-stream
8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX
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-word-returns-empty-string-on-eof:
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# 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
# var slice/ECX = {0, 0}
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
# write nothing to _test-stream
# next-word(_test-stream, slice)
# . . push args
51/push-ECX
68/push _test-stream/imm32
# . . call
e8/call next-word/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(slice->end - slice->start, 0, msg)
# . . push args
68/push "F - test-next-word-returns-empty-string-on-eof"/imm32
68/push 0/imm32
# . . push slice->end - slice->start
8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX
2b/subtract 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # subtract *ECX from EAX
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
# If datum of 'word' is not a valid name, it must be a hex int. Parse and print
# it in 'width' bytes of hex, least significant first.
# Otherwise just print the entire word including metadata.

View File

@ -252,6 +252,252 @@ $test-get-or-insert:end:
5d/pop-to-EBP
c3/return
# (re)compute the bounds of the next word in the line
# return empty string on reaching end of file
next-word: # line : (address stream byte), out : (address slice)
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# . save registers
50/push-EAX
51/push-ECX
56/push-ESI
57/push-EDI
# ESI = line
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI
# EDI = out
8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 0xc/disp8 . # copy *(EBP+12) to EDI
# skip-chars-matching(line, ' ')
# . . push args
68/push 0x20/imm32/space
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8)
# . . call
e8/call skip-chars-matching/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
$next-word:check0:
# if (line->read >= line->write) clear out and return
# . EAX = line->read
8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy *(ESI+4) to EAX
# . if (EAX < line->write) goto next check
3b/compare 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # compare EAX with *ESI
7c/jump-if-lesser $next-word:check-for-comment/disp8
# . return out = {0, 0}
c7 0/subop/copy 0/mod/direct 7/rm32/EDI . . . . . 0/imm32 # copy to *EDI
c7 0/subop/copy 1/mod/*+disp8 7/rm32/EDI . . . . 4/disp8 0/imm32 # copy to *(EDI+4)
eb/jump $next-word:end/disp8
$next-word:check-for-comment:
# out->start = &line->data[line->read]
8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 1/r32/ECX 4/disp8 . # copy *(ESI+4) to ECX
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 1/index/ECX . 0/r32/EAX 0xc/disp8 . # copy ESI+ECX+12 to EAX
89/copy 0/mod/indirect 7/rm32/EDI . . . 0/r32/EAX . . # copy EAX to *EDI
# if (line->data[line->read] == '#') out->end = &line->data[line->write]), skip rest of stream and return
# . EAX = line->data[line->read]
31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX
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
# . compare
3d/compare-EAX-and 0x23/imm32/pound
75/jump-if-not-equal $next-word:regular-word/disp8
$next-word:comment:
# . out->end = &line->data[line->write]
8b/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy *ESI to EAX
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 0/index/EAX . 0/r32/EAX 0xc/disp8 . # copy ESI+EAX+12 to EAX
89/copy 1/mod/*+disp8 7/rm32/EDI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EDI+4)
# . line->read = line->write
89/copy 1/mod/*+disp8 6/rm32/ESI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(ESI+4)
# . return
eb/jump $next-word:end/disp8
$next-word:regular-word:
# otherwise skip-chars-not-matching-whitespace(line) # including trailing newline
# . . push args
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8)
# . . call
e8/call skip-chars-not-matching-whitespace/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# out->end = &line->data[line->read]
8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 1/r32/ECX 4/disp8 . # copy *(ESI+4) to ECX
8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/ESI 1/index/ECX . 0/r32/EAX 0xc/disp8 . # copy ESI+ECX+12 to EAX
89/copy 1/mod/*+disp8 7/rm32/EDI . . . 0/r32/EAX 4/disp8 . # copy EAX to *(EDI+4)
$next-word:end:
# . restore registers
5f/pop-to-EDI
5e/pop-to-ESI
59/pop-to-ECX
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
test-next-word:
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# 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
# var slice/ECX = {0, 0}
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
# 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
# next-word(_test-stream, slice)
# . . push args
51/push-ECX
68/push _test-stream/imm32
# . . call
e8/call next-word/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(slice->start - _test-stream->data, 2, msg)
# . check-ints-equal(slice->start - _test-stream, 14, msg)
# . . push args
68/push "F - test-next-word: start"/imm32
68/push 0xe/imm32
# . . push slice->start - _test-stream
8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX
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-ints-equal(slice->end - _test-stream->data, 4, msg)
# . check-ints-equal(slice->end - _test-stream, 16, msg)
# . . push args
68/push "F - test-next-word: end"/imm32
68/push 0x10/imm32
# . . push slice->end - _test-stream
8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX
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-word-returns-whole-comment:
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# 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
# var slice/ECX = {0, 0}
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
# write(_test-stream, " # a")
# . . push args
68/push " # a"/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-word(_test-stream, slice)
# . . push args
51/push-ECX
68/push _test-stream/imm32
# . . call
e8/call next-word/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(slice->start - _test-stream->data, 2, msg)
# . check-ints-equal(slice->start - _test-stream, 14, msg)
# . . push args
68/push "F - test-next-word-returns-whole-comment: start"/imm32
68/push 0xe/imm32
# . . push slice->start - _test-stream
8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX
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-ints-equal(slice->end - _test-stream->data, 5, msg)
# . check-ints-equal(slice->end - _test-stream, 17, msg)
# . . push args
68/push "F - test-next-word-returns-whole-comment: end"/imm32
68/push 0x11/imm32
# . . push slice->end - _test-stream
8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX
81 5/subop/subtract 3/mod/direct 0/rm32/EAX . . . . . _test-stream/imm32 # subtract from EAX
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-word-returns-empty-string-on-eof:
# . prolog
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# 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
# var slice/ECX = {0, 0}
68/push 0/imm32/end
68/push 0/imm32/start
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
# write nothing to _test-stream
# next-word(_test-stream, slice)
# . . push args
51/push-ECX
68/push _test-stream/imm32
# . . call
e8/call next-word/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# check-ints-equal(slice->end - slice->start, 0, msg)
# . . push args
68/push "F - test-next-word-returns-empty-string-on-eof"/imm32
68/push 0/imm32
# . . push slice->end - slice->start
8b/copy 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # copy *(ECX+4) to EAX
2b/subtract 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # subtract *ECX from EAX
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
# 'table' is a stream of (key, value) rows
# keys are always strings (addresses; size 4 bytes)
# values may be any type, but rows (key+value) always occupy 'row-size' bytes

View File

@ -438,9 +438,140 @@ compute-offsets: # in : (address buffered-file), segments : (address stream {st
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# . save registers
50/push-EAX
51/push-ECX
52/push-EDX
53/push-EBX
56/push-ESI
57/push-EDI
# cur-segment-name = {0, 0}
#c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . compute-offsets:cur-segment-name/disp32 0/imm32 # copy to *compute-offsets:word-slice
#c7 0/subop/copy 1/mod/*+disp8 5/rm32/.disp32 . . . 4/disp8 compute-offsets:cur-segment-name/disp32 0/imm32 # copy to *(compute-offsets:word-slice+4)
# file-offset = 0
b8/copy-to-EAX 0/imm32
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX compute-offsets:file-offset/disp32 # copy EAX to *cur-segment-name
# segment-offset = 0
b8/copy-to-EAX 0/imm32
89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/EAX compute-offsets:segment-offset/disp32 # copy EAX to *cur-segment-name
# var heap/ECX : (address allocation-descriptor) = {0, 0}
68/push 0/imm32/limit
68/push 0/imm32/curr
89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX
# heap = new-segment(512)
# . . push args
51/push-ECX
68/push 0x200/imm32
# . . call
e8/call new-segment/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# EAX = new-stream(512, 1)
68/push 1/imm32
68/push 0x200/imm32
51/push-ECX
e8/call new-stream/disp32
# . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# line/ECX = EAX
8b/copy 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX
$compute-offsets:line-loop:
# clear-stream(line/ECX)
51/push-ECX
e8/call clear-stream/disp32
# . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# read-line-buffered(in, line/ECX)
51/push-ECX
ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8)
e8/call read-line-buffered/disp32
# . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# if(line->write == 0)
# . EAX = line/ECX->write
8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *EAX to EAX
# . line->write/EAX == 0 ?
3d/compare-EAX-and 0/imm32
# . if so, break
0f 84/jump-if-equal $compute-offsets:end/disp32
$compute-offsets:word-loop:
# var word-slice/EDX = {0, 0}
#c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . compute-offsets:word-slice/disp32 0/imm32 # copy to *compute-offsets:word-slice
#c7 0/subop/copy 1/mod/*+disp8 5/rm32/.disp32 . . . 4/disp8 compute-offsets:word-slice/disp32 0/imm32 # copy to *(compute-offsets:word-slice+4)
ba/copy-to-EDX compute-offsets:word-slice/imm32
# next-word(line/ECX, word-slice/EDX)
52/push-EDX
51/push-ECX
e8/call next-word/disp32
# . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# if slice-empty?(word/EDX) break
# . EAX = slice-empty?(word/EDX)
52/push-EDX
e8/call slice-empty?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# . EAX == 1 ?
3d/compare-EAX-and 1/imm32
# . if so, break
#74/jump-if-equal $compute-offsets:word-loop:end/disp8
# if slice-starts-with?(word-slice, "#") continue
68/push "#"/imm32
52/push-EDX
e8/call slice-starts-with?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# . EAX == 1 ?
3d/compare-EAX-and 1/imm32
# . if so, continue
74/jump-if-equal $compute-offsets:word-loop/disp8
#TODO: implement is-label? and it's block
# if slice-equal?(word-slice/EDX, "==")
# . EAX = slice-equal?(word-slice/EDX, "==")
68/push "=="/imm32
52/push-EDX
e8/call slice-equal?/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# . EAX == 0 ?
3d/compare-EAX-and 0/imm32
# . if so, goto else
74/jump-if-equal $compute-offsets:else/disp8
# . or fallthrough
# next-word(line/ECX, curr-segment-name)
68/push compute-offsets:curr-segment-name/imm32
51/push-ECX
e8/call next-word/disp32
# . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
$compute-offsets:else:
# width/EAX = compute-width(word-slice/EDX)
52/push-EDX
e8/call compute-width/disp32
# . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# segment-offset += width
# . EBX = *segment-offset
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX compute-offsets:segment-offset/disp32 # copy *segment-offset to EBX
# . *segment-offset/EBX += EAX/width
03/add 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # add EAX to EBX
89/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX compute-offsets:segment-offset/disp32 # copy EBX to *compute-offsets:segment-offset
# file-offset += width
# . EBX = *file-offset
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX compute-offsets:file-offset/disp32 # copy *file-offset to EBX
# . *file-offset/EBX += EAX/width
03/add 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # add EAX to EBX
89/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX compute-offsets:file-offset/disp32 # copy EBX to *compute-offsets:file-offset
e9/jump $compute-offsets:line-loop/disp32
$compute-offsets:end:
# . reclaim locals
# . restore registers
5f/pop-to-EDI
5e/pop-to-ESI
5b/pop-to-EBX
5a/pop-to-EDX
59/pop-to-ECX
58/pop-to-EAX
# . epilog
89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP
5d/pop-to-EBP
@ -1678,6 +1809,11 @@ $p_align:
# compute the starting address for each segment
0x1000/imm32
compute-offsets:curr-segment-name: 0/imm32/start 0/imm32/end
compute-offsets:file-offset: 0/imm32
compute-offsets:segment-offset: 0/imm32
compute-offsets:word-slice: 0/imm32/start 0/imm32/end
_test-label-slice-start:
41/A
41/A
@ -1686,5 +1822,4 @@ _test-label-slice-end2:
3A/:
_test-label-slice-end1:
# . . vim:nowrap:textwidth=0

View File

@ -4,10 +4,9 @@
if [[ $2 == 'test-'* ]]
then
TEST_NAME=$2 envsubst '$TEST_NAME' < run_one_test.subx > /tmp/run_one_test.subx
FILES=$(ls [0-9]*.subx apps/subx-common.subx $1 |sort |uniq)
echo $FILES > /tmp/last_run_files
elif [[ -e /tmp/last_run_files ]]
export TEST_NAME=$2
echo $TEST_NAME > /tmp/last_test_run
elif [[ -e /tmp/last_test_run ]]
then
FILES=`cat /tmp/last_run_files`
else
@ -16,7 +15,12 @@ else
fi
set -e
# turn newlines into spaces
CFLAGS=$CFLAGS subx --debug translate $(echo $FILES) /tmp/run_one_test.subx -o /tmp/a.elf
if [[ $1 == */* ]]
then
CFLAGS=$CFLAGS ./subx --debug translate [0-9]*.subx apps/subx-common.subx $1 /tmp/run_one_test.subx -o /tmp/a.elf
else
# don't mention files twice
CFLAGS=$CFLAGS ./subx --debug translate [0-9]*.subx apps/subx-common.subx /tmp/run_one_test.subx -o /tmp/a.elf
fi
subx --debug --trace run /tmp/a.elf
./subx --debug --trace run /tmp/a.elf