Edward Lim
Edward Lim

Reputation: 823

NASM assembly language cant seem to save output to a file

Ok so im following along a tutorial and i've been scratching my brains out over this.. I've tried looking for resources but nothing seems to work or click. All Im trying to do is read input from a file, character by character then proceed to save it to another file. (Copying if you will) Right now Im running into two main issues that are driving me nuts.

  1. For some reason the output of the file is getting printed out to the terminal screen. Thats wonderful and all but that was not what I had in mind when I wrote this. It was supposed to just write to a file and exit.
  2. After running the script, the "output file" gets created but it's empty

The tutorial that Im following is found on https://www.tutorialspoint.com/assembly_programming/assembly_file_management.htm

section .data
    f_in: db "file_input.txt",0
    f_out: db "file_output.txt",0
section .bss
    Buff resb 1     ;hold the value of one char
    fd_in resb 1
    fd_out resb 1
section .data
global _start
_start:
    nop         ;keeps gdb debugger happy
;Creates the output file that will be used to store
Create:
    mov eax, 8      ;sys call, create
    mov ebx, f_out      ;file name is ebx register
    mov ecx, 666q       ;file permisions for the outfile in octal
    int 80h         ;kernel call
    mov [fd_out], eax   ;mov file desc into fd_out

;Open the input file to be read in read only mode
;(0) = read only
;(1) = write only
;(2) = read write only
Open:
    mov eax, 5      ;sys call, open
    mov ebx, f_in       ;file name in ebx
    mov ecx, 0      ;file access mode (0) == read only
    int 80h         ;kernel call
    mov [fd_in], eax    ;mov file desc into fd_in

;Read the opened file data into Buff var declared above
;Buff only holds 1 byte
Read:   
    mov eax, 3      ;sys call, read
    mov ebx, [fd_in]    ;mov file desc in ebx
    mov ecx, Buff       ;mov pointer Buff into ecx
    mov edx, 1      ;mov Buff size into edx
    int 80h

    cmp eax, 0      ;check val in eax with 0
    je Exit         ;if eax is (0 means EOF) so exit

;write all the data encoded into the file
Write:
    mov eax, 4      ;sys call, write
    mov ebx, [fd_out]   ;file descriptor
    mov ecx, Buff       ;message to write
    mov edx, 1      ;length of message
    int 80h
    jmp Read        ;go back to begining and read again

Exit:
;close the files
Close_files:
    mov eax, 6      ;sys call, close
    mov ebx, [fd_in]    ;put file descriptor in ebx
    int 80h
    mov ebx, [fd_out]
    int 80h
;now exit after files are closed
    mov eax, 1      ;sys call, exit
    int 80h

Upvotes: 0

Views: 801

Answers (1)

Mike Nakis
Mike Nakis

Reputation: 61969

With fd_in resb 1 and fd_out resb 1 you are reserving ONLY ONE BYTE for your file handles. But then you read and write an entire ebx to and from those locations. ebx is 4 bytes long. That's not going to work very well.

Try resb 4 for both file handles.

An explanation of what is precisely happening: you open the output file, and you store the handle in fd_out. The file handle is probably something like 5, so 5 is written at fd_out, and the next 3 bytes are cleared with zeros. Then, you open the input file, and you store the handle in fd_in. This file handle is, say, 6, so 6 is written in fd_in, and the following 3 bytes are cleared, which means that fd_out is cleared, because it is located right after fd_in in memory. Then, next time you load fd_out into ebx, you are reading four zero bytes, meaning 0. A file handle of 0 apparently corresponds to the standard output, that's why everything is dumped to the screen.

Upvotes: 3

Related Questions