https://github.com/akkartik/mu/blob/main/309stream.subx

      1 # Some unsafe methods not intended to be used directly in SubX, only through
      2 # Mu after proper type-checking.
      3
      4 == code
      5
      6 stream-empty?:  # s: (addr stream _) -> result/eax: boolean
      7     # . prologue
      8     55/push-ebp
      9     89/<- %ebp 4/r32/esp
     10     # . save registers
     11     51/push-ecx
     12     56/push-esi
     13     # result = false
     14     b8/copy-to-eax 0/imm32/false
     15     # esi = s
     16     8b/-> *(ebp+8) 6/r32/esi
     17     # return s->read >= s->write
     18     8b/-> *esi 1/r32/ecx
     19     39/compare-with *(esi+4) 1/r32/ecx
     20     0f 9d/set-if->= %al
     21 $stream-empty?:end:
     22     # . restore registers
     23     5e/pop-to-esi
     24     59/pop-to-ecx
     25     # . epilogue
     26     89/<- %esp 5/r32/ebp
     27     5d/pop-to-ebp
     28     c3/return
     29
     30 stream-full?:  # s: (addr stream _) -> result/eax: boolean
     31     # . prologue
     32     55/push-ebp
     33     89/<- %ebp 4/r32/esp
     34     # . save registers
     35     51/push-ecx
     36     56/push-esi
     37     # result = false
     38     b8/copy-to-eax 0/imm32/false
     39     # esi = s
     40     8b/-> *(ebp+8) 6/r32/esi
     41     # return s->write >= s->size
     42     8b/-> *(esi+8) 1/r32/ecx
     43     39/compare-with *esi 1/r32/ecx
     44     0f 9d/set-if->= %al
     45 $stream-full?:end:
     46     # . restore registers
     47     5e/pop-to-esi
     48     59/pop-to-ecx
     49     # . epilogue
     50     89/<- %esp 5/r32/ebp
     51     5d/pop-to-ebp
     52     c3/return
     53
     54 write-to-stream:  # s: (addr stream _), in: (addr byte), n: int
     55     # . prologue
     56     55/push-ebp
     57     89/<- %ebp 4/r32/esp
     58     # . save registers
     59     50/push-eax
     60     51/push-ecx
     61     52/push-edx
     62     53/push-ebx
     63     57/push-edi
     64     # edi = s
     65     8b/-> *(ebp+8) 7/r32/edi
     66     # var swrite/edx: int = s->write
     67     8b/-> *edi 2/r32/edx
     68     # if (swrite + n > s->size) abort
     69     8b/-> *(ebp+0x10) 1/r32/ecx
     70     01/add-to %ecx 2/r32/edx
     71     3b/compare 1/r32/ecx *(edi+8)
     72     0f 8f/jump-if-> $write-to-stream:abort/disp32
     73     # var out/edx: (addr byte) = s->data + s->write
     74     8d/copy-address *(edi+edx+0xc) 2/r32/edx
     75     # var outend/ebx: (addr byte) = out + n
     76     8b/-> *(ebp+0x10) 3/r32/ebx
     77     8d/copy-address *(edx+ebx) 3/r32/ebx
     78     # eax = in
     79     8b/-> *(ebp+0xc) 0/r32/eax
     80     # var inend/ecx: (addr byte) = in + n
     81     8b/-> *(ebp+0x10) 1/r32/ecx
     82     8d/copy-address *(eax+ecx) 1/r32/ecx
     83     #
     84     (_append-4  %edx %ebx  %eax %ecx)  # => eax
     85     # s->write += n
     86     8b/-> *(ebp+0x10) 1/r32/ecx
     87     01/add-to *edi 1/r32/ecx
     88 $write-to-stream:end:
     89     # . restore registers
     90     5f/pop-to-edi
     91     5b/pop-to-ebx
     92     5a/pop-to-edx
     93     59/pop-to-ecx
     94     58/pop-to-eax
     95     # . epilogue
     96     89/<- %esp 5/r32/ebp
     97     5d/pop-to-ebp
     98     c3/return
     99
    100 $write-to-stream:abort:
    101     (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "write-to-stream: stream full" 3 0)  # 3=cyan
    102     {
    103       eb/jump loop/disp8
    104     }
    105     # never gets here
    106
    107 read-from-stream:  # s: (addr stream _), out: (addr byte), n: int
    108     # . prologue
    109     55/push-ebp
    110     89/<- %ebp 4/r32/esp
    111     # . save registers
    112     50/push-eax
    113     51/push-ecx
    114     52/push-edx
    115     53/push-ebx
    116     56/push-esi
    117     # esi = s
    118     8b/-> *(ebp+8) 6/r32/esi
    119     # var sread/edx: int = s->read
    120     8b/-> *(esi+4) 2/r32/edx
    121     # if (sread + n > s->write) abort
    122     8b/-> *(ebp+0x10) 1/r32/ecx
    123     01/add-to %ecx 2/r32/edx
    124     3b/compare 1/r32/ecx *esi
    125     0f 8f/jump-if-> $read-from-stream:abort/disp32
    126     # var in/edx: (addr byte) = s->data + s->read
    127     8d/copy-address *(esi+edx+0xc) 2/r32/edx
    128     # var inend/ebx: (addr byte) = in + n
    129     8b/-> *(ebp+0x10) 3/r32/ebx
    130     8d/copy-address *(edx+ebx) 3/r32/ebx
    131     # eax = out
    132     8b/-> *(ebp+0xc) 0/r32/eax
    133     # var outend/ecx: (addr byte) = out + n
    134     8b/-> *(ebp+0x10) 1/r32/ecx
    135     8d/copy-address *(eax+ecx) 1/r32/ecx
    136     #
    137     (_append-4  %eax %ecx  %edx %ebx)  # => eax
    138     # s->read += n
    139     8b/-> *(ebp+0x10) 1/r32/ecx
    140     01/add-to *(esi+4) 1/r32/ecx
    141 $read-from-stream:end:
    142     # . restore registers
    143     5e/pop-to-esi
    144     5b/pop-to-ebx
    145     5a/pop-to-edx
    146     59/pop-to-ecx
    147     58/pop-to-eax
    148     # . epilogue
    149     89/<- %esp 5/r32/ebp
    150     5d/pop-to-ebp
    151     c3/return
    152
    153 $read-from-stream:abort:
    154     (draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0 "read-from-stream: stream empty" 3 0)  # 3=cyan
    155     {
    156       eb/jump loop/disp8
    157     }
    158     # never gets here
    159
    160 stream-first:  # s: (addr stream byte) -> result/eax: byte
    161     # . prologue
    162     55/push-ebp
    163     89/<- %ebp 4/r32/esp
    164     # . save registers
    165     51/push-ecx
    166     56/push-esi
    167     # result = false
    168     b8/copy-to-eax 0/imm32
    169     # esi = s
    170     8b/-> *(ebp+8) 6/r32/esi
    171     # var idx/ecx: int = s->read
    172     8b/-> *(esi+4) 1/r32/ecx
    173     # if idx >= s->write return 0
    174     3b/compare-with 1/r32/ecx *esi
    175     7d/jump-if->= $stream-first:end/disp8
    176     # result = s->data[idx]
    177     8a/byte-> *(esi+ecx+0xc) 0/r32/AL
    178 $stream-first:end:
    179     # . restore registers
    180     5e/pop-to-esi
    181     59/pop-to-ecx
    182     # . epilogue
    183     89/<- %esp 5/r32/ebp
    184     5d/pop-to-ebp
    185     c3/return
    186
    187 stream-final:  # s: (addr stream byte) -> result/eax: byte
    188     # . prologue
    189     55/push-ebp
    190     89/<- %ebp 4/r32/esp
    191     # . save registers
    192     51/push-ecx
    193     56/push-esi
    194     # result = false
    195     b8/copy-to-eax 0/imm32
    196     # esi = s
    197     8b/-> *(ebp+8) 6/r32/esi
    198     # var max/ecx: int = s->write
    199     8b/-> *esi 1/r32/ecx
    200     # if s->read >= max return 0
    201     39/compare-with *(esi+4) 1/r32/ecx
    202     7d/jump-if->= $stream-final:end/disp8
    203     # var idx/ecx: int = max - 1
    204     49/decrement-ecx
    205     # result = s->data[idx]
    206     8a/byte-> *(esi+ecx+0xc) 0/r32/AL
    207 $stream-final:end:
    208     # . restore registers
    209     5e/pop-to-esi
    210     59/pop-to-ecx
    211     # . epilogue
    212     89/<- %esp 5/r32/ebp
    213     5d/pop-to-ebp
    214     c3/return