cassemblynasmmingw-w64windows64

Problems with File Reading and Printing in Assembly Using C Library Functions on Windows 64-bit


I'm working on a 64-bit assembly program using NASM and MinGW on Windows 10. My goal is to read the content of a file and print it to the console using C library functions (fopen, fread, fclose).

While the file is successfully opened, and the program prints the "File content:" prompt, the content of the file is not being displayed as expected. The file content either does not print at all.

Here's my current code:

; read file and print content

section .data
    filename db "test.txt", 0
    read_mode db "r", 0
    prompt db "File content:", 10, 0
    buffer_size equ 1024
    bytes_read dq 0
    hFile dq 0
    buffer db buffer_size dup(0)
    error_msg db "Failed to open the file.", 10, 0

section .text
    extern printf, fopen, fread, fclose
    global main

main:
    push rbp
    mov rbp, rsp

    ; Open the file
    lea rcx, [rel filename]  ; Filename
    lea rdx, [rel read_mode] ; Read mode
    call fopen
    mov [rel hFile], rax         ; Store file handle

    ; Check if the file was opened successfully
    cmp rax, 0
    je file_error

    ; Read file content
    lea rcx, [rel buffer]       ; Buffer
    mov rdx, buffer_size        ; Buffer size
    lea r8, [rel bytes_read]    ; Bytes read
    mov r9, [rel hFile]         ; File handle
    call fread

    ; Print the content
    lea rcx, [rel prompt]       ; Print the prompt
    call printf

    lea rcx, [rel buffer]       ; Print the buffer content
    call printf

    ; Close the file
    mov rcx, [rel hFile]
    call fclose

    ; Clean up and exit
    jmp program_end

file_error:
    lea rcx, [rel error_msg]
    call printf

program_end:
    mov rsp, rbp
    pop rbp
    ret

Issues:

What I've Tried:

Questions summary:

Additional Information:

I'm a newbie to assembly, and a self learner. Thank you in advance for your help!


Solution

    • Is there something wrong with how fread is used in this context?

    Yes, it appears so. Exactly what that is depends on precisely what you wanted to do. The arguments to fread are, in order:

    Furthermore, the return value should not be ignored. It conveys the number of items read (not bytes, unless the item size is 1), and that may be less than requested, even 0.

    • Are there any known issues with using printf to print the buffer when dealing with C library functions in assembly?
    • How can I ensure that the buffer is properly handled and printed?
    1. If you want to treat data as a C string then you must ensure that it is null-terminated. fread does not do that for you.

    2. You need to be attentive to the possibility of internal null characters in data you are treating as a C string.

    3. Arbitrary data should not be used as a printf format string. Instead, use format "%s" and pass (a pointer to) the data as a second argument, or else print with puts (which will add a newline at the end) or fputs.

    4. Also, be mindful that printf is a variadic function, with the variable arguments comprising all but the first. However, I don't think that the Windows x64 calling convention requires different handling for variadic functions.