This is what I've got for l_gets. It's pretty much your code. I moved "inc esi" up to the top so our first try is 1, not 0. If esi==len, we do want to do that read, in case the LF is there. Now we do. I cut back to reading one byte at a time, little as I like it. Fugly! I did not attempt to "flush the buffer". I indicated where we might want to - only if we're reading from stdin!
; nasm -f elf32 l_gets.asm -d TESTMAIN
; ld -o l_gets l_gets.o
bits 32
%ifdef TESTMAIN
section .bss
buf resb 80
fd resd 1
section .data
filename db `l_gets.asm\0` ; ourself - we know it's there
section .text
global _start
_start:
mov eax, 5 ; sys_open
mov ebx, filename
xor ecx, ecx
xor edx, edx
int 80h
test eax, eax
js exit ; bail out if error
mov [fd], eax
; test a call to it
; try multiple calls if we're reading file
; just to make sure we're stopping at LF
; and can continue from there
mov esi, 7
top:
push 80 ; length
push buf
push dword [fd]
call l_gets
add esp, 4 * 3
; print what we l_getsed - l_got?
mov edx, eax ; length read
mov eax, 4 ;sys_write
mov ebx, 1 ; stdout
mov ecx, buf
int 80h
; only if we're doing multiple reads
dec esi
jnz top
exit:
mov ebx, eax ; return value is number of bytes written (len)
mov eax, 1 ; sys exit
int 0x80
%endif
;-----------------------------
section .text
global l_gets
l_gets:
push ebp ; prologue
mov ebp, esp
push ebx ; preserve ebx
push esi
mov ebx, [ebp + 8] ; fd parameter into ebx
mov ecx, [ebp + 12] ; char *buf in ecx
mov edx, [ebp + 16] ; len in edx
xor esi, esi ; counter
cmp edx, 0 ; if len zero or less, exit
jle .done
mov edx, 1 ; read one byte at a time. ugh!
.char_loop:
inc esi ; increment count first
mov eax, 3 ; sys read
int 0x80
cmp [ecx], byte 0xA ; test for linefeed
je .done
inc ecx ; advance to next byte
cmp esi, [ebp + 16] ; does read bytes = len?
je .done
; if this happens, we didn't find a LF
; if we're reading stdin, this indicates overflow
; we might want to flush OS's input buffer ("keyboard buffer")
jmp .char_loop
.done:
mov eax, esi ; # bytes read into eax
pop esi
pop ebx ; restore ebx
mov esp, ebp ; epilogue
pop ebp
ret
;-----------------------------------------------
That's as far as I got. I'm not sure it's "complete". See what you think...
Best,
Frank
Ah, again we're bumping into each other. Your l_write looks good at first glance. It returns the number of bytes written because that's what sys_write does!