温馨提示×

linux c++怎样调系统调用

小樊
49
2026-09-23 09:09:23
栏目: 编程语言

在 Linux 下用 C++ 调用系统调用(syscall),常见有几种方式,从“最常用”到“最底层”依次是:


一、最常用:使用 glibc 封装的 API(推荐)

绝大多数系统调用,Linux 都通过 glibc 提供了 C/C++ 函数接口。

示例:write 系统调用

#include <unistd.h>
#include <fcntl.h>
#include <cstring>

int main() {
    int fd = open("test.txt", O_WRONLY | O_CREAT, 0644);
    const char* msg = "hello\n";
    write(fd, msg, strlen(msg));
    close(fd);
    return 0;
}

✅ 优点:

  • 简单、可移植
  • 编译器自动处理参数和寄存器

二、直接调用 syscall() 函数(无 glibc 封装时)

当某个系统调用 glibc 没有封装,可以用 syscall():

#include <unistd.h>
#include <sys/syscall.h>
#include <linux/perf_event.h>

int main() {
    long id = syscall(SYS_gettid);
    return 0;
}

示例:调用自定义 / 新加的系统调用

syscall(333, arg1, arg2);

✅ 适合:

  • 内核新特性
  • 自己写的系统调用

三、内联汇编(最底层,x86_64)

直接通过 int 0x80 或 syscall 指令。

x86_64 示例(write)

#include <cstring>

int main() {
    const char* msg = "hi\n";
    long len = strlen(msg);

    asm volatile (
        "mov $1, %%rax\n"   // syscall number: write
        "mov $1, %%rdi\n"   // fd = 1
        "mov %0, %%rsi\n"
        "mov %1, %%rdx\n"
        "syscall"
        :
        : "r"(msg), "r"(len)
        : "%rax", "%rdi", "%rsi", "%rdx"
    );
    return 0;
}

⚠️ 不推荐日常使用,容易出错。


四、自己新增系统调用(进阶)

如果你是在写内核模块 / 修改内核:

  1. 在内核中添加 syscall
  2. 分配 syscall 号
  3. 用户态用 syscall() 调用

五、如何查系统调用号?

cat /usr/include/asm/unistd_64.h

或者:

man 2 syscall
man 2 open

总结

方式 推荐度 场景
glibc 函数 ⭐⭐⭐⭐⭐ 日常开发
syscall() ⭐⭐⭐⭐ 无封装调用
内联汇编 ⭐ 内核/底层研究

如果你有具体系统调用(如 fork、ioctl、epoll、自定义 syscall),我可以给你完整 C++ 示例。

0 踩