Tip: glibc have wrapers around syscalls like, open(), read(), write(), create(), close()... The list of arguments are the same as the regular syscalls and follows the same calling convenction (except RCX is substituted by R10). If you take a look at 'man creat' and 'man open' you'll see that creat() is the same as open(), except the flags O_CREAT|O_WRONLY|O_TRUNC is assumed for the last one... Both functions will return a positive value (file descriptor) or negative (-1) in case of error (in EAX)...
Then, you can use open() to open/create a file using O_CREAT|O_RDWR|O_TRUNC if you want to be able to read/write the "new" file... and, take a look at the function prototype:
int open( const char *fname, int flags, mode_t mode );
Where `mode_t` is a typedef to 'int`... Using 'int' means you don't need the upper half of R?? registers, so you can write:
; test.asm
;
; Compiling and linking:
;
; nasm -felf64 -o test.o test.asm
; ld -s -o test test.o
;
bits 64
default rel
%define SYS_WRITE 1
%define SYS_OPEN 2
%define SYS_CLOSE 3
%define SYS_EXIT 60
%define STDERR_FILENO 2
; See with 'gcc -dM -E -include unistd.h - < /dev/null | grep O_'
%define O_CREAT 0o100
%define O_TRUNC 0o1000
%define O_RDWR 0o02
section .rodata
fname:
db "myfile.txt",0
errmsg1:
db `Cannot open/create file.\n`
errmsg1_len equ $ - errmsg1
errmsg2:
db `Error writing to file.\n`
errmsg2_len equ $ - errmsg2
buffer:
db `This should be writen to the file.\n`
buffer_len equ $ - buffer
section .text
global _start
_start:
; Try to open/create a file...
mov eax,SYS_OPEN
lea rdi,[fname] ; fname
mov esi,O_CREAT | O_RDWR | O_TRUNC ; flags
mov edx,0o0644 ; permission (in octal).
syscall
test eax,eax ; is the file descriptro negative?
jns .continue ; no? continue. yes? then...
; ... print error message...
lea rsi,[errmsg1]
mov edx,errmsg1_len
.printerr_exit:
mov edi,STDERR_FILENO
mov eax,SYS_WRITE
syscall
; ...and exit with error 1.
mov eax,SYS_EXIT
mov edi,1
syscall
.continue:
mov ebx,eax ; store fd in EBX (Preserved bewteen calls).
; Try to write a string to the file.
mov edi,eax ; Put file descriptor in EDI.
mov eax,SYS_WRITE
lea rsi,[buffer]
mov edx,buffer_len
syscall
test eax,eax ; write retuns -1 in case of error. Is it negative?
jns .continue2 ; no? continue. yes, then...
; ...close the file...
mov eax,SYS_CLOSE
mov edi,ebx
syscall
; ... and print error messgae and exit with 1.
lea rsi,[errmsg2]
mov edx,errmsg2_len
jmp .printerr_exit
.continue2:
; Close the file and exit with 0.
mov eax,SYS_CLOSE
mov edi,ebx
syscall
mov eax,SYS_EXIT
xor edi,edi
syscall