Author Topic: printf affected by DF (direction flag)?  (Read 257 times)

Offline uvance

  • Jr. Member
  • *
  • Posts: 3
printf affected by DF (direction flag)?
« 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:

Code: [Select]
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:

Code: [Select]
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]
« Last Edit: October 14, 2022, 12:31:26 PM by uvance »

Offline fredericopissarra

  • Full Member
  • **
  • Posts: 228
  • Country: br
Re: printf affected by DF (direction flag)?
« Reply #1 on: October 14, 2022, 02:19:27 PM »
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:
Code: [Select]
char *endp = p + SIZE;
for ( char *q = p; p < endp; p++ )
  *q = '\0';
Can be optimized by the compiler as:
Code: [Select]
  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.
« Last Edit: October 14, 2022, 02:34:03 PM by fredericopissarra »