writing to file using syscalls in x86_64 assembly (not NASM)

89 Views Asked by At

Before I start writing this question, just in case it gets flagged for duplicates: this is NOT using NASM syntax. All the other questions use NASM, which I don't know. Anyways:

I'm trying to simply write to a txt file using x86_64 assembly (GNU), and I can't seem to get the desired write outcome. I'm using the open, write, and close syscall codes to achieve my goal, but apparently to no avail. I am compiling using the following commands:

sudo as -o db.o db.S
sudo ld -s -o db db.o
./db

Here is my assembly code. You can pretty much ignore all print and println functions, the main one I'm concerned about is write_to_txt_file:

EDIT: I just learned how to run this through gdb and %rax (the return register) after the first syscall in the write function was -22. I have no idea what this means but I'm doing research. For your reference, this is in Linux

EDIT 2: someone mentioned using strace. When I do, this is the output. I have never used strace before, so I have no clue what to do with this info, but I'm going to do some research while waiting for other responses

enter image description here

EDIT 3: I have made changes according to the suggestions in the comments, and now have error code -2 instead of -22. It seems like the program is struggling to find my text file, despite the .S file being in the same directory as my txt file

EDIT 4: Using strace cat database.txt and strace tee database.txt, I get the following outputs near the end:

cat:

openat(AT_FDCWD, "database.txt", O_RDONLY) = 3
newfstatat(3, "", {st_mode=S_IFREG|0644, st_size=0, ...}, AT_EMPTY_PATH) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
mmap(NULL, 139264, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f6126f1d000
read(3, "", 131072)                     = 0
munmap(0x7f6126f1d000, 139264)          = 0
close(3)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?

tee: doesn't finish running. I have to use ctrl-c to exit it. I then get this:

strace: Process 19309 detached
 <detached ...>

EDIT 5: moved filename to the top of my data declarations. Now when I run strace, I get this: enter image description here

EDIT 6: this issue is now solved. I have put the working function below if anyone else is going through similar confusions

ACTUAL CODE

write_to_txt_file:
#%rdi must hold an address to a character array, like mov $buf, %rdi
#%rsi must hold %rdi's length, like mov $tlen, %rsi

    push %rdi
    push %rsi

    #open file:
    mov $0x2, %rax
    mov $filename, %rdi
    mov $0x61, %rdx
    mov $0x441, %rsi
    syscall

    mov %rax, %r8

    #write to file:
    mov $0x1, %rax
    mov %r8, %rdi
    pop %r13    #contents of %rdi which were pushed onto the stack get popped into %r12
    pop %r12    #^^same but with length
    mov %r12, %rsi
    mov %r13, %rdx
    syscall

    ret

0

There are 0 best solutions below