Calling printf from inline ASM (X64)

2019-09-02 09:28发布

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?

标签: c linux
2条回答
爷的心禁止访问
2楼-- · 2019-09-02 10:02

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
查看更多
Fickle 薄情
3楼-- · 2019-09-02 10:20

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

查看更多
登录 后发表回答