You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在OpenBSD等Unix平台上如何直接调用syscall而不使用封装函数?

OpenBSD 直接执行系统调用的实现方案

1. 直接使用 libc 提供的 syscall() 函数

这是最符合你需求的实现方式,OpenBSD 的标准 C 库原生提供了通用系统调用入口函数,你想要的 syscall(4, 1, "hello!", 6) 形式代码可以直接运行。
使用步骤:

  • 引入头文件 <sys/syscall.h>,这个头文件同时定义了所有系统调用的编号宏(比如SYS_write对应值就是4)
  • 直接按 syscall(系统调用号, 参数1, 参数2, ...) 格式编写代码即可
    可运行示例代码:
#include <sys/syscall.h>
#include <unistd.h>

int main(void) {
    // 两种写法都可以,直接写4和用SYS_write宏效果一致
    // syscall(SYS_write, 1, "hello!", 6);
    syscall(4, 1, "hello!", 6);
    return 0;
}

编译运行方式:

cc -o syscall_demo syscall_demo.c
./syscall_demo

运行后会直接在标准输出打印hello!。

2. 纯汇编实现无依赖系统调用

如果你连 libc 提供的syscall()封装都不想用,可以直接通过汇编指令触发系统调用,完全不依赖任何库函数。
以 amd64 架构 OpenBSD 为例,系统调用触发规则:

  • 系统调用编号存入rax寄存器
  • 参数按顺序存入rdi、rsi、rdx、r10、r8、r9寄存器
  • 执行syscall指令触发,调用返回值存在rax寄存器
    对应write调用的汇编示例片段:
mov rax, 4          ; write系统调用编号为4
mov rdi, 1          ; 第一个参数:标准输出文件描述符1
mov rsi, msg_ptr    ; 第二个参数:字符串首地址
mov rdx, 6          ; 第三个参数:字符串长度
syscall

注意:硬编码系统调用编号的代码不具备跨版本、跨架构兼容性,OpenBSD 不同版本间系统调用编号可能发生调整,非特殊需求不建议在生产代码中使用这类写法。

内容的提问来源于stack exchange,提问作者Dragos Polifronie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 13:06:05