diff options
Diffstat (limited to 'subx/072slice.subx')
-rw-r--r-- | subx/072slice.subx | 1173 |
1 files changed, 0 insertions, 1173 deletions
diff --git a/subx/072slice.subx b/subx/072slice.subx deleted file mode 100644 index e568fbae..00000000 --- a/subx/072slice.subx +++ /dev/null @@ -1,1173 +0,0 @@ -# new data structure: a slice is an open interval of addresses [start, end) -# that includes 'start' but not 'end' - -== 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 - -slice-empty?: # s : (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 - # ECX = s - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 1/r32/ECX 8/disp8 . # copy *(EBP+8) to ECX - # if (s->start == s->end) return true - # . EAX = s->start - 8b/copy 0/mod/indirect 1/rm32/ECX . . . 0/r32/EAX . . # copy *ECX to EAX - # . compare EAX and s->end - 39/compare 1/mod/*+disp8 1/rm32/ECX . . . 0/r32/EAX 4/disp8 . # compare EAX and *(ECX+4) - b8/copy-to-EAX 1/imm32/true - 74/jump-if-equal $slice-empty?:end/disp8 - b8/copy-to-EAX 0/imm32/false -$slice-empty?: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-slice-empty-true: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = {34, 34} - 68/push 34/imm32/end - 68/push 34/imm32/start - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # slice-empty?(slice) - # . . push args - 51/push-ECX - # . . call - e8/call slice-empty?/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-slice-empty-true"/imm32 - 68/push 1/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-slice-empty-false: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX = {34, 23} - 68/push 23/imm32/end - 68/push 34/imm32/start - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # slice-empty?(slice) - # . . push args - 51/push-ECX - # . . call - e8/call slice-empty?/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-slice-empty-false"/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 - -slice-equal?: # s : (address slice), p : (address string) -> EAX : boolean - # pseudocode: - # if (p == 0) return (s == 0) - # currs = s->start - # maxs = s->end - # if (maxs - currs != p->length) return false - # currp = p->data - # while currs < maxs - # if (*currs != *currp) return false - # ++currs - # ++currp - # return true - # - # registers: - # currs: EDX - # maxs: ESI - # currp: EBX - # *currs: EAX - # *currp: ECX - # - # . 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 - # ESI = s - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI - # currs/EDX = s->start - 8b/copy 0/mod/indirect 6/rm32/ESI . . . 2/r32/EDX . . # copy *ESI to EDX - # maxs/ESI = s->end - 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 6/r32/ESI 4/disp8 . # copy *(ESI+4) to ESI - # EAX = maxs - currs - 89/copy 3/mod/direct 0/rm32/EAX . . . 6/r32/ESI . . # copy ESI to EAX - 29/subtract 3/mod/direct 0/rm32/EAX . . . 2/r32/EDX . . # subtract EDX from EAX - # EBX = p - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 3/r32/EBX 0xc/disp8 . # copy *(EBP+12) to EBX - # if (p != 0) goto next check - 81 7/subop/compare 3/mod/direct 3/rm32/EBX . . . . . 0/imm32 # compare EBX - 75/jump-if-not-equal $slice-equal?:nonnull-string/disp8 -$slice-equal?:null-string: - # return s->start == s->end - 3d/compare-EAX-and 0/imm32 - 74/jump-if-equal $slice-equal?:true/disp8 - eb/jump $slice-equal?:false/disp8 -$slice-equal?:nonnull-string: - # if (EAX != p->length) return false - 39/compare 0/mod/indirect 3/rm32/EBX . . . 0/r32/EAX . . # compare *EBX and EAX - 75/jump-if-not-equal $slice-equal?:false/disp8 - # currp/EBX = p->data - 81 0/subop/add 3/mod/direct 3/rm32/EBX . . . . . 4/imm32 # add to EBX - # EAX = ECX = 0 - 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX - 31/xor 3/mod/direct 1/rm32/ECX . . . 1/r32/ECX . . # clear ECX -$slice-equal?:loop: - # if (currs >= maxs) return true - 39/compare 3/mod/direct 2/rm32/EDX . . . 6/r32/ESI . . # compare EDX with ESI - 73/jump-if-greater-or-equal-unsigned $slice-equal?:true/disp8 - # AL = *currp - 8a/copy-byte 0/mod/indirect 3/rm32/EBX . . . 0/r32/AL . . # copy byte at *EBX to AL - # CL = *currs - 8a/copy-byte 0/mod/indirect 2/rm32/EDX . . . 1/r32/CL . . # copy byte at *EDX to CL - # if (EAX != ECX) return false - 39/compare 3/mod/direct 0/rm32/EAX . . . 1/r32/ECX . . # compare EAX and ECX - 75/jump-if-not-equal $slice-equal?:false/disp8 - # ++currp - 43/increment-EBX - # ++currs - 42/increment-EDX - eb/jump $slice-equal?:loop/disp8 -$slice-equal?:false: - b8/copy-to-EAX 0/imm32 - eb/jump $slice-equal?:end/disp8 -$slice-equal?:true: - b8/copy-to-EAX 1/imm32 -$slice-equal?:end: - # . 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-slice-equal: - # - slice-equal?(slice("Abc"), "Abc") == 1 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 = slice-equal?(ECX, "Abc") - # . . push args - 68/push "Abc"/imm32 - 51/push-ECX - # . . call - e8/call slice-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 1, msg) - # . . push args - 68/push "F - test-slice-equal"/imm32 - 68/push 1/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-slice-equal-false: - # - slice-equal?(slice("bcd"), "Abc") == 0 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "bcd" - b8/copy-to-EAX "bcd"/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 = slice-equal?(ECX, "Abc") - # . . push args - 68/push "Abc"/imm32 - 51/push-ECX - # . . call - e8/call slice-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-slice-equal-false"/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-slice-equal-too-long: - # - slice-equal?(slice("Abcd"), "Abc") == 0 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Abcd" - b8/copy-to-EAX "Abcd"/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 = slice-equal?(ECX, "Abc") - # . . push args - 68/push "Abc"/imm32 - 51/push-ECX - # . . call - e8/call slice-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-slice-equal-too-long"/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-slice-equal-too-short: - # - slice-equal?(slice("A"), "Abc") == 0 - # . 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 - # 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 = slice-equal?(ECX, "Abc") - # . . push args - 68/push "Abc"/imm32 - 51/push-ECX - # . . call - e8/call slice-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-slice-equal-too-short"/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-slice-equal-empty: - # - slice-equal?(slice(""), "Abc") == 0 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX - 68/push 0/imm32/end - 68/push 0/imm32/start - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = slice-equal?(ECX, "Abc") - # . . push args - 68/push "Abc"/imm32 - 51/push-ECX - # . . call - e8/call slice-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-slice-equal-empty"/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-slice-equal-with-empty: - # - slice-equal?(slice("Ab"), "") == 0 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Ab" - b8/copy-to-EAX "Ab"/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 = slice-equal?(ECX, "") - # . . push args - 68/push ""/imm32 - 51/push-ECX - # . . call - e8/call slice-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-slice-equal-with-empty"/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-slice-equal-empty-with-empty: - # - slice-equal?(slice(""), "") == 1 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var slice/ECX - 68/push 0/imm32/end - 68/push 0/imm32/start - 89/copy 3/mod/direct 1/rm32/ECX . . . 4/r32/ESP . . # copy ESP to ECX - # EAX = slice-equal?(ECX, "") - # . . push args - 68/push ""/imm32 - 51/push-ECX - # . . call - e8/call slice-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 1, msg) - # . . push args - 68/push "F - test-slice-equal-empty-with-empty"/imm32 - 68/push 1/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-slice-equal-with-null: - # - slice-equal?(slice("Ab"), null) == 0 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Ab" - b8/copy-to-EAX "Ab"/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 = slice-equal?(ECX, 0) - # . . push args - 68/push 0/imm32 - 51/push-ECX - # . . call - e8/call slice-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-slice-equal-with-null"/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 - -slice-starts-with?: # s : (address slice), head : (address string) -> EAX : boolean - # pseudocode - # lenh = head->length - # if (lenh > s->end - s->start) return false - # i = 0 - # currs = s->start - # currp = head->data - # while i < lenh - # if (*currs != *currh) return false - # ++i - # ++currs - # ++currh - # return true - # - # registers: - # currs: ESI - # currh: EDI - # *currs: EAX - # *currh: EBX - # i: ECX - # lenh: EDX - # - # . 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 - 57/push-EDI - # ESI = s - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 8/disp8 . # copy *(EBP+8) to ESI - # ECX = s->end - s->start - 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 1/r32/ECX 4/disp8 . # copy *(ESI+4) to ECX - 2b/subtract 0/mod/indirect 6/rm32/ESI . . . 1/r32/ECX . . # subtract *ESI from ECX - # EDI = head - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 7/r32/EDI 0xc/disp8 . # copy *(EBP+12) to EDI - # lenh/EDX = head->length - 8b/copy 0/mod/indirect 7/rm32/EDI . . . 2/r32/EDX . . # copy *EDI to EDX - # if (lenh > s->end - s->start) return false - 39/compare 3/mod/direct 2/rm32/EDX . . . 1/r32/ECX . . # compare EDX with ECX - 7f/jump-if-greater $slice-starts-with?:false/disp8 - # currs/ESI = s->start - 8b/subtract 0/mod/indirect 6/rm32/ESI . . . 6/r32/ESI . . # copy *ESI to ESI - # currh/EDI = head->data - 81 0/subop/add 3/mod/direct 7/rm32/EDI . . . . . 4/imm32 # add to EDI - # i/ECX = 0 - 31/xor 3/mod/direct 1/rm32/ECX . . . 1/r32/ECX . . # clear ECX - # EAX = EBX = 0 - 31/xor 3/mod/direct 0/rm32/EAX . . . 0/r32/EAX . . # clear EAX - 31/xor 3/mod/direct 3/rm32/EBX . . . 3/r32/EBX . . # clear EBX -$slice-starts-with?:loop: - # if (i >= lenh) return true - 39/compare 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # compare ECX with EDX - 7d/jump-if-greater-or-equal $slice-starts-with?:true/disp8 - # AL = *currs - 8a/copy-byte 0/mod/indirect 6/rm32/ESI . . . 0/r32/AL . . # copy byte at *ESI to AL - # BL = *currh - 8a/copy-byte 0/mod/indirect 7/rm32/EDI . . . 3/r32/BL . . # copy byte at *EDI to BL - # if (*currs != *currh) return false - 39/compare 3/mod/direct 0/rm32/EAX . . . 3/r32/EBX . . # compare EAX and EBX - 75/jump-if-not-equal $slice-starts-with?:false/disp8 - # ++i - 41/increment-ECX - # ++currs - 46/increment-ESI - # ++currh - 47/increment-EDI - eb/jump $slice-starts-with?:loop/disp8 -$slice-starts-with?:true: - b8/copy-to-EAX 1/imm32 - eb/jump $slice-starts-with?:end/disp8 -$slice-starts-with?:false: - b8/copy-to-EAX 0/imm32 -$slice-starts-with?:end: - # . 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-slice-starts-with-single-character: - # - slice-starts-with?(slice("Abc"), "A") == 1 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 = slice-starts-with?(ECX, "A") - # . . push args - 68/push "A"/imm32 - 51/push-ECX - # . . call - e8/call slice-starts-with?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 1, msg) - # . . push args - 68/push "F - test-slice-starts-with-single-character"/imm32 - 68/push 1/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-slice-starts-with-empty-string: - # - slice-starts-with?(slice("Abc"), "") == 1 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 = slice-starts-with?(ECX, "") - # . . push args - 68/push ""/imm32 - 51/push-ECX - # . . call - e8/call slice-starts-with?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 1, msg) - # . . push args - 68/push "F - test-slice-starts-with-empty-string"/imm32 - 68/push 1/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-slice-starts-with-multiple-characters: - # - slice-starts-with?(slice("Abc"), "Ab") == 1 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 = slice-starts-with?(ECX, "Ab") - # . . push args - 68/push "Ab"/imm32 - 51/push-ECX - # . . call - e8/call slice-starts-with?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 1, msg) - # . . push args - 68/push "F - test-slice-starts-with-multiple-characters"/imm32 - 68/push 1/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-slice-starts-with-entire-string: - # - slice-starts-with?(slice("Abc"), "Abc") == 1 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 = slice-starts-with?(ECX, "Abc") - # . . push args - 68/push "Abc"/imm32 - 51/push-ECX - # . . call - e8/call slice-starts-with?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 1, msg) - # . . push args - 68/push "F - test-slice-starts-with-entire-string"/imm32 - 68/push 1/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-slice-starts-with-fails: - # - slice-starts-with?(slice("Abc"), "Abd") == 1 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 = slice-starts-with?(ECX, "Abd") - # . . push args - 68/push "Abd"/imm32 - 51/push-ECX - # . . call - e8/call slice-starts-with?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-slice-starts-with-fails"/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-slice-starts-with-fails-2: - # - slice-starts-with?(slice("Abc"), "Ac") == 1 - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 = slice-starts-with?(ECX, "Ac") - # . . push args - 68/push "Ac"/imm32 - 51/push-ECX - # . . call - e8/call slice-starts-with?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 0, msg) - # . . push args - 68/push "F - test-slice-starts-with-fails-2"/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 - -# write a slice to a stream -# abort if the stream doesn't have enough space -write-slice: # out : (address stream), s : (address slice) - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # . save registers - 50/push-EAX - 51/push-ECX - 52/push-EDX - 53/push-EBX - 56/push-ESI - 57/push-EDI - # ESI = s - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI - # curr/ECX = s->start - 8b/copy 0/mod/indirect 6/rm32/ESI . . . 1/r32/ECX . . # copy *ESI to ECX - # max/ESI = s->end - 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 6/r32/ESI 4/disp8 . # copy *(ESI+4) to ESI - # EDI = out - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI - # EDX = out->length - 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 2/r32/EDX 8/disp8 . # copy *(EDI+8) to EDX - # EBX = out->write - 8b/copy 0/mod/indirect 7/rm32/EDI . . . 3/r32/EBX . . # copy *EDI to EBX -$write-slice:loop: - # if (curr >= max) break - 39/compare 3/mod/direct 1/rm32/ECX . . . 6/r32/ESI . . # compare ECX with ESI - 73/jump-if-greater-or-equal-unsigned $write-slice:loop-end/disp8 - # if (out->write >= out->length) abort - 39/compare 3/mod/direct 3/rm32/EBX . . . 2/r32/EDX . . # compare EBX with EDX - 7d/jump-if-greater-or-equal $write-slice:abort/disp8 - # out->data[out->write] = *in - # . AL = *in - 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 - # . out->data[out->write] = AL - 88/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/EDI 3/index/EBX . 0/r32/AL 0xc/disp8 . # copy AL to *(EDI+EBX+12) - # ++out->write - 43/increment-EBX - # ++in - 41/increment-ECX - eb/jump $write-slice:loop/disp8 -$write-slice:loop-end: - # persist out->write - 89/copy 0/mod/indirect 7/rm32/EDI . . . 3/r32/EBX . . # copy EBX to *EDI -$write-slice:end: - # . restore registers - 5f/pop-to-EDI - 5e/pop-to-ESI - 5b/pop-to-EBX - 5a/pop-to-EDX - 59/pop-to-ECX - 58/pop-to-EAX - # . epilog - 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 5d/pop-to-EBP - c3/return - -$write-slice:abort: - # . _write(2/stderr, error) - # . . push args - 68/push "write-slice: out of space"/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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - # never gets here - -test-write-slice: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # setup - # . clear-stream(_test-stream) - # . . push args - 68/push _test-stream/imm32 - # . . call - e8/call clear-stream/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 - # write-slice(_test-stream, slice) - # . . push args - 51/push-ECX - 68/push _test-stream/imm32 - # . . call - e8/call write-slice/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-stream-equal(_test-stream, "Abc", msg) - # . . push args - 68/push "F - test-write-slice"/imm32 - 68/push "Abc"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call check-stream-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 - -# write a slice to a buffered-file -write-slice-buffered: # out : (address buffered-file), s : (address slice) - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # . save registers - 50/push-EAX - 51/push-ECX - 52/push-EDX - 53/push-EBX - 56/push-ESI - 57/push-EDI - # ESI = s - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI - # curr/ECX = s->start - 8b/copy 0/mod/indirect 6/rm32/ESI . . . 1/r32/ECX . . # copy *ESI to ECX - # max/ESI = s->end - 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 6/r32/ESI 4/disp8 . # copy *(ESI+4) to ESI - # EDI = out - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . 7/r32/EDI 8/disp8 . # copy *(EBP+8) to EDI - # EDX = out->length - 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 2/r32/EDX 0xc/disp8 . # copy *(EDI+12) to EDX - # EBX = out->write - 8b/copy 1/mod/*+disp8 7/rm32/EDI . . . 3/r32/EBX 4/disp8 . # copy *(EDI+4) to EBX -$write-slice-buffered:loop: - # if (curr >= max) break - 39/compare 3/mod/direct 1/rm32/ECX . . . 6/r32/ESI . . # compare ECX with ESI - 73/jump-if-greater-or-equal-unsigned $write-slice-buffered:loop-end/disp8 - # if (out->write >= out->length) flush and clear out's stream - 39/compare 3/mod/direct 3/rm32/EBX . . . 2/r32/EDX . . # compare EBX with EDX - 7c/jump-if-lesser $write-slice-buffered:to-stream/disp8 - # . persist out->write - 89/copy 1/mod/*+disp8 7/rm32/EDI . . . 3/r32/EBX 4/disp8 . # copy EBX to *(EDI+4) - # . flush(out) - # . . push args - 57/push-EDI - # . . call - e8/call flush/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . clear-stream(stream = out+4) - # . . push args - 8d/copy-address 1/mod/*+disp8 7/rm32/EDI . . . 0/r32/EAX 4/disp8 . # copy EDI+4 to EAX - 50/push-EAX - # . . call - e8/call clear-stream/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . out->write must now be 0; update its cache at EBX - 31/xor 3/mod/direct 3/rm32/EBX . . . 3/r32/EBX . . # clear EBX -$write-slice-buffered:to-stream: - # out->data[out->write] = *in - # . AL = *in - 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 - # . out->data[out->write] = AL - 88/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/EDI 3/index/EBX . 0/r32/AL 0x10/disp8 . # copy AL to *(EDI+EBX+16) - # ++out->write - 43/increment-EBX - # ++in - 41/increment-ECX - eb/jump $write-slice-buffered:loop/disp8 -$write-slice-buffered:loop-end: - # persist necessary variables from registers - 89/copy 1/mod/*+disp8 7/rm32/EDI . . . 3/r32/EBX 4/disp8 . # copy EBX to *(EDI+4) -$write-slice-buffered:end: - # . restore registers - 5f/pop-to-EDI - 5e/pop-to-ESI - 5b/pop-to-EBX - 5a/pop-to-EDX - 59/pop-to-ECX - 58/pop-to-EAX - # . epilog - 89/copy 3/mod/direct 4/rm32/ESP . . . 5/r32/EBP . . # copy EBP to ESP - 5d/pop-to-EBP - c3/return - -test-write-slice-buffered: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # setup - # . clear-stream(_test-stream) - # . . push args - 68/push _test-stream/imm32 - # . . call - e8/call clear-stream/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # . clear-stream(_test-buffered-file+4) - # . . push args - b8/copy-to-EAX _test-buffered-file/imm32 - 05/add-to-EAX 4/imm32 - 50/push-EAX - # . . call - e8/call clear-stream/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 - # write-slice-buffered(_test-buffered-file, slice) - # . . push args - 51/push-ECX - 68/push _test-buffered-file/imm32 - # . . call - e8/call write-slice-buffered/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # flush(_test-buffered-file) - # . . push args - 68/push _test-buffered-file/imm32 - # . . call - e8/call flush/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 4/imm32 # add to ESP - # check-stream-equal(_test-stream, "Abc", msg) - # . . push args - 68/push "F - test-write-slice-buffered"/imm32 - 68/push "Abc"/imm32 - 68/push _test-stream/imm32 - # . . call - e8/call check-stream-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 - -# copy a slice into a new (dynamically allocated) string -slice-to-string: # ad : (address allocation-descriptor), in : (address slice) -> out/EAX : (address array) - # . 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 - # ESI = in - 8b/copy 1/mod/*+disp8 5/rm32/EBP . . . 6/r32/ESI 0xc/disp8 . # copy *(EBP+12) to ESI - # curr/EDX = in->start - 8b/copy 0/mod/indirect 6/rm32/ESI . . . 2/r32/EDX . . # copy *ESI to EDX - # max/EBX = in->end - 8b/copy 1/mod/*+disp8 6/rm32/ESI . . . 3/r32/EBX 4/disp8 . # copy *(ESI+4) to EBX - # size/ECX = max - curr + 4 # total size of output string (including the initial length) - 89/copy 3/mod/direct 1/rm32/ECX . . . 3/r32/EBX . . # copy EBX to ECX - 29/subtract 3/mod/direct 1/rm32/ECX . . . 2/r32/EDX . . # subtract EDX from ECX - 81 0/subop/add 3/mod/direct 1/rm32/ECX . . . . . 4/imm32 # add to ECX - # out/EAX = allocate(ad, size) - # . . push args - 51/push-ECX - ff 6/subop/push 1/mod/*+disp8 5/rm32/EBP . . . . 8/disp8 . # push *(EBP+8) - # . . call - e8/call allocate/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # if (EAX == 0) abort - 3d/compare-EAX-and 0/imm32 - 74/jump-if-equal $slice-to-string:abort/disp8 - # *out = size-4 - 89/copy 0/mod/indirect 0/rm32/EAX . . . 1/r32/ECX . . # copy ECX to *EAX - 81 5/subop/subtract 0/mod/indirect 0/rm32/EAX . . . . . 4/imm32 # subtract 4 from *EAX - # save out - 50/push-EAX - # EAX = _append-4(EAX+4, EAX+size, curr, max) # clobbering ECX - # . . push args - 53/push-EBX - 52/push-EDX - # . . push EAX+size (clobbering ECX) - 01/add 3/mod/direct 1/rm32/ECX . . . 0/r32/EAX . . # add EAX to ECX - 51/push-ECX - # . . push EAX+4 (clobbering EAX) - 81 0/subop/add 3/mod/direct 0/rm32/EAX . . . . . 4/imm32 # add to EAX - 50/push-EAX - # . . call - e8/call _append-4/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 0x10/imm32 # add to ESP - # restore out (assumes _append-4 can't error) - 58/pop-to-EAX -$slice-to-string:end: - # . 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 - -$slice-to-string:abort: - # . _write(2/stderr, error) - # . . push args - 68/push "slice-to-string: out of space\n"/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 - b8/copy-to-EAX 1/imm32/exit - cd/syscall 0x80/imm8 - # never gets here - -test-slice-to-string: - # . prolog - 55/push-EBP - 89/copy 3/mod/direct 5/rm32/EBP . . . 4/r32/ESP . . # copy ESP to EBP - # var heap/EDX : (address allocation-descriptor) = {0, 0} - 68/push 0/imm32/limit - 68/push 0/imm32/curr - 89/copy 3/mod/direct 2/rm32/EDX . . . 4/r32/ESP . . # copy ESP to EDX - # heap = new-segment(512) - # . . push args - 52/push-EDX - 68/push 0x200/imm32 - # . . call - e8/call new-segment/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # (EAX..ECX) = "Abc" - b8/copy-to-EAX "Abc"/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 = slice-to-string(heap, slice) - # . . push args - 51/push-ECX - 52/push-EDX - # . . call - e8/call slice-to-string/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP -#? # dump word-slice {{{ -#? # . write(2/stderr, "AA: ") -#? # . . push args -#? 68/push "AA: "/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 -#? # . write(2/stderr, EAX) -#? # . . push args -#? 50/push-EAX -#? 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 -#? # . write(2/stderr, "$\n") -#? # . . push args -#? 68/push "$\n"/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 -#? # }}} - # EAX = string-equal?(EAX, "Abc") - # . . push args - 68/push "Abc"/imm32 - 50/push-EAX - # . . call - e8/call string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/ESP . . . . . 8/imm32 # add to ESP - # check-ints-equal(EAX, 1, msg) - # . . push args - 68/push "F - test-slice-to-string"/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 - -# . . vim:nowrap:textwidth=0 |