diff options
Diffstat (limited to 'subx/062write-stream.subx')
-rw-r--r-- | subx/062write-stream.subx | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/subx/062write-stream.subx b/subx/062write-stream.subx index 73766fe3..92c67dc2 100644 --- a/subx/062write-stream.subx +++ b/subx/062write-stream.subx @@ -21,7 +21,7 @@ write-stream: # f : fd or (address stream), s : (address stream) -> <void> 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) - 7d/jump-if-greater-or-equal $write-stream:fake/disp8 + 73/jump-if-greater-unsigned-or-equal $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) @@ -102,6 +102,11 @@ _write-stream: # fd : int, s : (address stream) -> <void> # . . syscall b8/copy-to-EAX 4/imm32/write cd/syscall 0x80/imm8 + # if (EAX < 0) abort + 3d/compare-EAX-with 0/imm32 + 0f 8c/jump-if-lesser $_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 @@ -114,6 +119,21 @@ _write-stream: # fd : int, s : (address stream) -> <void> 5d/pop-to-EBP c3/return +$_write-stream:abort: + # . _write(2/stderr, error) + # . . push args + 68/push "_write-stream: failed to write to file"/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 + b8/copy-to-EAX 1/imm32/exit + cd/syscall 0x80/imm8 + # never gets here + test-write-stream-single: # setup # . clear-stream(_test-stream) |