diff options
author | Kartik Agaram <vc@akkartik.com> | 2018-09-21 13:44:16 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2018-09-21 13:44:16 -0700 |
commit | caaeccd68e2baf49c4df5ada5799cffcecb51c60 (patch) | |
tree | bd41ab2a45b490cc78b18c589cef3cf4d938c967 /subx/apps/factorial.subx | |
parent | 0828df68de1defe68d63fd19cd3ed76be09918c8 (diff) | |
download | mu-caaeccd68e2baf49c4df5ada5799cffcecb51c60.tar.gz |
4567 - support automated tests in SubX
All it takes is to code-generate a simple function called 'run_tests' that calls all functions starting with 'test_' one by one. I've temporarily switched the factorial app to run as a test. But that's temporary, because all the code to print '.' vs 'F' needs to get extracted out into a helper.
Diffstat (limited to 'subx/apps/factorial.subx')
-rw-r--r-- | subx/apps/factorial.subx | 86 |
1 files changed, 75 insertions, 11 deletions
diff --git a/subx/apps/factorial.subx b/subx/apps/factorial.subx index 31821dce..d71ea455 100644 --- a/subx/apps/factorial.subx +++ b/subx/apps/factorial.subx @@ -13,17 +13,18 @@ # 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 # main: - # prepare to make a call - 55/push . . . . . . . . # push EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # factorial(5) - 68/push . . . . . . . 5/imm32 # push 5 - e8/call . . . . . . factorial/disp32 - # discard arg - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add 4 to ESP - # clean up after call - 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 5d/pop . . . . . . . . # pop to EBP + e8/call run_tests/disp32 +#? # prepare to make a call +#? 55/push . . . . . . . . # push EBP +#? 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP +#? # factorial(5) +#? 68/push . . . . . . . 5/imm32 # push 5 +#? e8/call . . . . . . factorial/disp32 +#? # discard arg +#? 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add 4 to ESP +#? # clean up after call +#? 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP +#? 5d/pop . . . . . . . . # pop to EBP # exit(EAX) 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX @@ -59,4 +60,67 @@ factorial: $factorial:exit: c3/return +test_factorial: + # factorial(5) + # push arg + 68/push . . . . . . . 5/imm32 # push 5 + # call + e8/call . . . . . . factorial/disp32 + # discard arg + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add 4 to ESP + # if EAX == 120 + 3d/compare . . . . . . . 0x78/imm32/120 # compare EAX with 120 + 75/jump-if-unequal . . . . . . $test_factorial:else/disp8 + # print('.') + # push args + 68/push . . . . . . . Test_passed/imm32 + # call + e8/call . . . . . . write_stderr/disp32 + # discard arg + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add 4 to ESP + # return + c3/return + # else: +$test_factorial:else: + # print('F') + # push args + 68/push . . . . . . . Test_failed/imm32 + # call + e8/call . . . . . . write_stderr/disp32 + # discard arg + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add 4 to ESP + # end + c3/return + +## helpers + +write_stderr: # s : (address array byte) -> <void> + # write(2/stderr, (data) s+4, (size) *s) + # fd = 2 (stderr) + bb/copy . . . . . . . 2/imm32 # copy 2 to EBX + # x = s+4 + 8b/copy 1/mod/*+disp8 4/rm32/SIB 4/base/ESP 4/index/none . 1/r32/ECX 4/disp8 . # copy *(ESP+4) to ECX + 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add 4 to ECX + # size = *s + 8b/copy 1/mod/*+disp8 4/rm32/SIB 4/base/ESP 4/index/none . 2/r32/EDX 4/disp8 . # copy *(ESP+4) to EDX + 8b/copy 0/mod/indirect 2/rm32/EDX . . . 2/r32/EDX . . # copy *EDX to EDX + # call write() + b8/copy . . . . . . . 4/imm32/write # copy 1 to EAX + cd/syscall . . . . . . . 0x80/imm8 # int 80h + # end + c3/return + +== data +Test_passed: + # size + 01 00 00 00 + # data + 2e/dot + +Test_failed: + # size + 01 00 00 00 + # data + 46/F + # vim:ft=subx:nowrap:so=0 |