Writing Files in Assembly Language

Here’s the translation of the Go code to Assembly Language, formatted in Markdown suitable for Hugo:

section .data
    hello db 'hello', 0xA
    helloLen equ $ - hello
    go db 'go', 0xA
    goLen equ $ - go
    some db 'some', 0xA
    someLen equ $ - some
    writes db 'writes', 0xA
    writesLen equ $ - writes
    buffered db 'buffered', 0xA
    bufferedLen equ $ - buffered
    wrote db 'wrote %d bytes', 0xA, 0
    filename1 db '/tmp/dat1', 0
    filename2 db '/tmp/dat2', 0
    mode dw 644o

section .bss
    fd resq 1

section .text
    global _start
    extern printf

_start:
    ; Write to /tmp/dat1
    mov rax, 2
    mov rdi, filename1
    mov rsi, 64o | 1o
    mov rdx, mode
    syscall
    
    mov [fd], rax
    
    mov rax, 1
    mov rdi, [fd]
    mov rsi, hello
    mov rdx, helloLen
    syscall
    
    mov rax, 1
    mov rdi, [fd]
    mov rsi, go
    mov rdx, goLen
    syscall
    
    mov rax, 3
    mov rdi, [fd]
    syscall
    
    ; Write to /tmp/dat2
    mov rax, 2
    mov rdi, filename2
    mov rsi, 64o | 1o
    mov rdx, mode
    syscall
    
    mov [fd], rax
    
    mov rax, 1
    mov rdi, [fd]
    mov rsi, some
    mov rdx, someLen
    syscall
    
    push someLen
    push wrote
    call printf
    add rsp, 16
    
    mov rax, 1
    mov rdi, [fd]
    mov rsi, writes
    mov rdx, writesLen
    syscall
    
    push writesLen
    push wrote
    call printf
    add rsp, 16
    
    mov rax, 1
    mov rdi, [fd]
    mov rsi, buffered
    mov rdx, bufferedLen
    syscall
    
    push bufferedLen
    push wrote
    call printf
    add rsp, 16
    
    mov rax, 3
    mov rdi, [fd]
    syscall
    
    mov rax, 60
    xor rdi, rdi
    syscall

This Assembly Language code demonstrates file writing operations similar to the original example. Here’s an explanation of the key parts:

  1. We define our data in the .data section, including the strings we want to write and the filenames.

  2. In the .bss section, we reserve space for the file descriptor.

  3. The actual file operations are performed in the .text section:

    • We use the syscall instruction to perform system calls for file operations.
    • rax is set to 2 for opening files, 1 for writing, and 3 for closing.
    • File permissions are set using octal notation (644o).
  4. We write to /tmp/dat1 first, then to /tmp/dat2.

  5. After each write operation, we call printf to display the number of bytes written.

  6. Finally, we close the files and exit the program.

To run this program, you would need to assemble it into an object file and then link it to create an executable. The exact commands may vary depending on your system and assembler, but it might look something like this:

$ nasm -f elf64 writing-files.asm
$ ld writing-files.o -o writing-files
$ ./writing-files
wrote 5 bytes
wrote 7 bytes
wrote 9 bytes

After running the program, you can check the contents of the written files:

$ cat /tmp/dat1
hello
go
$ cat /tmp/dat2
some
writes
buffered

This Assembly Language version provides a low-level implementation of file writing operations, demonstrating direct system calls for file handling.