C 如何嵌入内联程序集以调用sys\u unlink?

C 如何嵌入内联程序集以调用sys\u unlink?,c,assembly,inline-assembly,system-calls,unlink,C,Assembly,Inline Assembly,System Calls,Unlink,我尝试使用内联程序集调用sys_unlink,如下所示: int sys_unlink(const char *filename) { int ret; __asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename)); return ret; } 但它不起作用,它总是返回-14 我想知道这段代码是否正确,因为我对汇编不太了解。这段代码只对x86(32位)进程正确-它没有对x86-64进程使用正确的系统调用号。

我尝试使用内联程序集调用sys_unlink,如下所示:

 int sys_unlink(const char *filename) {

    int ret;

    __asm__("int $0x80" : "=a"(ret) : "a"(10), "b"(filename));

    return ret;

}
但它不起作用,它总是返回-14


我想知道这段代码是否正确,因为我对汇编不太了解。

这段代码只对x86(32位)进程正确-它没有对x86-64进程使用正确的系统调用号。使用
\uuu NR\u从
asm/unistd.h
取消链接,而不是硬编码的
10

#include <asm/unistd.h>

int sys_unlink(const char *filename)
{
    int ret;

    asm("int $0x80" : "=a"(ret) : "a"(__NR_unlink), "b"(filename));
    return ret;
}
#包括
int sys_unlink(常量字符*文件名)
{
int ret;
asm(“int$0x80”:“=a”(ret):“a”((未链接),“b”(文件名));
返回ret;
}

如果您正在编译一个32位进程,则
-14
EFAULT
,表示您传递的文件名有问题。如何调用它?

该代码仅适用于x86(32位)进程-它没有为x86-64进程使用正确的系统调用号。使用
\uuu NR\u从
asm/unistd.h
取消链接,而不是硬编码的
10

#include <asm/unistd.h>

int sys_unlink(const char *filename)
{
    int ret;

    asm("int $0x80" : "=a"(ret) : "a"(__NR_unlink), "b"(filename));
    return ret;
}
#包括
int sys_unlink(常量字符*文件名)
{
int ret;
asm(“int$0x80”:“=a”(ret):“a”((未链接),“b”(文件名));
返回ret;
}

如果您正在编译一个32位进程,则
-14
EFAULT
,表示您传递的文件名有问题。您如何称呼它?

我认为您甚至不能将此工作限制在Linux下的单个平台上:Linux进行系统调用的现代方式是通过内核提供的存根并通过VDSO链接。即使是您正在链接的libc也不知道(不需要知道)系统调用约定是什么——它只是从VDSO中提取一个引用。它通过一个隐藏在
environ
之后的神奇参数获取对VDSO的引用,然后将其视为任何其他动态库。内核根据CPU能力选择系统调用约定


我碰巧知道(因为我试过这么做!)很难访问那些VDSO符号。glibc不会为您导出它们(或任何有用的句柄)。我看到的唯一可行的方法是检查您自己的
/proc/self/maps
以找到VDSO,然后使用
dl
函数来获得它(重复一些glibc设置工作).

我认为在Linux下,您甚至不能将此工作限制在单个平台上:Linux进行系统调用的现代方式是通过内核提供的存根,并通过VDSO链接。即使是您正在链接的libc也不知道(不需要知道)系统调用约定是什么——它只是从VDSO中提取一个引用。它通过一个隐藏在
environ
之后的神奇参数获取对VDSO的引用,然后将其视为任何其他动态库。内核根据CPU能力选择系统调用约定


我碰巧知道(因为我试过这么做!)很难访问那些VDSO符号。glibc不会为您导出它们(或任何有用的句柄)。我看到的唯一可行的方法是检查您自己的
/proc/self/maps
以找到VDSO,然后使用
dl
函数来获取它(重复一些glibc设置工作)。

旧的
int$0x80
入口点仍然受支持(并且将在很长一段时间内得到支持),因为它是旧ABI的一个基本部分。
int$0x80
接口对于实现
clone
也是必不可少的,因为VDSO接口需要一个工作堆栈,而使用
SYS\u clone
时,堆栈是在syscall返回后在用户空间中创建的。旧的
int$0x80
入口点仍然受支持(并且将在很长一段时间内得到支持),因为它是旧ABI的基本部分。
int$0x80
接口对于实现
clone
也是必不可少的,因为VDSO接口需要一个工作堆栈,而对于
SYS\u clone
,堆栈是在syscall返回后在用户空间中创建的。谢谢你的回答,我使用的是64位机器。我在取消链接时更改了10,但现在我得到了-1(EPERM)。谢谢你的回答,我使用的是64位机器。我在取消链接时更改了10,但现在得到了-1(EPERM)