diff options
Diffstat (limited to 'linux/310copy-bytes.subx')
-rw-r--r-- | linux/310copy-bytes.subx | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/linux/310copy-bytes.subx b/linux/310copy-bytes.subx new file mode 100644 index 00000000..2586a53f --- /dev/null +++ b/linux/310copy-bytes.subx @@ -0,0 +1,157 @@ +# Some helpers for copying non-overlapping regions of memory. +# Really only intended to be called from code generated by mu.subx. + +== code + +copy-bytes: # src: (addr byte), dest: (addr byte), size: int + # pseudocode: + # curr-src/esi = src + # curr-dest/edi = dest + # i/ecx = 0 + # while true + # if (i >= size) break + # *curr-dest = *curr-src + # ++curr-src + # ++curr-dest + # ++i + # + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + 52/push-edx + 56/push-esi + 57/push-edi + # curr-src/esi = src + 8b/-> *(ebp+8) 6/r32/esi + # curr-dest/edi = dest + 8b/-> *(ebp+0xc) 7/r32/edi + # var i/ecx: int = 0 + b9/copy-to-ecx 0/imm32 + # edx = size + 8b/-> *(ebp+0x10) 2/r32/edx + { + # if (i >= size) break + 39/compare %ecx 2/r32/edx + 7d/jump-if->= break/disp8 + # *curr-dest = *curr-src + 8a/byte-> *esi 0/r32/AL + 88/byte<- *edi 0/r32/AL + # update + 46/increment-esi + 47/increment-edi + 41/increment-ecx + eb/jump loop/disp8 + } +$copy-bytes:end: + # . restore registers + 5f/pop-to-edi + 5e/pop-to-esi + 5a/pop-to-edx + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +stream-to-array: # in: (addr stream _), out: (addr handle array _) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + 52/push-edx + 56/push-esi + # esi = s + 8b/-> *(ebp+8) 6/r32/esi + # var len/ecx: int = s->write - s->read + 8b/-> *esi 1/r32/ecx + 2b/subtract *(esi+4) 1/r32/ecx + # allocate + (allocate-array Heap %ecx *(ebp+0xc)) + # var in/edx: (addr byte) = s->data + s->read + 8b/-> *(esi+4) 2/r32/edx + 8d/copy-address *(esi+edx+0xc) 2/r32/edx + # var dest/eax: (addr byte) = data for out + 8b/-> *(ebp+0xc) 0/r32/eax + (lookup *eax *(eax+4)) # => eax + 8d/copy-address *(eax+4) 0/r32/eax + # + (copy-bytes %edx %eax %ecx) +$stream-to-array:end: + # . restore registers + 5e/pop-to-esi + 5a/pop-to-edx + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +test-stream-to-array: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # setup + (clear-stream _test-input-stream) + (write _test-input-stream "abc") + # skip something + (read-byte _test-input-stream) # => eax + # var out/ecx: (handle array byte) + 68/push 0/imm32 + 68/push 0/imm32 + 89/<- %ecx 4/r32/esp + # + (stream-to-array _test-input-stream %ecx) + (lookup *ecx *(ecx+4)) # => eax + (check-strings-equal %eax "bc") + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +# like stream-to-array but ignore surrounding quotes +# we might do other stuff here later +unquote-stream-to-array: # in: (addr stream _), out: (addr handle array _) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + 52/push-edx + 56/push-esi + # esi = s + 8b/-> *(ebp+8) 6/r32/esi + # var len/ecx: int = s->write - s->read - 2 + 8b/-> *esi 1/r32/ecx + 2b/subtract *(esi+4) 1/r32/ecx + 81 7/subop/compare %ecx 2/imm32 + 7c/jump-if-< $unquote-stream-to-array:end/disp8 + 81 5/subop/subtract %ecx 2/imm32 + # allocate + (allocate-array Heap %ecx *(ebp+0xc)) + # var in/edx: (addr byte) = s->data + s->read + 1 + 8b/-> *(esi+4) 2/r32/edx + 8d/copy-address *(esi+edx+0xd) 2/r32/edx # Stream-data + 1 + # var dest/eax: (addr byte) = data for out + 8b/-> *(ebp+0xc) 0/r32/eax + (lookup *eax *(eax+4)) # => eax + 8d/copy-address *(eax+4) 0/r32/eax + # + (copy-bytes %edx %eax %ecx) +$unquote-stream-to-array:end: + # . restore registers + 5e/pop-to-esi + 5a/pop-to-edx + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return |