2
votes

I'm having a problem trying to open a file and read from it. The user is prompted for the file name.

The program compiles without error but doesn't show anything. When I hardcode the filename in the .data section it runs fine, but when I get the filename from the user it fails to read the file. Where am I doing wrong? I can't find any error.

Output using hardcoded name: welcome

Output when user enters the name: ���

Here is my code:

section .data
    promptUsr db 'enter a file name:',0xA,0xD
    lenPrompt equ $-promptUsr
    info db 1
    ;file_name db 'data.txt' (NOTE:harcoded name works when used)
section .bss
    fd_in resb 1
    buffer resb 7
    file_name resb 20  
section .text
    global _start
_start:

;prompt user to enter a file name
        mov eax,4   ;sys_write
        mov ebx,1   ;stdout
        mov ecx,promptUsr
        mov edx,lenPrompt
    int 0x80

;read filename  (NOTE:when user enters the same name 'data.txt',this is the output:���)
        mov eax,3   
        mov ebx,2   
        mov ecx,file_name   ;(NOTE:tried using 'dword[file_name]',doesnt work)
        mov edx,20
    int 0x80

;open file 
    mov eax,5
    mov ebx,file_name   ;(NOTE:also tried using 'dword[file_name]',doesnt work too)
    mov ecx,2           ;read n write
    mov edx,7777h   ;all file permissions
   int 0x80 
    mov [fd_in],eax 

;read 7 bytes of the file
    mov eax,3
    mov ebx,[fd_in]
    mov ecx,buffer  
    mov edx,7       
    int 0x80    

;close the file
    mov eax,6
   int 0x80
;print out what was read
    mov eax,4
    mov ebx,1
    mov ecx,buffer
    mov edx,7
   int 0x80
;end program
    mov eax,1
   int 0x80
2
would also love to know how to check first if the file exists before opening it.thanx anyonemig

2 Answers

1
votes

To add to what Michael says... 1) fd_in is too small - make it resd 1. 2) sys_read doesn't return a zero-terminated string, and sys_open wants one.

mov byte [ecx + eax - 1], 0

after the sys_read of the filename should zero-terminate it.

0
votes

Looks like you're trying to read from STDERR:

mov eax,3   
mov ebx,2   
mov ecx,file_name   ;(NOTE:tried using 'dword[file_name]',doesnt work)
mov edx,20

That mov ebx,2 ought to be mov ebx,0 if you want to read from STDIN.


would also love to know how to check first if the file exists before opening it

If you use sys_open without the O_CREAT flag set, it should fail and return -1 if the file doesn't already exist. You could also use access (syscall 33) or stat (syscall 18) if you want to.