From 8815cf7d57e738731dfc43680b4eccbaef9d822c Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 14 Sep 2020 22:26:56 -0700 Subject: 6780 --- 118parse-hex.subx | 938 ------------------------------------------------------ 1 file changed, 938 deletions(-) delete mode 100644 118parse-hex.subx (limited to '118parse-hex.subx') diff --git a/118parse-hex.subx b/118parse-hex.subx deleted file mode 100644 index ebbd4e4e..00000000 --- a/118parse-hex.subx +++ /dev/null @@ -1,938 +0,0 @@ -# some utilities for converting numbers from hex -# lowercase letters only for now - -== 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 - -is-hex-int?: # in: (addr slice) -> 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 - 53/push-ebx - # ecx = s - 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx - # edx = s->end - 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx - # var curr/ecx: (addr byte) = s->start - 8b/copy 0/mod/indirect 1/rm32/ecx . . . 1/r32/ecx . . # copy *ecx to ecx - # if s is empty return false - b8/copy-to-eax 0/imm32/false - 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx - 73/jump-if-addr>= $is-hex-int?:end/disp8 - # skip past leading '-' - # . if (*curr == '-') ++curr - 31/xor 3/mod/direct 3/rm32/ebx . . . 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 . . . . . 0x2d/imm32/- # compare ebx - 75/jump-if-!= $is-hex-int?:initial-0/disp8 - # . ++curr - 41/increment-ecx - # skip past leading '0x' -$is-hex-int?:initial-0: - # . if (*curr != '0') jump to loop - 31/xor 3/mod/direct 3/rm32/ebx . . . 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 . . . . . 0x30/imm32/0 # compare ebx - 75/jump-if-!= $is-hex-int?:loop/disp8 - # . ++curr - 41/increment-ecx -$is-hex-int?:initial-0x: - # . 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>= $is-hex-int?:true/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 3/rm32/ebx . . . 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-!= $is-hex-int?:loop/disp8 - # . ++curr - 41/increment-ecx -$is-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>= $is-hex-int?:true/disp8 - # var eax: boolean = is-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 is-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-= $is-hex-int?:end/disp8 - # ++curr - 41/increment-ecx - # loop - eb/jump $is-hex-int?:loop/disp8 -$is-hex-int?:true: - # return true - b8/copy-to-eax 1/imm32/true -$is-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-is-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 = is-hex-int?(slice) - # . . push args - 51/push-ecx - # . . call - e8/call is-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-is-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-is-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 = is-hex-int?(slice) - # . . push args - 51/push-ecx - # . . call - e8/call is-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-is-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-is-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 = is-hex-int?(slice) - # . . push args - 51/push-ecx - # . . call - e8/call is-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-is-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-is-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 = is-hex-int?(slice) - # . . push args - 51/push-ecx - # . . call - e8/call is-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-is-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-is-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 = is-hex-int?(slice) - # . . push args - 51/push-ecx - # . . call - e8/call is-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-is-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-is-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 = is-hex-int?(slice) - # . . push args - 51/push-ecx - # . . call - e8/call is-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-is-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-is-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 = is-hex-int?(slice) - # . . push args - 51/push-ecx - # . . call - e8/call is-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-is-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-is-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 = is-hex-int?(slice) - # . . push args - 51/push-ecx - # . . call - e8/call is-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-is-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 - # edx = 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, 0x34a, 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, 0x34a, 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 - -is-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-< $is-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-<= $is-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-> $is-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->= $is-hex-digit?:true/disp8 - # otherwise return false -$is-hex-digit?:false: - b8/copy-to-eax 0/imm32/false - eb/jump $is-hex-digit?:end/disp8 -$is-hex-digit?:true: - b8/copy-to-eax 1/imm32/true -$is-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 = is-hex-digit?(0x2f) - # . . push args - 68/push 0x2f/imm32 - # . . call - e8/call is-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 = is-hex-digit?(0x30) - # . . push args - 68/push 0x30/imm32 - # . . call - e8/call is-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 = is-hex-digit?(0x39) - # . . push args - 68/push 0x39/imm32 - # . . call - e8/call is-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 = is-hex-digit?(0x3a) - # . . push args - 68/push 0x3a/imm32 - # . . call - e8/call is-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 = is-hex-digit?(0x61) - # . . push args - 68/push 0x61/imm32 - # . . call - e8/call is-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 = is-hex-digit?(0x66) - # . . push args - 68/push 0x66/imm32 - # . . call - e8/call is-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 = is-hex-digit?(0x67) - # . . push args - 68/push 0x67/imm32 - # . . call - e8/call is-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 -- cgit 1.4.1-2-gfad0