diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-07-05 12:13:28 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-07-05 12:13:28 -0700 |
commit | c09c91e185aad8e01b570c2569e13c1e429d2f99 (patch) | |
tree | 52a5ae1494ad5b7b2319411815dc45510e761c24 /113write-stream.subx | |
parent | f2c5b05374186f9422cfdaf1ada096e39ac91a8b (diff) | |
download | mu-c09c91e185aad8e01b570c2569e13c1e429d2f99.tar.gz |
6612 - reorganize layers
Diffstat (limited to '113write-stream.subx')
-rw-r--r-- | 113write-stream.subx | 252 |
1 files changed, 252 insertions, 0 deletions
diff --git a/113write-stream.subx b/113write-stream.subx new file mode 100644 index 00000000..d7e975c0 --- /dev/null +++ b/113write-stream.subx @@ -0,0 +1,252 @@ +# write-stream: like write, but write streams rather than strings + +== 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 + +#? Entry: # manual test +#? # write-stream(stdout, _test-stream2) +#? 68/push _test-stream2/imm32 +#? 68/push 1/imm32/stdout +#? e8/call write-stream/disp32 +#? # syscall(exit, Num-test-failures) +#? 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx +#? e8/call syscall_exit/disp32 + +write-stream: # f: fd or (addr stream byte), s: (addr stream byte) + # . prologue + 55/push-ebp + 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp + # if (f < 0x08000000) _write-stream(f, s), return # f can't be a user-mode address, so treat it as a kernel file descriptor + 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 0x08000000/imm32 # compare *(ebp+8) + 73/jump-if-addr>= $write-stream:fake/disp8 + # . . push args + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + # . . call + e8/call _write-stream/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + eb/jump $write-stream:end/disp8 +$write-stream:fake: + # otherwise, treat 'f' as a stream to append to + # . save registers + 50/push-eax + 56/push-esi + 57/push-edi + # edi = f + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi + # esi = s + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi + # eax = _append-4(&f->data[f->write], &f->data[f->size], &s->data[s->read], &s->data[s->write]) + # . . push &s->data[s->write] + 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax + 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax + 50/push-eax + # . . push &s->data[s->read] + 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax + 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax + 50/push-eax + # . . push &f->data[f->size] + 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 0/r32/eax 8/disp8 . # copy *(edi+8) to eax + 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy edi+eax+12 to eax + 50/push-eax + # . . push &f->data[f->write] + 8b/copy 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # copy *edi to eax + 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy edi+eax+12 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 + # f->write += eax + 01/add 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # add eax to *edi + # s->read += eax + 01/add 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # add eax to *(esi+4) + # . restore registers + 5f/pop-to-edi + 5e/pop-to-esi + 58/pop-to-eax +$write-stream:end: + # . epilogue + 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 5d/pop-to-ebp + c3/return + +_write-stream: # fd: int, s: (addr stream byte) + # . prologue + 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 + # edi = s->read + 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 7/r32/edi 4/disp8 . # copy *(esi+4) to edi + # edx = s->write + 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx + # syscall(write, fd, &s->data[s->read], s->write - s->read) + # . . fd: ebx + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx + # . . data: ecx = &s->data[s->read] + 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 7/index/edi . 1/r32/ecx 0xc/disp8 . # copy esi+edi+12 to ecx + # . . size: edx = s->write - s->read + 29/subtract 3/mod/direct 2/rm32/edx . . . 7/r32/edi . . # subtract edi from edx + # . . syscall + e8/call syscall_write/disp32 + # if (eax < 0) abort + 3d/compare-eax-with 0/imm32 + 0f 8c/jump-if-< $_write-stream:abort/disp32 + # s->read += eax + 01/add 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # add eax to *(esi+4) + # . 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 + # . epilogue + 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp + 5d/pop-to-ebp + c3/return + +$_write-stream:abort: + # . _write(2/stderr, error) + # . . push args + 68/push "_write-stream: failed to write to file\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 + e8/call syscall_exit/disp32 + # never gets here + +test-write-stream-single: + # 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-stream2) + # . . push args + 68/push _test-stream2/imm32 + # . . call + e8/call clear-stream/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # . write(_test-stream2, "Ab") + # . . push args + 68/push "Ab"/imm32 + 68/push _test-stream2/imm32 + # . . call + e8/call write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # write-stream(_test-stream, _test-stream2) + # . . push args + 68/push _test-stream2/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call write-stream/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-stream-equal(_test-stream, "Ab", msg) + # . . push args + 68/push "F - test-write-stream-single"/imm32 + 68/push "Ab"/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 + # . end + c3/return + +test-write-stream-appends: + # 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-stream2) + # . . push args + 68/push _test-stream2/imm32 + # . . call + e8/call clear-stream/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # . write(_test-stream2, "C") + # . . push args + 68/push "C"/imm32 + 68/push _test-stream2/imm32 + # . . call + e8/call write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # first write + # . write-stream(_test-stream, _test-stream2) + # . . push args + 68/push _test-stream2/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call write-stream/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # second write + # . write(_test-stream2, "D") + # . . push args + 68/push "D"/imm32 + 68/push _test-stream2/imm32 + # . . call + e8/call write/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . write-stream(_test-stream, _test-stream2) + # . . push args + 68/push _test-stream2/imm32 + 68/push _test-stream/imm32 + # . . call + e8/call write-stream/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # check-stream-equal(_test-stream, "CD", msg) + # . . push args + 68/push "F - test-write-stream-appends"/imm32 + 68/push "CD"/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 + # . end + c3/return + +== data + +_test-stream2: # (stream byte) + # current write index + 4/imm32 + # current read index + 1/imm32 + # size + 8/imm32 + # data + 41/A 42/B 43/C 44/D 00 00 00 00 # 8 bytes + +# . . vim:nowrap:textwidth=0 |