From 03c6f1d3858ff0fdb6af6ce4b61bea51f16b33be Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 2 Feb 2019 22:05:11 -0800 Subject: 4949 --- subx/063hex.subx | 809 ------------------------------------------------------- 1 file changed, 809 deletions(-) delete mode 100644 subx/063hex.subx (limited to 'subx/063hex.subx') diff --git a/subx/063hex.subx b/subx/063hex.subx deleted file mode 100644 index 6ba2ef7e..00000000 --- a/subx/063hex.subx +++ /dev/null @@ -1,809 +0,0 @@ -# some utilities for converting numbers to/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 - -# main: - e8/call run-tests/disp32 # 'run-tests' is a function created automatically by SubX. It calls all functions that start with 'test-'. - # syscall(exit, Num-test-failures) - 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/EBX Num-test-failures/disp32 # copy *Num-test-failures to EBX - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - -is-hex-int?: # in : (address slice) -> EAX : boolean - # . prolog - 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 - # curr/ECX = 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 - 7d/jump-if-greater-or-equal $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-not-equal $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-not-equal $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 - 7d/jump-if-greater-or-equal $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-not-equal $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 - 7d/jump-if-greater-or-equal $is-hex-int?:true/disp8 - # EAX = 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-with-EAX 0/imm32 - 74/jump-if-equal $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 - # . epilog - 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: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "34" - 68/push _test-slice-hex-int-end/imm32 - 68/push _test-slice-hex-int/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, 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 - # . epilog - 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: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "34a" - 68/push _test-slice-hex-int-letters-end/imm32 - 68/push _test-slice-hex-int-letters/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, 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 - # . epilog - 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: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "34q" - 68/push _test-slice-digits-and-char-end/imm32 - 68/push _test-slice-digits-and-char/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-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 - # . epilog - 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: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "q34" - 68/push _test-slice-char-and-digits-end/imm32 - 68/push _test-slice-char-and-digits/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-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 - # . epilog - 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: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "" - 68/push _test-slice-empty-end/imm32 - 68/push _test-slice-empty/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 - # . epilog - 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: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "0x3a" - 68/push _test-slice-hex-int-with-0x-prefix-end/imm32 - 68/push _test-slice-hex-int-with-0x-prefix/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, 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 - # . epilog - 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: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "-34a" - 68/push _test-slice-hex-int-letters-end/imm32 - 68/push _test-slice-hex-int-letters-negative/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, 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 - # . epilog - 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: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "-0x3a" - 68/push _test-slice-hex-int-with-0x-prefix-end/imm32 - 68/push _test-slice-hex-int-with-0x-prefix-negative/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, 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 - # . epilog - 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 : (address slice) -> result/EAX - # . prolog - 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 - # result/EBX = 0 - 31/xor 3/mod/direct 3/rm32/EBX . . . 3/r32/EBX . . # clear 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 - # curr/ECX = s->start - 8b/copy 0/mod/indirect 1/rm32/ECX . . . 1/r32/ECX . . # copy *ECX to ECX - # negate?/ESI = false - 31/xor 3/mod/direct 6/rm32/ESI . . . 6/r32/ESI . . # clear ESI -$parse-hex-int:negative: - # . if (*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 - 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0x2d/imm32/- # compare EAX - 75/jump-if-not-equal $parse-hex-int:initial-0/disp8 - # . ++curr - 41/increment-ECX - # . negate = true - be/copy-to-ESI 1/imm32/true -$parse-hex-int: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 - 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0x30/imm32/0 # compare EAX - 75/jump-if-not-equal $parse-hex-int:loop/disp8 - # . ++curr - 41/increment-ECX -$parse-hex-int:initial-0x: - # . if (curr >= in->end) return result - 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX - 7d/jump-if-greater-or-equal $parse-hex-int: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 - 81 7/subop/compare 3/mod/direct 0/rm32/EAX . . . . . 0x78/imm32/x # compare EAX - 75/jump-if-not-equal $parse-hex-int:loop/disp8 - # . ++curr - 41/increment-ECX -$parse-hex-int:loop: - # if (curr >= in->end) break - 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX - 7d/jump-if-greater-or-equal $parse-hex-int:negate/disp8 - # EAX = 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:loop/disp8 -$parse-hex-int:negate: - 81 7/subop/compare 3/mod/direct 6/rm32/ESI . . . . . 0/imm32 # compare ESI - 74/jump-if-equal $parse-hex-int:end/disp8 - f7 3/subop/negate 3/mod/direct 3/rm32/EBX . . . . . . # negate EBX -$parse-hex-int:end: - 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 - # . epilog - 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-single-digit: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "a" - 68/push _test-slice-hex-int-single-letter-end/imm32 - 68/push _test-slice-hex-int-single-letter/imm32 - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = parse-hex-int(slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-hex-int/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-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 - # . epilog - 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-multi-digit: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "34a" - 68/push _test-slice-hex-int-letters-end/imm32 - 68/push _test-slice-hex-int-letters/imm32 - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = parse-hex-int(slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-hex-int/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-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 - # . epilog - 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-0x-prefix: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "0x34" - 68/push _test-slice-hex-int-with-0x-prefix-end/imm32 - 68/push _test-slice-hex-int-with-0x-prefix/imm32 - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = parse-hex-int(slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-hex-int/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-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 - # . epilog - 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-zero: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "0" - 68/push _test-slice-hex-int-zero-end/imm32 - 68/push _test-slice-hex-int-zero/imm32 - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = parse-hex-int(slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-hex-int/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-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 - # . epilog - 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-0-prefix: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "03" - 68/push _test-slice-hex-int-with-0-prefix-end/imm32 - 68/push _test-slice-hex-int-with-0-prefix/imm32 - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = parse-hex-int(slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-hex-int/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-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 - # . epilog - 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-negative: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = "-03" - 68/push _test-slice-hex-int-negative-with-0-prefix-end/imm32 - 68/push _test-slice-hex-int-negative-with-0-prefix/imm32 - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = parse-hex-int(slice) - # . . push args - 51/push-ECX - # . . call - e8/call parse-hex-int/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # check-ints-equal(EAX, 0xfffffffd, msg) - # . . push args - 68/push "F - test-parse-hex-int-negative"/imm32 - 68/push 0xfffffffd/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 - # . epilog - 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 -> EAX : boolean - # . prolog - 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' - b8/copy-to-EAX 0/imm32/false - 81 7/subop/compare 3/mod/direct 1/rm32/ECX . . . . . 0x30/imm32 # compare ECX - 7c/jump-if-lesser $is-hex-digit?:end/disp8 - # return false if c > 'f' - 81 7/subop/compare 3/mod/direct 1/rm32/ECX . . . . . 0x66/imm32 # compare ECX - 7f/jump-if-greater $is-hex-digit?:end/disp8 - # return true if c <= '9' - b8/copy-to-EAX 1/imm32/true - 81 7/subop/compare 3/mod/direct 1/rm32/ECX . . . . . 0x39/imm32 # compare ECX - 7e/jump-if-lesser-or-equal $is-hex-digit?:end/disp8 - # return true if c >= 'a' - 81 7/subop/compare 3/mod/direct 1/rm32/ECX . . . . . 0x61/imm32 # compare ECX - 7d/jump-if-greater-or-equal $is-hex-digit?:end/disp8 - # otherwise return false - b8/copy-to-EAX 0/imm32/false -$is-hex-digit?: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-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 : num - # no error checking; accepts argument in EAX - # if EAX <= '9' return EAX - '0' - 3d/compare-EAX 0x39/imm32/9 - 7f/jump-if-greater $from-hex-char:else/disp8 - 2d/subtract-from-EAX 0x30/imm32/0 - c3/return -$from-hex-char:else: - # otherwise return EAX - 'a' + 10 - 2d/subtract-from-EAX 0x57/imm32/a-10 - c3/return - -to-hex-char: # in/EAX : nibble -> out/EAX : byte - # no error checking; accepts argument in EAX - # if EAX <= 9 return EAX + '0' - 3d/compare-EAX 0x9/imm32/9 - 7f/jump-if-greater $to-hex-char:else/disp8 - 05/add-to-EAX 0x30/imm32/0 - c3/return -$to-hex-char:else: - # otherwise return EAX + 'a' - 10 - 05/add-to-EAX 0x57/imm32/a-10 - c3/return - -== data - -_test-slice-empty: - # nothing -_test-slice-empty-end: - -_test-slice-hex-int: - 33/3 34/4 -_test-slice-hex-int-end: - -_test-slice-hex-int-letters-negative: - 2d/- -_test-slice-hex-int-letters: - 33/3 34/4 61/a -_test-slice-hex-int-letters-end: - -_test-slice-hex-int-single-letter: - 61/a -_test-slice-hex-int-single-letter-end: - -_test-slice-char-and-digits: - 71/q 33/3 34/4 -_test-slice-char-and-digits-end: - -_test-slice-digits-and-char: - 33/3 34/4 71/q -_test-slice-digits-and-char-end: - -_test-slice-hex-int-with-0x-prefix-negative: - 2d/- -_test-slice-hex-int-with-0x-prefix: - 30/0 78/x 33/3 34/4 -_test-slice-hex-int-with-0x-prefix-end: - -_test-slice-hex-int-zero: - 30/0 -_test-slice-hex-int-zero-end: - -_test-slice-hex-int-with-0-prefix: - 30/0 33/3 -_test-slice-hex-int-with-0-prefix-end: - -_test-slice-hex-int-negative-with-0-prefix: - 2d/- 30/0 33/3 -_test-slice-hex-int-negative-with-0-prefix-end: - -# . . vim:nowrap:textwidth=0 -- cgit 1.4.1-2-gfad0