从内联 ASM (X64) 调用 printf

标签 c linux

我有这个代码:

#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;
}

x86 版本按预期工作,但 x64 版本出现段错误。为什么会出现段错误?

最佳答案

64 位 ABI 使用寄存器(RDI、RSI、RDX、RCX、R8 和 R9)而不是堆栈来传递参数。所以代码应该是:

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

关于从内联 ASM (X64) 调用 printf,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20301201/

相关文章:

c++ - OOP 中的 GLFWwindowsizefun 可访问性

c - select() 系统调用未按预期工作

linux - 反向排序文件中的第三个数字列

linux - 使用 valet-linux 在 ubuntu 中仅显示默认页面

android - 识别/proc/*/maps 中的代码段的好方法

python - 找出每个 clientId 的新旧映射之间的差异

将十六进制字符串转换为 signed int 会在不同平台上产生不同的值

c - C 中的双向链表崩溃

linux - cat source.txt | cat source.txt 和有什么区别grep x 和 grep x source.txt?

c - Memcpy 函数在 C 中崩溃