about summary refs log tree commit diff stats
<
UML
===

The uml documents can be opened with bouml, althought there's
not much useful, up-to-date information.
Commit message (Collapse)AuthorAgeFilesLines
...
| | * .Kartik Agaram2019-07-012-3/+3
| | | | | | | | | | | | Fix some comments.
>Kartik Agaram2019-06-282-12/+155 | | | | | | | | | | | | | | | Flesh out final test some more. We also now have a new family of primitives for writing non-strings to input streams in tests. | | * fix layout and some commentsKartik Agaram2019-06-171-43/+76 | | | | | | | | | | | | When two assertions don't share context they're clearer when separated. | | * .Kartik Agaram2019-06-171-160/+160 | | | | | | | | | | | | | | | | | | | | | Move tests adjacent to function being tested. Originally I didn't expect the helpers to get their own tests. But even so, arguably the original layout was less clear. | | * .Kartik Agaram2019-06-171-6/+6 | | | | | * .Kartik Agaram2019-06-171-13/+21 | | | | | | | | | | | | | | | Make a test a little less confusing; stream was initialized with data filled in but outside bounds. | | * fix two hangs in trace-scanKartik Agaram2019-06-171-6/+27 | | | | | | | | | | | | | | | 1. skip-next-line should skip newline 2. trace-scan was falling into an infinite loop on non-matching lines | | * move test data to bottom of fileKartik Agaram2019-06-171-28/+30 | | | | | * bugfix to opcode 8f; it requires subopsKartik Agaram2019-06-171-2/+1 | | | | | * support `CFLAGS=-g ./run_one_test.sh ...`Kartik Agaram2019-06-171-2/+3 | | | | | * .Kartik Agaram2019-06-161-0/+1 | | | | | | | | | | | | | | | | | | | | | | | | This missing line was giving the illusion that all was well when running a single test at a time. Now trace-scan still hangs, but it hangs reliably. And it's clear what the logic error is. | | * fix bug in skip-next-linenc2019-06-151-1/+2 | | | | | * implement next-line-matches?nc2019-06-151-8/+133 | | | | | * implement skip-next-linenc2019-06-151-9/+88 | | | | | * pseudocode skeletons for all functionsKartik Agaram2019-06-132-7/+152 | | | | | * .Kartik Agaram2019-06-131-1/+36 | | | | | * flesh out survey testsKartik Agaram2019-06-122-15/+219 | | | | | * .Kartik Agaram2019-06-121-1/+8 | | | | | | | | | | | | Fix a bug when running tests singly in the 'SubX standard library'. | | * .Kartik Agaram2019-06-1219-114/+0 | | | | | | | | | | | | | | | Now that we don't have to edit code to run a single test, delete that commented out fragment everywhere. | | * .Kartik Agaram2019-06-111-0/+1 | | | | | * rerun most recent test if cursor not in a testKartik Agaram2019-06-112-1/+15 | | | | | * fork vimrc for Mu and SubXKartik Agaram2019-06-112-65/+93 | | | | | | | | | | | | | | | I checked if we needed to bring back anything since commit 3976, but the only difference is dropping the :(scenario) DSL. | | * only open the trace if test failsKartik Agaram2019-06-111-2/+16 | | | | | * new Vim convenience macroKartik Agaram2019-06-113-0/+40 | | | | | | | | | | | | Runs test under cursor and opens its trace. | | * .Kartik Agaram2019-06-114-100/+0 | | | | | * .Kartik Agaram2019-06-091-7/+7 | | | | | * .Kartik Agaram2019-06-081-3/+3 | | | | | * .Kartik Agaram2019-06-081-1/+1 | | | | | * fix stale docsKartik Agaram2019-06-081-11/+5 | | | | | * snapshot of trace primitivesKartik Agaram2019-06-081-0/+346 | | | | | * .Kartik Agaram2019-06-089-73/+61 | | | | | * Fix stale `initialize-trace-stream`Kartik Agaram2019-06-0810-8/+287 | | | | | * .Kartik Agaram2019-06-082-0/+0 | | | | | * .Kartik Agaram2019-06-089-22/+17 | | | | | | | | | | | | Simplify `string-equal`. | | * implement compute-widthnc2019-06-082-270/+357 | | | | | * added tests for compute-widthnc2019-06-081-0/+112 | | | | | * start fleshing out trace support some moreKartik Agaram2019-06-058-5/+23 | | | | | | | | | | | | | | | I think the path to readable tests for survey.subx passes through white-box tests. | | * .Kartik Agaram2019-05-2712-136/+143 | | | | | | | | | | | | | | | | | | 'get-or-insert-stream' is now the more generic 'get-or-insert' that can handle tables of any value type. But callers have to be careful to cast values to the right type. | | * .Kartik Agaram2019-05-266-385/+278 | | | | | * new primitive: check-array-equalKartik Agaram2019-05-268-0/+68 | | | | | * new primitive: parse-array-of-intsKartik Agaram2019-05-2514-8/+355 | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Mostly for tests. For every new type we want to compare in a test, we're now going to start using some primitive that can parse its value from string. In this manner we can get syntax for literals in machine code. Open question: parsing aggregates of aggregates. Like an array of structs. This is the first time we allocate from the heap in standard library tests. So we now need to start initializing the heap in all our apps. | | * .Kartik Agaram2019-05-2511-18/+17 | | | | | | | | | | | | | | | hoist 'Heap' variable into the std library in anticipation of the parse-array-of-ints primitive. . 3/r32/ebx . . # clear ebx 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 3/r32/BL . . # copy byte at *ecx to BL 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x78/imm32/x # compare ebx 75/jump-if-!= $hex-int?:loop/disp8 # . ++curr 41/increment-ecx $hex-int?:loop: # if (curr >= in->end) return true 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-addr>= $hex-int?:true/disp8 # var eax: boolean = hex-digit?(*curr) # . . push args 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 50/push-eax # . . call e8/call hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # if (eax == false) return false 3d/compare-eax-and 0/imm32/false 74/jump-if-= $hex-int?:end/disp8 # ++curr 41/increment-ecx # loop eb/jump $hex-int?:loop/disp8 $hex-int?:true: # return true b8/copy-to-eax 1/imm32/true $hex-int?:end: # . restore registers 5b/pop-to-ebx 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-hex-int: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "34" b8/copy-to-eax "34"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = hex-int?(slice) # . . push args 51/push-ecx # . . call e8/call hex-int?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-hex-int"/imm32 68/push 1/imm32/true 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-hex-int-handles-letters: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "34a" b8/copy-to-eax "34a"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = hex-int?(slice) # . . push args 51/push-ecx # . . call e8/call hex-int?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-hex-int-handles-letters"/imm32 68/push 1/imm32/true 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-hex-int-with-trailing-char: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "34q" b8/copy-to-eax "34q"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = hex-int?(slice) # . . push args 51/push-ecx # . . call e8/call hex-int?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0, msg) # . . push args 68/push "F - test-hex-int-with-trailing-char"/imm32 68/push 0/imm32/false 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-hex-int-with-leading-char: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "q34" b8/copy-to-eax "q34"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = hex-int?(slice) # . . push args 51/push-ecx # . . call e8/call hex-int?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0, msg) # . . push args 68/push "F - test-hex-int-with-leading-char"/imm32 68/push 0/imm32/false 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-hex-int-empty: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # var slice/ecx: slice = "" 68/push 0/imm32 68/push 0/imm32 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = hex-int?(slice) # . . push args 51/push-ecx # . . call e8/call hex-int?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0, msg) # . . push args 68/push "F - test-hex-int-empty"/imm32 68/push 0/imm32/false 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-hex-int-handles-0x-prefix: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "0x3a" b8/copy-to-eax "0x3a"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = hex-int?(slice) # . . push args 51/push-ecx # . . call e8/call hex-int?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-hex-int-handles-0x-prefix"/imm32 68/push 1/imm32/true 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-hex-int-handles-negative: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "-34a" b8/copy-to-eax "-34a"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = hex-int?(slice) # . . push args 51/push-ecx # . . call e8/call hex-int?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-hex-int-handles-negative"/imm32 68/push 1/imm32/true 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-hex-int-handles-negative-0x-prefix: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "-0x3a" b8/copy-to-eax "-0x3a"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = hex-int?(slice) # . . push args 51/push-ecx # . . call e8/call hex-int?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-hex-int-handles-negative-0x-prefix"/imm32 68/push 1/imm32/true 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 parse-hex-int: # in: (addr array byte) -> result/eax: int # . 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 # eax = in 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax # var curr/ecx: (addr byte) = &in->data 8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy eax+4 to ecx # var max/edx: (addr byte) = &in->data[in->size] # . edx = in->size 8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax to edx # . edx = in->data + in->size 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 2/index/edx . 2/r32/edx 4/disp8 . # copy eax+edx+4 to edx # return parse-hex-int-helper(curr, max) # . . push args 52/push-edx 51/push-ecx # . . call e8/call parse-hex-int-helper/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp $parse-hex-int:end: # . restore registers 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 parse-hex-int-from-slice: # in: (addr slice) -> result/eax: int # . 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 # ecx = in 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # var max/edx: (addr byte) = in->end 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx # var curr/ecx: (addr byte) = in->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 1/r32/ecx . . # copy *ecx to ecx # return parse-hex-int-helper(curr, max) # . . push args 52/push-edx 51/push-ecx # . . call e8/call parse-hex-int-helper/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp $parse-hex-int-from-slice:end: # . restore registers 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 parse-hex-int-helper: # start: (addr byte), end: (addr byte) -> result/eax: int # . 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 53/push-ebx 56/push-esi # var curr/ecx: (addr byte) = start 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # edx = max 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx # var result/ebx: int = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx # var negate?/esi: boolean = false 31/xor 3/mod/direct 6/rm32/esi . . . 6/r32/esi . . # clear esi $parse-hex-int-helper:negative: # if (*curr == '-') ++curr, negate = true 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 3d/compare-eax-and 0x2d/imm32/- 75/jump-if-!= $parse-hex-int-helper:initial-0/disp8 # . ++curr 41/increment-ecx # . negate = true be/copy-to-esi 1/imm32/true $parse-hex-int-helper:initial-0: # skip past leading '0x' # . if (*curr != '0') jump to loop 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 3d/compare-eax-and 0x30/imm32/0 75/jump-if-!= $parse-hex-int-helper:loop/disp8 # . ++curr 41/increment-ecx $parse-hex-int-helper:initial-0x: # . if (curr >= in->end) return result 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-addr>= $parse-hex-int-helper:end/disp8 # . if (*curr != 'x') jump to loop # the previous '0' is still valid so doesn't need to be checked again 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 3d/compare-eax-and 0x78/imm32/x 75/jump-if-!= $parse-hex-int-helper:loop/disp8 # . ++curr 41/increment-ecx $parse-hex-int-helper:loop: # if (curr >= in->end) break 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-addr>= $parse-hex-int-helper:negate/disp8 # var eax: int = from-hex-char(*curr) # . . copy arg to eax 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL # . . call e8/call from-hex-char/disp32 # result = result * 16 + eax c1/shift 4/subop/left 3/mod/direct 3/rm32/ebx . . . . . 4/imm8 # shift ebx left by 4 bits 01/add 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # add eax to ebx # ++curr 41/increment-ecx # loop eb/jump $parse-hex-int-helper:loop/disp8 $parse-hex-int-helper:negate: # if (negate?) result = -result 81 7/subop/compare 3/mod/direct 6/rm32/esi . . . . . 0/imm32/false # compare esi 74/jump-if-= $parse-hex-int-helper:end/disp8 f7 3/subop/negate 3/mod/direct 3/rm32/ebx . . . . . . # negate ebx $parse-hex-int-helper:end: # return result 89/copy 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # copy ebx to eax # . restore registers 5e/pop-to-esi 5b/pop-to-ebx 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-parse-hex-int-from-slice-single-digit: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "a" b8/copy-to-eax "a"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = parse-hex-int-from-slice(slice) # . . push args 51/push-ecx # . . call e8/call parse-hex-int-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0xa, msg) # . . push args 68/push "F - test-parse-hex-int-from-slice-single-digit"/imm32 68/push 0xa/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-parse-hex-int-from-slice-multi-digit: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "34a" b8/copy-to-eax "34a"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = parse-hex-int-from-slice(slice) # . . push args 51/push-ecx # . . call e8/call parse-hex-int-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0x34a, msg) # . . push args 68/push "F - test-parse-hex-int-from-slice-multi-digit"/imm32 68/push 0x34a/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-parse-hex-int-from-slice-0x-prefix: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "0x34" b8/copy-to-eax "0x34"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = parse-hex-int-from-slice(slice) # . . push args 51/push-ecx # . . call e8/call parse-hex-int-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0x34, msg) # . . push args 68/push "F - test-parse-hex-int-from-slice-0x-prefix"/imm32 68/push 0x34/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-parse-hex-int-from-slice-zero: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "0" b8/copy-to-eax "0"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = parse-hex-int-from-slice(slice) # . . push args 51/push-ecx # . . call e8/call parse-hex-int-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0, msg) # . . push args 68/push "F - test-parse-hex-int-from-slice-zero"/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-parse-hex-int-from-slice-0-prefix: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "03" b8/copy-to-eax "03"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = parse-hex-int-from-slice(slice) # . . push args 51/push-ecx # . . call e8/call parse-hex-int-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0x3, msg) # . . push args 68/push "F - test-parse-hex-int-from-slice-0-prefix"/imm32 68/push 0x3/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-parse-hex-int-from-slice-negative: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # (eax..ecx) = "-03" b8/copy-to-eax "-03"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 # var slice/ecx: slice = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # eax = parse-hex-int-from-slice(slice) # . . push args 51/push-ecx # . . call e8/call parse-hex-int-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, -3, msg) # . . push args 68/push "F - test-parse-hex-int-from-slice-negative"/imm32 68/push -3/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 hex-digit?: # c: 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 # ecx = c 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # return false if c < '0' 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x30/imm32 # compare ecx 7c/jump-if-< $hex-digit?:false/disp8 # return true if c <= '9' 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x39/imm32 # compare ecx 7e/jump-if-<= $hex-digit?:true/disp8 # drop case 25/and-eax-with 0x5f/imm32 # return false if c > 'f' 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x66/imm32 # compare ecx 7f/jump-if-> $hex-digit?:false/disp8 # return true if c >= 'a' 81 7/subop/compare 3/mod/direct 1/rm32/ecx . . . . . 0x61/imm32 # compare ecx 7d/jump-if->= $hex-digit?:true/disp8 # otherwise return false $hex-digit?:false: b8/copy-to-eax 0/imm32/false eb/jump $hex-digit?:end/disp8 $hex-digit?:true: b8/copy-to-eax 1/imm32/true $hex-digit?:end: # . restore registers 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-hex-below-0: # eax = hex-digit?(0x2f) # . . push args 68/push 0x2f/imm32 # . . call e8/call hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0, msg) # . . push args 68/push "F - test-hex-below-0"/imm32 68/push 0/imm32/false 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 c3/return test-hex-0-to-9: # eax = hex-digit?(0x30) # . . push args 68/push 0x30/imm32 # . . call e8/call hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-hex-at-0"/imm32 68/push 1/imm32/true 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 = hex-digit?(0x39) # . . push args 68/push 0x39/imm32 # . . call e8/call hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-hex-at-9"/imm32 68/push 1/imm32/true 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 c3/return test-hex-above-9-to-a: # eax = hex-digit?(0x3a) # . . push args 68/push 0x3a/imm32 # . . call e8/call hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0, msg) # . . push args 68/push "F - test-hex-above-9-to-a"/imm32 68/push 0/imm32/false 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 c3/return test-hex-a-to-f: # eax = hex-digit?(0x61) # . . push args 68/push 0x61/imm32 # . . call e8/call hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-hex-at-a"/imm32 68/push 1/imm32/true 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 = hex-digit?(0x66) # . . push args 68/push 0x66/imm32 # . . call e8/call hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 1, msg) # . . push args 68/push "F - test-hex-at-f"/imm32 68/push 1/imm32/true 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 c3/return test-hex-above-f: # eax = hex-digit?(0x67) # . . push args 68/push 0x67/imm32 # . . call e8/call hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # check-ints-equal(eax, 0, msg) # . . push args 68/push "F - test-hex-above-f"/imm32 68/push 0/imm32/false 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 c3/return from-hex-char: # in/eax: byte -> out/eax: nibble $from-hex-char:check0: # if (eax < '0') goto abort 3d/compare-eax-with 0x30/imm32/0 7c/jump-if-< $from-hex-char:abort/disp8 $from-hex-char:check1: # if (eax > 'f') goto abort 3d/compare-eax-with 0x66/imm32/f 7f/jump-if-> $from-hex-char:abort/disp8 $from-hex-char:check2: # if (eax > '9') goto next check 3d/compare-eax-with 0x39/imm32/9 7f/jump-if-> $from-hex-char:check3/disp8 $from-hex-char:digit: # return eax - '0' 2d/subtract-from-eax 0x30/imm32/0 c3/return $from-hex-char:check3: # if (eax < 'a') goto abort 3d/compare-eax-with 0x61/imm32/a 7c/jump-if-< $from-hex-char:abort/disp8 $from-hex-char:letter: # return eax - ('a'-10) 2d/subtract-from-eax 0x57/imm32/a-10 c3/return $from-hex-char:abort: # . _write(2/stderr, error) # . . push args 68/push "invalid hex char: "/imm32 68/push 2/imm32/stderr # . . call e8/call _write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # . clear-stream($Stderr->buffer) # . . save eax 50/push-eax # . . push args 68/push $Stderr->buffer/imm32 # . . call e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # . . restore eax 58/pop-to-eax # . write-int32-hex-buffered(Stderr, eax) # . . push args 50/push-eax 68/push Stderr/imm32 # . . call e8/call write-int32-hex-buffered/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # . flush(Stderr) # . . push args 68/push Stderr/imm32 # . . call e8/call flush/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # . _write(2/stderr, "\n") # . . push args 68/push Newline/imm32 68/push 2/imm32/stderr # . . call e8/call _write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # . syscall(exit, 1) bb/copy-to-ebx 1/imm32 e8/call syscall_exit/disp32 # never gets here # . . vim:nowrap:textwidth=0