NASM - The Netwide Assembler
NASM Forum => Using NASM => Topic started by: uvance on October 14, 2022, 11:56:58 AM
-
I suppose this is a gray area since printf is C, not Assembly, but I see this being affected by the reflags, so.
I noticed that when I call printf with DF set it causes a segmentation fault. It works fine when DF is clear. Example below:
extern printf
section .data
string db "Hello there!",10,0
section .text
global main
main:
push rbp
mov rbp, rsp
; uncommenting the line below will cause a segmentation fault when printf is called
; std
mov rdi, string
mov rax, 0
call printf
xor rax, rax
mov rsp, rbp
pop rbp
ret
I couldn't find this behavior documented anywhere. Any idea about what is going on here?
For some reason it worked fine when it runs with gdb:
Reading symbols from printfdf...
(gdb) run
Starting program: /home/al/dev/asm/tests/movsb/printfdf
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Hello there!
[Inferior 1 (process 31333) exited normally]
-
I noticed that when I call printf with DF set it causes a segmentation fault...
Because the Application Binary Interface (ABI) tells you that the direction flag MUST be always cleared... If you changed it, clear it back before using anything else.
For "anything" I mean, including, expressions... This:
char *endp = p + SIZE;
for ( char *q = p; p < endp; p++ )
*q = '\0';
Can be optimized by the compiler as:
lea rdi,[p]
mov ecx,SIZE
xor eax,eax
rep stosb
Notice: Where's the 'cld'? Nowhere, huh? The compiler expects this flag being ALWAYS cleared.
If you don't your own routines only you can play with flags as you like, but if you are using routines made for C/C++ you have to respect the ABI.
This is docummented on POSIX, SysV ABI and MS-ABI, for example.