Cat program in x64 FASM I wrote cat program in x64 FASM and I would like to know if there is anything that can be improved.

This implementation of cat supports:


Reading from stdin.
Multiple arguments.


I checked few cases and program behaves exactly like original cat command.

Is there anything I could do to improve performance of this program? I compared it to original cat and my program is around 200ms slower on 512MB file.

Code:

format ELF64 executable 3
entry start

BUFSIZE equ 1048576

segment readable writeable
    fd dq 0
    buf rb BUFSIZE

segment readable executable

start:
    mov rbx, 1
    cmp [rsp], rbx
    je read
open:
    xor rsi, rsi            ;fd=open(pathname,flags)
    mov rdi, [rsp+rbx*8+8]
    mov rax, 2
    syscall
    mov [fd], rax
read:
    mov rdx, BUFSIZE        ;bytes_read=read(fd,buf,BUFSIZE)
    mov rsi, buf
    mov rdi, [fd]
    mov rax, 0
    syscall
write:
    mov rdx, rax            ;write(STDOUT_FILENO,buf,bytes_read)
    mov rsi, buf
    mov rdi, 1
    mov rax, 1
    syscall
    test rdx, rdx           ;if(bytes_read!=0) goto read
    jnz read
close:
    mov rdi, [fd]           ;close(fd)
    mov rax, 3
    syscall
    inc rbx
    cmp rbx, [rsp]          ;if(rbx&lt;argc)
    jb open
exit:
    xor rdi, rdi
    mov rax, 60
    syscall
Linux has the sendfile system call, which copies data between file descriptors instead of copying the data to userspace and back to kernel space. That may be more efficient.

Your code looks very clean and organized. If you had used named constants instead of magic numbers, you might not even need some of the comments:

    mov rdx, tax
    mov rsi, but
    mov rdi, STDOUT_FILENO
    mov rax, SYS_write
    syscall


But I think even with these constants, the comments are still helpful, so I'd probably keep them anyway.

You should add error handling for stdout write errors, such as ENOSPACE.