0

How to write data into an external file on Linux?

For instance, if I start the code with .include "output.s" and want to write "1111 0000" into it, then how to do this.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
User
  • 3
  • 2
  • 2
    `.include` seems like an assemble time directive. Assemblers generally don't support writing anything (except the output file) at assemble time. Perhaps you are mixing up build time inclusion with run time file access. – ecm Oct 20 '22 at 10:02
  • Then how to store text into an external file using assembly? – User Oct 20 '22 at 10:05
  • Or do you mean that it is not possible to write anything to an external file using assembly? – User Oct 20 '22 at 10:09
  • 1
    Do you mean something like https://stackoverflow.com/questions/8312290/how-to-open-a-file-in-assembler-and-modify-it – Özgür Güzeldereli Oct 20 '22 at 10:12
  • 1
    What operating system are you programming for? Are you programming with the libc? – fuz Oct 20 '22 at 10:16
  • Operating system is linux (ubuntu if it matters), and I am programming with libc – User Oct 20 '22 at 10:19
  • 2
    @User Then open write and close files the same way you would do it in C, i.e. by calling `open`, `write`, and `close`. If you like, I can write an example for you. – fuz Oct 20 '22 at 10:24
  • An example would be nice. – User Oct 20 '22 at 10:26
  • [read and write to file assembly](https://stackoverflow.com/q/37940707) has a 32-bit Linux example of making `open` and `read`/`write` system calls. But it also starts off with a high-level overview of what to do, which you could do with x86-64 call numbers / calling convention for `syscall`. – Peter Cordes Oct 20 '22 at 10:42
  • Some existing Q&As that use NASM syntax include: [How to append to a file using x86-64 Linux system calls?](https://stackoverflow.com/q/48541868) / [Why does my assembly code not work? It should open, write to and read a file on Linux x86\_64](https://stackoverflow.com/q/62510576). And a GAS Q&A: [How to rewrite a files content? Linux x86\_64, assembly, GAS](https://stackoverflow.com/q/53125140) – Peter Cordes Oct 20 '22 at 10:46

1 Answers1

1

The best way to do file I/O is to use the libc. Envision how you would do it in C, then do the same thing in assembly. For example, in C you could do

int main() {
    ssize_t n;
    int fd;
    char buf[9] = "1111 0000";

    fd = creat("output.s", 0666);
    if (fd == -1) {
        perror("output.s");
        return (EXIT_FAILURE);
    }

    n = write(fd, buf, sizeof buf);
    if (n == -1) {
        perror("output.s");
        return (EXIT_FAILURE);
    }

    close(fd);

    return (EXIT_SUCCESS);
}

Next, translate the code step by step into assembly:

        .data
name:   .string "output.s"              # the file name
buf:    .ascii  "1111 0000"
buflen=         .-buf                   # the length of buf

        .text
        .globl  main
        .type   main, @function

main:   push    %rbx                    # free rbx and align stack

        lea     name(%rip), %rdi        # file name
        mov     $0666, %esi             # initial permissions
        call    creat                   # create the file
        cmp     $-1, %eax               # was the call successful?
        je      .Lfail                  # if not, process error

        mov     %eax, %ebx              # stash a copy of the file descriptor
        mov     %eax, %edi              # file descriptor
        lea     buf(%rip), %rsi         # buffer
        mov     $buflen, %edx           # buffer length
        call    write                   # write data
        cmp     $-1, %rax               # was the call successful?
        je      .Lfail                  # if not, process error

        mov     %ebx, %edi              # file descriptor
        call    close                   # close the file

        xor     %eax, %eax              # return EXIT_SUCCESS
        pop     %rbx                    # restore %rbx
        ret

.Lfail: lea     name(%rip), %rdi        # the file name
        call    perror                  # print an error message

        mov     $1, %eax                # return EXIT_FAILURE
        pop     %rbx                    # restore %rbx
        ret

        .size   main, .-main
fuz
  • 88,405
  • 25
  • 200
  • 352