https://github.com/akkartik/mu/blob/master/309stream.subx
  1 # Some unsafe methods not intended to be used directly in SubX, only through
  2 # Mu after proper type-checking.
  3 
  4 write-to-stream:  # s: (addr stream), in: (addr byte), n: int
  5     # . prologue
  6     55/push-ebp
  7     89/<- %ebp 4/r32/esp
  8     # . save registers
  9     50/push-eax
 10     51/push-ecx
 11     52/push-edx
 12     53/push-ebx
 13     57/push-edi
 14     # edi = s
 15     8b/-> *(ebp+8) 7/r32/edi
 16     # var swrite/edx: int = s->write
 17     8b/-> *edi 2/r32/edx
 18     # if (swrite + n > s->size) abort
 19     8b/-> *(ebp+0x10) 1/r32/ecx
 20     01/add-to %ecx 2/r32/edx
 21     3b/compare 1/r32/ecx *(edi+8)
 22     0f 8f/jump-if-> $write-to-stream:abort/disp32
 23     # var out/edx: (addr byte) = s->data + s->write
 24     8d/copy-address *(edi+edx+0xc) 2/r32/edx
 25     # var outend/ebx: (addr byte) = out + n
 26     8b/-> *(ebp+0x10) 3/r32/ebx
 27     8d/copy-address *(edx+ebx) 3/r32/ebx
 28     # eax = in
 29     8b/-> *(ebp+0xc) 0/r32/eax
 30     # var inend/ecx: (addr byte) = in + n
 31     8b/-> *(ebp+0x10) 1/r32/ecx
 32     8d/copy-address *(eax+ecx) 1/r32/ecx
 33     #
 34     (_append-4  %edx %ebx  %eax %ecx)  # => eax
 35     # s->write += n
 36     8b/-> *(ebp+0x10) 1/r32/ecx
 37     01/add-to *edi 1/r32/ecx
 38 $write-to-stream:end:
 39     # . restore registers
 40     5f/pop-to-edi
 41     5b/pop-to-ebx
 42     5a/pop-to-edx
 43     59/pop-to-ecx
 44     58/pop-to-eax
 45     # . epilogue
 46     89/<- %esp 5/r32/ebp
 47     5d/pop-to-ebp
 48     c3/return
 49 
 50 $write-to-stream:abort:
 51     (write-buffered Stderr "write-to-stream: stream full\n")
 52     (flush Stderr)
 53     bb/copy-to-ebx 1/imm32
 54     (syscall_exit)
 55     # never gets here
 56 
 57 read-from-stream:  # s: (addr stream), out: (addr byte), n: int
 58     # . prologue
 59     55/push-ebp
 60     89/<- %ebp 4/r32/esp
 61     # . save registers
 62     50/push-eax
 63     51/push-ecx
 64     52/push-edx
 65     53/push-ebx
 66     56/push-esi
 67     # esi = s
 68     8b/-> *(ebp+8) 6/r32/esi
 69     # var sread/edx: int = s->read
 70     8b/-> *(esi+4) 2/r32/edx
 71     # if (sread + n > s->write) abort
 72     8b/-> *(ebp+0x10) 1/r32/ecx
 73     01/add-to %ecx 2/r32/edx
 74     3b/compare 1/r32/ecx *esi
 75     0f 8f/jump-if-> $read-from-stream:abort/disp32
 76     # var in/edx: (addr byte) = s->data + s->read
 77     8d/copy-address *(esi+edx+0xc) 2/r32/edx
 78     # var inend/ebx: (addr byte) = in + n
 79     8b/-> *(ebp+0x10) 3/r32/ebx
 80     8d/copy-address *(edx+ebx) 3/r32/ebx
 81     # eax = out
 82     8b/-> *(ebp+0xc) 0/r32/eax
 83     # var outend/ecx: (addr byte) = out + n
 84     8b/-> *(ebp+0x10) 1/r32/ecx
 85     8d/copy-address *(eax+ecx) 1/r32/ecx
 86     #
 87     (_append-4  %eax %ecx  %edx %ebx)  # => eax
 88     # s->read += n
 89     8b/-> *(ebp+0x10) 1/r32/ecx
 90     01/add-to *(esi+4) 1/r32/ecx
 91 $read-from-stream:end:
 92     # . restore registers
 93     5e/pop-to-esi
 94     5b/pop-to-ebx
 95     5a/pop-to-edx
 96     59/pop-to-ecx
 97     58/pop-to-eax
 98     # . epilogue
 99     89/<- %esp 5/r32/ebp
100     5d/pop-to-ebp
101     c3/return
102 
103 $read-from-stream:abort:
104     (write-buffered Stderr "read-from-stream: stream empty\n")
105     (flush Stderr)
106     bb/copy-to-ebx 1/imm32
107     (syscall_exit)
108     # never gets here