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:
fread
.fread
and fclose
.Questions summary:
Additional Information:
I'm a newbie to assembly, and a self learner. Thank you in advance for your help!
- 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:
size
bytes long. You appear to be passing 0, which would not read anything. If you pass 1 as the item size, then you might well want to pass the buffer size here (less 1 to leave room for a string terminator, if you need that).FILE*
indicating the source from which to read the dataFurthermore, 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?
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.
You need to be attentive to the possibility of internal null characters in data you are treating as a C string.
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
.
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.