【问题标题】:x86_64 Linux syscall argumentsx86_64 Linux 系统调用参数
【发布时间】:2014-04-22 01:51:30
【问题描述】:

我正在 Linux 上学习 x86_64 汇编,我遇到了一些相互矛盾的信息,我希望这些信息可以得到澄清。一方面,我读到对于系统调用参数,您将按照 rdi、rsi、rdx 等的顺序使用寄存器。但另一方面,我读到您使用寄存器 rbx、rcx、rdx 等。有人告诉我,这是因为 ABI,但我并不完全理解这到底意味着什么。

为什么有两种格式,哪一种更合适?

【问题讨论】:

    标签: linux assembly x86-64 system-calls abi


    【解决方案1】:

    根据this Wikibooks page,这取决于您用于执行系统调用的指令。

    • 如果您使用的是int $0x80(32 位 ABI,调用号码来自asm/unistd_32.h),那么您应该使用eax 作为系统调用号码,并使用ebxecxedxesiediebp 用于参数(按此顺序)。

    • 如果您使用 syscall 指令(64 位 ABI,本机调用号来自 asm/unistd.h),则应使用 rax 作为系统调用号,rdirsirdxr10r8r9 用于参数。

    What are the calling conventions for UNIX & Linux system calls on i386 and x86-64

    在 64 位模式下,syscall 是首选,因为它更快,适用于所有 x86-64 Linux 内核,并且支持 64 位指针和整数。 int 0x80 ABI 真正接受ecx 中的输入,而不是rcx,例如,使其无法用于64 位代码中堆栈上的缓冲区的writereadWhat happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?.

    【讨论】:

    • 好吧,考虑到我使用的是 x86_64,我会使用 syscall。我刚刚看到 rbx rcxrdx 被用作参数(按此顺序)的示例,并且对原因感到困惑。
    • @Chiggins 您是否有机会向我们指出rbxrcxrdx 用于使用x86_64 进行系统调用的示例?我只是好奇。
    • @Chiggins 好吧,要么代码示例不起作用,要么 Wikibooks 错误。你可以很容易地编写一个测试用例。在rdirsi 等中放入一组参数,在rbx 等中放入另一组。调用系统调用并查看使用了哪组参数。
    • @augurar 代码示例有效,我自己编译并测试过。
    • @Chiggins 请注意,链接中的前两个系统调用使用了错误的寄存器集,只是将它们归零。但是零是(几乎)所有寄存器在程序入口点上的值,所以这些xors 实际上是无操作的。这就是为什么该程序可能适合您的原因,尽管它有时会错误地传递参数。
    猜你喜欢
    • 2012-01-20
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 2015-06-09
    • 2010-11-15
    • 2012-07-19
    • 1970-01-01
    • 2014-07-07
    相关资源
    最近更新 更多