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 stream-empty?:  # s: (addr stream _) -> result/eax: boolean
  5     # . prologue
  6     55/push-ebp
  7     89/<- %ebp 4/r32/esp
  8     # . save registers
  9     51/push-ecx
 10     56/push-esi
 11     # result = false
 12     b8/copy-to-eax 0/imm32/false
 13     # esi = s
 14     8b/-> *(ebp+8) 6/r32/esi
 15     # return s->read >= s->write
 16     8b/-> *esi 1/r32/ecx
 17     39/compare-with *(esi+4) 1/r32/ecx
 18     0f 9d/set-if->= %al
 19 $stream-empty?:end:
 20     # . restore registers
 21     5e/pop-to-esi
 22     59/pop-to-ecx
 23     # . epilogue
 24     89/<- %esp 5/r32/ebp
 25     5d/pop-to-ebp
 26     c3/return
 27 
 28 stream-full?:  # s: (addr stream _) -> result/eax: boolean
 29     # . prologue
 30     55/push-ebp
 31     89/<- %ebp 4/r32/esp
 32     # . save registers
 33     51/push-ecx
 34     56/push-esi
 35     # result = false
 36     b8/copy-to-eax 0/imm32/false
 37     # esi = s
 38     8b/-> *(ebp+8) 6/r32/esi
 39     # return s->write >= s->size
 40     8b/-> *(esi+8) 1/r32/ecx
 41     39/compare-with *esi 1/r32/ecx
 42     0f 9d/set-if->= %al
 43 $stream-full?:end:
 44     # . restore registers
 45     5e/pop-to-esi
 46     59/pop-to-ecx
 47     # . epilogue
 48     89/<- %esp 5/r32/ebp
 49     5d/pop-to-ebp
 50     c3/return
 51 
 52 write-to-stream:  # s: (addr stream _), in: (addr byte), n: int
 53     # . prologue
 54     55/push-ebp
 55     89/<- %ebp 4/r32/esp
 56     # . save registers
 57     50/push-eax
 58     51/push-ecx
 59     52/push-edx
 60     53/push-ebx
 61     57/push-edi
 62     # edi = s
 63     8b/-> *(ebp+8) 7/r32/edi
 64     # var swrite/edx: int = s->write
 65     8b/-> *edi 2/r32/edx
 66     # if (swrite + n > s->size) abort
 67     8b/-> *(ebp+0x10) 1/r32/ecx
 68     01/add-to %ecx 2/r32/edx
 69     3b/compare 1/r32/ecx *(edi+8)
 70     0f 8f/jump-if-> $write-to-stream:abort/disp32
 71     # var out/edx: (addr byte) = s->data + s->write
 72     8d/copy-address *(edi+edx+0xc) 2/r32/edx
 73     # var outend/ebx: (addr byte) = out + n
 74     8b/-> *(ebp+0x10) 3/r32/ebx
 75     8d/copy-address *(edx+ebx) 3/r32/ebx
 76     # eax = in
 77     8b/-> *(ebp+0xc) 0/r32/eax
 78     # var inend/ecx: (addr byte) = in + n
 79     8b/-> *(ebp+0x10) 1/r32/ecx
 80     8d/copy-address *(eax+ecx) 1/r32/ecx
 81     #
 82     (_append-4  %edx %ebx  %eax %ecx)  # => eax
 83     # s->write += n
 84     8b/-> *(ebp+0x10) 1/r32/ecx
 85     01/add-to *edi 1/r32/ecx
 86 $write-to-stream:end:
 87     # . restore registers
 88     5f/pop-to-edi
 89     5b/pop-to-ebx
 90     5a/pop-to-edx
 91     59/pop-to-ecx
 92     58/pop-to-eax
 93     # . epilogue
 94     89/<- %esp 5/r32/ebp
 95     5d/pop-to-ebp
 96     c3/return
 97 
 98 $write-to-stream:abort:
 99     (write-buffered Stderr "write-to-stream: stream full\n")
100     (flush Stderr)
101     bb/copy-to-ebx 1/imm32
102     (syscall_exit)
103     # never gets here
104 
105 read-from-stream:  # s: (addr stream _), out: (addr byte), n: int
106     # . prologue
107     55/push-ebp
108     89/<- %ebp 4/r32/esp
109     # . save registers
110     50/push-eax
111     51/push-ecx
112     52/push-edx
113     53/push-ebx
114     56/push-esi
115     # esi = s
116     8b/-> *(ebp+8) 6/r32/esi
117     # var sread/edx: int = s->read
118     8b/-> *(esi+4) 2/r32/edx
119     # if (sread + n > s->write) abort
120     8b/-> *(ebp+0x10) 1/r32/ecx
121     01/add-to %ecx 2/r32/edx
122     3b/compare 1/r32/ecx *esi
123     0f 8f/jump-if-> $read-from-stream:abort/disp32
124     # var in/edx: (addr byte) = s->data + s->read
125     8d/copy-address *(esi+edx+0xc) 2/r32/edx
126     # var inend/ebx: (addr byte) = in + n
127     8b/-> *(ebp+0x10) 3/r32/ebx
128     8d/copy-address *(edx+ebx) 3/r32/ebx
129     # eax = out
130     8b/-> *(ebp+0xc) 0/r32/eax
131     # var outend/ecx: (addr byte) = out + n
132     8b/-> *(ebp+0x10) 1/r32/ecx
133     8d/copy-address *(eax+ecx) 1/r32/ecx
134     #
135     (_append-4  %eax %ecx  %edx %ebx)  # => eax
136     # s->read += n
137     8b/-> *(ebp+0x10) 1/r32/ecx
138     01/add-to *(esi+4) 1/r32/ecx
139 $read-from-stream:end:
140     # . restore registers
141     5e/pop-to-esi
142     5b/pop-to-ebx
143     5a/pop-to-edx
144     59/pop-to-ecx
145     58/pop-to-eax
146     # . epilogue
147     89/<- %esp 5/r32/ebp
148     5d/pop-to-ebp
149     c3/return
150 
151 $read-from-stream:abort:
152     (write-buffered Stderr "read-from-stream: stream empty\n")
153     (flush Stderr)
154     bb/copy-to-ebx 1/imm32
155     (syscall_exit)
156     # never gets here