0

This is the code I have:

section .bss
    bufflen equ 1024
    buff: resb bufflen

    whatread: resb 8

section .data

section .text

global main

main:
    nop
    read:
        mov eax,3           ; Specify sys_read
        mov ebx,0           ; Specify standard input
        mov ecx,buff        ; Where to read to...
        mov edx,bufflen     ; How long to read
        int 80h             ; Tell linux to do its magic

                            ; Eax currently has the return value from linux system call..
        add eax, 30h        ; Convert number to ASCII digit
        mov [whatread],eax  ; Store how many byte reads info to memory at loc whatread

        mov eax,4           ; Specify sys_write
        mov ebx,1           ; Specify standart output
        mov ecx,whatread    ; Get the address of whatread in ecx
        mov edx,4           ; number of bytes to be written
        int 80h             ; Tell linux to do its work

        mov eax,3           ; Specify sys_read
        mov ebx,0           ; Specify standard input
        mov ecx,buff        ; Where to read to...
        mov edx,bufflen     ; How long to read
        int 80h             ; Tell linux to do its magic

                            ; Eax currently has the return value from linux system call..
        add eax, 30h        ; Convert number to ASCII digit
        mov [whatread],eax  ; Store how many byte reads info to memory at loc whatread

        mov eax,4           ; Specify sys_write
        mov ebx,1           ; Specify standart output
        mov ecx,whatread    ; Get the address of whatread in ecx
        mov edx,4           ; number of bytes to be written
        int 80h             ; Tell linux to do its work

    mov eax, 1; 
    mov ebx, 0; 
    int 80h

and I have a file called all.txt with contents:

61 62 63 0A 64 65 66 0A (abc - new line - def - new line)

Here is a sample run:

koray@koray-VirtualBox:~/asm/buffasm$ ./buff < all.txt
80koray@koray-VirtualBox:~/asm/buffasm$ 

So the first read of the code tries to read 1024 bytes from the file. The file itself has 8 bytes.. Then it prints 8 in the console which is fine I guess. But then, why does it print a '0' which means an end of file? I would expect it to read the same 8 bytes again? Why is it trying to read the next 1024 bytes?

Koray Tugay
  • 22,894
  • 45
  • 188
  • 319
  • 1
    Why would it re-read? You hit end-of-file and you haven't reset the file pointer. You know about this concept of a current position in files, right? That is not asm-specific thing. – Jester Jan 13 '15 at 16:34
  • @Jester Where does it keep the file pointer? As far as I see I am passing the same file again and it should not be aware of this? How can I reset the pointer? – Koray Tugay Jan 13 '15 at 16:35
  • @Jester Also, why doesn't it read an EOF in the first try as the 9th byte? – Koray Tugay Jan 13 '15 at 16:36
  • 1
    The kernel maintains the file pointer for the open files. You can reset the pointer by using `lseek` system call. The `read` system call may return less data than requested, that's why you get `8` first and only get `0` when no more data can be read. Also note not all files are seekable (for example if you don't redirect `stdin`). – Jester Jan 13 '15 at 16:36
  • 1
    @KorayTugay: why doesn't it read an `EOF` as the last byte? Because `EOF` is not a "byte" (say `char`), it's an `int`. Which is why something like `getchar()` returns an `int`. `read()` doesn't have to write `EOF` to your buffer, because it returns the number of `char`s read. – EOF Jan 13 '15 at 17:37

1 Answers1

0

There is no logic the program to read the same bytes again. They are already read and in the buffer. The input buffer (filled by the redirected file) is empty, so no more bytes can be read. That is why the sys_read ends with 0 read bytes.

The same logic will be if it was not STDIN, but a real file (of course, previously opened by sys_open).

BTW, returned count of 0 is actually what is called EOF.

johnfound
  • 6,857
  • 4
  • 31
  • 60