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

如何获取单个独立C函数的优化可执行二进制代码?

获取自包含C函数的优化二进制片段用于JIT整合

一、编译生成仅含目标函数的目标文件

首先用GCC/Clang编译你的add.c,开启优化选项(比如-O3)生成仅包含函数代码的目标文件:

gcc -O3 -c add.c -o add.o

这个add.o仅包含存储函数代码的.text段和少量必要元数据,没有可执行文件的冗余内容。

二、提取纯函数二进制字节

方法1:用objcopy生成纯二进制文件

直接提取.text段的原始机器码到独立文件:

objcopy -O binary --only-section=.text add.o add.bin

add.bin就是add函数的纯机器码字节,无任何额外数据。

方法2:用objdump提取十六进制机器码

如果需要直接得到可嵌入代码的字节数组,用objdump反汇编查看机器码:

objdump -d add.o

输出类似(以x86-64架构为例):

0000000000000000 <add>:
   0:   8d 04 37                lea    eax,[rdi+rsi*1]
   3:   c3                      ret

第二列的8d 04 37 c3就是函数的机器码,可直接写成C数组:

unsigned char add_code[] = {0x8d, 0x04, 0x37, 0xc3};

三、运行时加载并执行二进制片段

核心步骤

  1. 分配具备可执行权限的内存区域;
  2. 将二进制字节复制到该区域;
  3. 将内存地址转换为匹配函数签名的指针,直接调用。

示例代码

#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

// 定义匹配add函数签名的函数指针类型
typedef int (*AddFunc)(int, int);

int main() {
    // 读取add.bin文件
    int fd = open("add.bin", O_RDONLY);
    off_t code_size = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);

    // 分配可读写可执行的匿名内存
    void *exec_mem = mmap(
        NULL, code_size,
        PROT_READ | PROT_WRITE | PROT_EXEC,
        MAP_PRIVATE | MAP_ANONYMOUS,
        -1, 0
    );
    if (exec_mem == MAP_FAILED) {
        perror("mmap failed");
        return 1;
    }

    // 复制二进制代码到可执行内存
    read(fd, exec_mem, code_size);
    close(fd);

    // 转换为函数指针并调用
    AddFunc add = (AddFunc)exec_mem;
    printf("3 + 5 = %d\n", add(3, 5));

    // 释放内存
    munmap(exec_mem, code_size);
    return 0;
}

注意:不同CPU架构的调用约定不同(比如x86-64用rdi/rsi传递前两个参数,x86用栈传参),需确保函数指针的调用约定与编译时一致。

四、替代方案

如果手动处理二进制片段过于繁琐,这些方案更适合JIT场景:

  • LLVM ORC JIT:直接将C代码编译为LLVM IR,再通过JIT编译器生成可执行函数,支持复杂代码生成、优化与链接,适合大型JIT系统;
  • libjit:轻量级JIT库,提供API直接生成机器码,无需手动处理二进制字节,适合简单函数的动态生成;
  • 手写机器码:对于逻辑极简的函数,直接编写对应架构的机器码字节数组,无需编译步骤,但扩展性较差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 23:24:37