This commit is contained in:
Kartik Agaram 2018-12-06 11:11:43 -08:00
parent e9909be374
commit 272408b06b
2 changed files with 137 additions and 1 deletions

Binary file not shown.

View File

@ -44,6 +44,7 @@
#? e8/call test-scan-next-byte/disp32
#? e8/call test-scan-next-byte-handles-eof/disp32
#? e8/call test-scan-next-byte-skips-comment/disp32
#? e8/call test-convert-next-hex-byte/disp32
e8/call run-tests/disp32
8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX
eb/jump $main:end/disp8
@ -96,7 +97,7 @@ convert-next-hex-byte: # in : (address buffered-file), err : (address buffered-
# if (EAX == 0xffffffff) return
# ECX = EAX
# EAX = scan-next-byte(in, err, ed)
# if (EAX == 0xffffffff) error("partial byte found")
# if (EAX == 0xffffffff) error("partial byte found.")
# ECX = (ECX << 8) | EAX
# return
#
@ -104,13 +105,148 @@ convert-next-hex-byte: # in : (address buffered-file), err : (address buffered-
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# . save registers
51/push-ECX
# EAX = scan-next-byte(in, err, ed)
# . . push args
ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16)
ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12)
ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8)
# . . call
e8/call scan-next-byte/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# if (EAX == 0xffffffff) return
81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0xffffffff/imm32 # compare EAX
74/jump-if-equal $convert-next-hex-byte:end/disp8
# ECX = EAX
89/copy 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # copy EAX to ECX
# EAX = scan-next-byte(in, err, ed)
# . . push args
ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16)
ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12)
ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 8/disp8 . # push *(EBP+8)
# . . call
e8/call scan-next-byte/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# if (EAX == 0xffffffff) error(ed, err, "partial byte found.")
81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0xffffffff/imm32 # compare EAX
75/jump-if-not-equal $convert-next-hex-byte:convert/disp8
# . error-byte(ed, err, msg, '.') # reusing error-byte to avoid creating _yet_ another helper
# . . push args
68/push 0x2e/imm32/period/dummy
68/push "convert-next-hex-byte: partial byte found"/imm32
ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0xc/disp8 . # push *(EBP+12)
ff 6/subop/push 1/mod/*+disp8 4/rm32/sib 5/base/EBP 4/index/none . . 0x10/disp8 . # push *(EBP+16)
# . . call
e8/call error-byte/disp32 # never returns
$convert-next-hex-byte:convert:
# EAX = (EAX << 8) | ECX
# . EAX <<= 8
c1/shift 4/subop/left 3/mod/direct 0/rm32/EAX . . . . . 8/imm8 # shift EAX left by 8 bits
# . EAX |= ECX
09/or 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # EAX = bitwise OR with ECX
$convert-next-hex-byte:end:
# . restore registers
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-convert-next-hex-byte:
# - check that the first two bytes of the input are assembled into the resulting number
# This test uses exit-descriptors. Use EBP for setting up local variables.
55/push-EBP
89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP
# clear all streams
# . 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
# . clear-stream(_test-buffered-file+4)
# . . push args
b8/copy-to-EAX _test-buffered-file/imm32
05/add-to-EAX 4/imm32
50/push-EAX
# . . call
e8/call clear-stream/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP
# . clear-stream(_test-error-stream)
# . . push args
68/push _test-error-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
# initialize '_test-stream' to "abc"
# . 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
# initialize exit-descriptor 'ed' for the call to 'convert-next-hex-byte' below
# . var ed/ECX : exit-descriptor
81 5/subop/subtract 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # subtract from ESP
8d/copy-address 0/mod/indirect 4/rm32/sib 4/base/ESP 4/index/none . 1/r32/ECX . . # copy ESP to ECX
# . tailor-exit-descriptor(ed, 12)
# . . push args
68/push 0xc/imm32/nbytes-of-args-for-convert-next-hex-byte
51/push-ECX/ed
# . . call
e8/call tailor-exit-descriptor/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# EAX = convert-next-hex-byte(_test-buffered-file, _test-error-stream, ed)
# . . push args
51/push-ECX/ed
68/push _test-error-stream/imm32
68/push _test-buffered-file/imm32
# . . call
e8/call convert-next-hex-byte/disp32
# registers except ESP may be clobbered at this point
# pop args to convert-next-hex-bytes
# . . discard first 2 args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
# . . restore ed
59/pop-to-ECX
# check that convert-next-hex-byte didn't abort
# . check-ints-equal(ed->value, 0, msg)
# . . push args
68/push "F - test-convert-next-hex-byte: unexpected abort"/imm32
68/push 0/imm32
# . . push ed->value
ff 6/subop/push 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 . # push *(ECX+4)
# . . call
e8/call check-ints-equal/disp32
# . . discard args
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP
# return if abort
81 7/subop/compare 1/mod/*+disp8 1/rm32/ECX . . . . 4/disp8 0/imm32 # compare *(ECX+4)
75/jump-if-not-equal $test-convert-next-hex-byte:end/disp8
# check-ints-equal(EAX, 0x61/a 0x62/b, msg)
# . . push args
68/push "F - test-convert-next-hex-byte"/imm32
68/push 0x6261/imm32/ab
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
$test-convert-next-hex-byte:end:
# . epilog
# don't restore ESP from EBP; manually reclaim locals
81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP
5d/pop-to-EBP
c3/return
# read whitespace until a hex byte, and return it
# return 0xffffffff if file ends without finding a hex byte
# on '#' skip all bytes until newline