alexandernst
alexandernst

Reputation: 15099

Calling printf from inline ASM (X64)

I have this code:

#include <stdio.h>
#include <stdint.h>

int main(void){
    char *fmt = "%s";
    char *s = "Hello world!\n";

//gcc -m32 test.c
#ifdef __i386__
    int32_t ret;
    __asm__ __volatile__ (
        "push %1\n\t"
        "push %2\n\t"
        "movl $2, %%eax\n\t"
        "call printf\n\t"
        "movl %0, %%eax"
        : "=r" (ret)
        : "r" (s), "r" (fmt)
        :
    );
#endif

//gcc -m64 test.c
#ifdef __x86_64__
    int64_t ret;
    __asm__ __volatile__ (
        "push %1\n\t"
        "push %2\n\t"
        "movq $2, %%rax\n\t"
        "call printf\n\t"
        "movq %0, %%rax"
        : "=r" (ret)
        : "r" (s), "r" (fmt)
        :
    );
#endif

    return ret;
}

The x86 version works as expected, but the x64 version segfaults. Why is it segfault-ing?

Upvotes: 0

Views: 1588

Answers (2)

Fabel
Fabel

Reputation: 1761

The 64-bit ABI uses registers (RDI, RSI, RDX, RCX, R8 and R9) instead of the stack for argument passing. So the code should be:

movl %2,%%rdi
movl %1,%%rsi
call printf
movq %0,%%rax

Upvotes: 1

Aif
Aif

Reputation: 11220

I think this is relative to 64bit EABI. You can find some information on that SO question.

Upvotes: 1

Related Questions