diff options
author | Kartik Agaram <vc@akkartik.com> | 2019-08-25 00:59:52 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2019-08-25 00:59:52 -0700 |
commit | f40528078d78b72d244aaeffefc8a68946c1f457 (patch) | |
tree | 7020e6be3f5a1faef494b1eb7ac065fb84382c47 /apps | |
parent | 1a7b15aa3d2873983bec5787e565695ed194fbae (diff) | |
download | mu-f40528078d78b72d244aaeffefc8a68946c1f457.tar.gz |
desugar: parsing seems complete
Diffstat (limited to 'apps')
-rwxr-xr-x | apps/desugar | bin | 44534 -> 45981 bytes | |||
-rw-r--r-- | apps/desugar.subx | 457 |
2 files changed, 420 insertions, 37 deletions
diff --git a/apps/desugar b/apps/desugar index bfdec579..e8084ddf 100755 --- a/apps/desugar +++ b/apps/desugar Binary files differdiff --git a/apps/desugar.subx b/apps/desugar.subx index cbd8a408..4f2db492 100644 --- a/apps/desugar.subx +++ b/apps/desugar.subx @@ -1507,7 +1507,7 @@ parse-effective-address: # word : (address slice) -> base/EAX, index/ECX, scale # if (*word->start != '<') goto error3 # ++word->start to skip '<' # skip whitespace - # read register into scale + # read integer into scale # skip whitespace # if (*word->start == ')') goto end # } @@ -1671,15 +1671,52 @@ $parse-effective-address:index: 3d/compare-EAX-and 0x29/imm32/close-paren 74/jump-if-equal $parse-effective-address:end/disp8 $parse-effective-address:check-for-scale: - # if (*word->start != '<') goto displacement + # if (*word->start != '<') goto next check + 3d/compare-EAX-and 0x3c/imm32/less-than + 75/jump-if-not-equal $parse-effective-address:check-for-displacement/disp8 # ++word->start to skip '<' + ff 0/subop/increment 0/mod/indirect 6/rm32/ESI . . . . . . # increment *ESI # if (*word->start != '<') goto error3 # ++word->start to skip '<' + ff 0/subop/increment 0/mod/indirect 6/rm32/ESI . . . . . . # increment *ESI # skip whitespace + # . EAX = skip-chars-matching-whitespace-in-slice(word->start, word->end) + # . . push args + ff 6/subop/push 1/mod/*+disp8 6/rm32/ESI . . . . 4/disp8 . # push *(ESI+4) + ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI + # . . call + e8/call skip-chars-matching-whitespace-in-slice/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + # . word->start = EAX + 89/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy EAX to *ESI $parse-effective-address:scale: - # read register into scale + # read positive integer into scale + # . EAX = next-positive-hex-int(word) + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) + # . . call + e8/call next-positive-hex-int/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + # . EDX = EAX + 89/copy 3/mod/direct 2/rm32/EDX . . . 0/r32/EAX . . # copy EAX to EDX # skip whitespace + # . EAX = skip-chars-matching-whitespace-in-slice(word->start, word->end) + # . . push args + ff 6/subop/push 1/mod/*+disp8 6/rm32/ESI . . . . 4/disp8 . # push *(ESI+4) + ff 6/subop/push 0/mod/indirect 6/rm32/ESI . . . . . . # push *ESI + # . . call + e8/call skip-chars-matching-whitespace-in-slice/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP + # . word->start = EAX + 89/copy 0/mod/indirect 6/rm32/ESI . . . 0/r32/EAX . . # copy EAX to *ESI # if (*word->start == ')') goto end + 8a/copy-byte 0/mod/indirect 0/rm32/EAX . . . 0/r32/AL . . # copy byte at *EAX to AL + 81 4/subop/and 3/mod/direct 0/rm32/EAX . . . . . 0xff/imm32 # bitwise and of EAX + 3d/compare-EAX-and 0x29/imm32/close-paren + 74/jump-if-equal $parse-effective-address:end/disp8 $parse-effective-address:check-for-displacement: # if (*word->start not in '+' '-') goto error4 $parse-effective-address:displacement: @@ -1692,7 +1729,7 @@ $parse-effective-address:displacement: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP # . EBX = EAX - 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EBX to EAX + 89/copy 3/mod/direct 3/rm32/EBX . . . 0/r32/EAX . . # copy EAX to EBX # skip whitespace # . EAX = skip-chars-matching-whitespace-in-slice(word->start, word->end) # . . push args @@ -2066,9 +2103,129 @@ test-parse-effective-address-base-index: 5d/pop-to-EBP c3/return -#? test-parse-effective-address-base-index-scale: -#? -#? test-parse-effective-address-base-index-scale-displacement: +test-parse-effective-address-base-index-scale: + # . prolog + 55/push-EBP + 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + # var slice/ECX = "*(esi+ecx<<2)" + b8/copy-to-EAX "*(esi+ecx<<2)"/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 + # . ECX = {EAX, ECX} + 51/push-ECX + 50/push-EAX + 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX + # EAX, ECX, EDX, EBX = parse-effective-address(slice) + # . . push args + 51/push-ECX + # . . call + e8/call parse-effective-address/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + # slice clobbered beyond this point + # check-ints-equal(EAX, 6, msg) + # . . push args + 68/push "F - test-parse-effective-address-base-index-scale/base"/imm32 + 68/push 6/imm32/ESI + 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 + # check-ints-equal(ECX, 1, msg) + # . . push args + 68/push "F - test-parse-effective-address-base-index-scale/index"/imm32 + 68/push 1/imm32/none + 51/push-ECX + # . . call + e8/call check-ints-equal/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + # check-ints-equal(EDX, 2, msg) + # . . push args + 68/push "F - test-parse-effective-address-base-index-scale/scale"/imm32 + 68/push 2/imm32 + 52/push-EDX + # . . call + e8/call check-ints-equal/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + # check-ints-equal(EBX, 0, msg) + # . . push args + 68/push "F - test-parse-effective-address-base-index-scale/displacement"/imm32 + 68/push 0/imm32 + 53/push-EBX + # . . 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-effective-address-base-index-scale-displacement: + # . prolog + 55/push-EBP + 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP + # var slice/ECX = "*(esi + ecx<<2 - 0x34)" + b8/copy-to-EAX "*(esi + ecx<<2 - 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 + # . ECX = {EAX, ECX} + 51/push-ECX + 50/push-EAX + 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX + # EAX, ECX, EDX, EBX = parse-effective-address(slice) + # . . push args + 51/push-ECX + # . . call + e8/call parse-effective-address/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP + # slice clobbered beyond this point + # check-ints-equal(EAX, 6, msg) + # . . push args + 68/push "F - test-parse-effective-address-base-index-scale/base"/imm32 + 68/push 6/imm32/ESI + 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 + # check-ints-equal(ECX, 1, msg) + # . . push args + 68/push "F - test-parse-effective-address-base-index-scale/index"/imm32 + 68/push 1/imm32/none + 51/push-ECX + # . . call + e8/call check-ints-equal/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + # check-ints-equal(EDX, 2, msg) + # . . push args + 68/push "F - test-parse-effective-address-base-index-scale/scale"/imm32 + 68/push 2/imm32 + 52/push-EDX + # . . call + e8/call check-ints-equal/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0xc/imm32 # add to ESP + # check-ints-equal(EBX, -0x34, msg) + # . . push args + 68/push "F - test-parse-effective-address-base-index-scale/displacement"/imm32 + 68/push -0x34/imm32 + 53/push-EBX + # . . 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 # Code generation: # if index is none and disp is 0, then mod = 0 and rm32 = base @@ -2774,8 +2931,8 @@ test-next-hex-int-single-digit: # . prolog 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 + # (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 @@ -2808,8 +2965,8 @@ test-next-hex-int-multi-digit: # . prolog 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 + # (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 @@ -2842,8 +2999,8 @@ test-next-hex-int-0x-prefix: # . prolog 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 + # (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 @@ -2858,7 +3015,7 @@ test-next-hex-int-0x-prefix: e8/call next-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) + # check-ints-equal(EAX, 0x34, msg) # . . push args 68/push "F - test-next-hex-int-0x-prefix"/imm32 68/push 0x34/imm32 @@ -2876,8 +3033,8 @@ test-next-hex-int-zero: # . prolog 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 + # (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 @@ -2892,7 +3049,7 @@ test-next-hex-int-zero: e8/call next-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) + # check-ints-equal(EAX, 0, msg) # . . push args 68/push "F - test-next-hex-int-zero"/imm32 68/push 0/imm32 @@ -2910,8 +3067,8 @@ test-next-hex-int-0-prefix: # . prolog 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 + # (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 @@ -2926,10 +3083,10 @@ test-next-hex-int-0-prefix: e8/call next-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) + # check-ints-equal(EAX, 3, msg) # . . push args 68/push "F - test-next-hex-int-0-prefix"/imm32 - 68/push 0x3/imm32 + 68/push 3/imm32 50/push-EAX # . . call e8/call check-ints-equal/disp32 @@ -2944,8 +3101,8 @@ test-next-hex-int-negative: # . prolog 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 + # (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 @@ -2960,10 +3117,10 @@ test-next-hex-int-negative: e8/call next-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) + # check-ints-equal(EAX, -3, msg) # . . push args 68/push "F - test-next-hex-int-negative"/imm32 - 68/push 0xfffffffd/imm32 + 68/push -3/imm32 50/push-EAX # . . call e8/call check-ints-equal/disp32 @@ -2978,8 +3135,8 @@ test-next-hex-int-negative-with-space: # . prolog 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 + # (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 @@ -2994,10 +3151,10 @@ test-next-hex-int-negative-with-space: e8/call next-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) + # check-ints-equal(EAX, -3, msg) # . . push args 68/push "F - test-next-hex-int-negative-with-space"/imm32 - 68/push 0xfffffffd/imm32 + 68/push -3/imm32 50/push-EAX # . . call e8/call check-ints-equal/disp32 @@ -3008,12 +3165,102 @@ test-next-hex-int-negative-with-space: 5d/pop-to-EBP c3/return -test-next-hex-int-stop-at-non-hex: +# assumes 'in' starts a positive unsigned integer +# returns the value of the integer +# side-effect: modifies 'in' to skip past the integer +next-positive-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 - # (EAX..ECX) = "- 03)" - b8/copy-to-EAX "- 03)"/imm32 + # . save registers + 51/push-ECX + 52/push-EDX + 53/push-EBX + 56/push-ESI + 57/push-EDI + # result/EDI = 0 + 31/xor 3/mod/direct 7/rm32/EDI . . . 7/r32/EDI . . # clear EDI + # ESI = in + 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI + # EDX = in->end + 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 2/r32/EDX 4/disp8 . # copy *(ESI+4) to EDX + # curr/ECX = in->start + 8b/copy 0/mod/indirect 6/rm32/ESI . . . 1/r32/ECX . . # copy *ESI to ECX + # negate?/EBX = false + 31/xor 3/mod/direct 3/rm32/EBX . . . 3/r32/EBX . . # clear EBX + # EAX = *curr + 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 +$next-positive-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 + 3d/compare-EAX-and 0x30/imm32/0 + 75/jump-if-not-equal $next-positive-hex-int:loop/disp8 + # . ++curr + 41/increment-ECX +$next-positive-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 + 73/jump-if-greater-or-equal-unsigned $next-positive-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 + 3d/compare-EAX-and 0x78/imm32/x + 75/jump-if-not-equal $next-positive-hex-int:loop/disp8 + # . ++curr + 41/increment-ECX +$next-positive-hex-int:loop: + # if (curr >= in->end) break + 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX + 73/jump-if-greater-or-equal-unsigned $next-positive-hex-int:end/disp8 + # if (!is-hex-digit?(*curr)) break + # . EAX = *curr + 8a/copy-byte 0/mod/indirect 1/rm32/ECX . . . 0/r32/AL . . # copy byte at *ECX to AL + # . EAX = is-hex-digit?(*curr) + # . . push args + 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 == 0) break + 3d/compare-EAX-and 0/imm32 + 74/jump-if-equal $next-positive-hex-int:end/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 7/rm32/EDI . . . . . 4/imm8 # shift EDI left by 4 bits + 01/add 3/mod/direct 7/rm32/EDI . . . 0/r32/EAX . . # add EAX to EDI + # ++curr + 41/increment-ECX + # loop + eb/jump $next-positive-hex-int:loop/disp8 +$next-positive-hex-int:end: + # word->start = curr + 89/copy 0/mod/indirect 6/rm32/ESI . . . 1/r32/ECX . . # copy ECX to *ESI + # return EDI + 89/copy 3/mod/direct 0/rm32/EAX . . . 7/r32/EDI . . # copy EDI to EAX + # . restore registers + 5f/pop-to-EDI + 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-next-positive-hex-int-single-digit: + # . prolog + 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 @@ -3021,17 +3268,153 @@ test-next-hex-int-stop-at-non-hex: 51/push-ECX 50/push-EAX 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = next-hex-int(slice) + # EAX = next-positive-hex-int(slice) # . . push args 51/push-ECX # . . call - e8/call next-hex-int/disp32 + e8/call next-positive-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) + # check-ints-equal(EAX, 0xa, msg) + # . . push args + 68/push "F - test-next-positive-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-next-positive-hex-int-multi-digit: + # . prolog + 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 = {EAX, ECX} + 51/push-ECX + 50/push-EAX + 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX + # EAX = next-positive-hex-int(slice) # . . push args - 68/push "F - test-next-hex-int-stop-at-non-hex"/imm32 - 68/push 0xfffffffd/imm32 + 51/push-ECX + # . . call + e8/call next-positive-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-next-positive-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-next-positive-hex-int-0x-prefix: + # . prolog + 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 = {EAX, ECX} + 51/push-ECX + 50/push-EAX + 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX + # EAX = next-positive-hex-int(slice) + # . . push args + 51/push-ECX + # . . call + e8/call next-positive-hex-int/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-next-positive-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-next-positive-hex-int-zero: + # . prolog + 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 = {EAX, ECX} + 51/push-ECX + 50/push-EAX + 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX + # EAX = next-positive-hex-int(slice) + # . . push args + 51/push-ECX + # . . call + e8/call next-positive-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-next-positive-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-next-positive-hex-int-0-prefix: + # . prolog + 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 = {EAX, ECX} + 51/push-ECX + 50/push-EAX + 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX + # EAX = next-positive-hex-int(slice) + # . . push args + 51/push-ECX + # . . call + e8/call next-positive-hex-int/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-next-positive-hex-int-0-prefix"/imm32 + 68/push 3/imm32 50/push-EAX # . . call e8/call check-ints-equal/disp32 |