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

AArch64 Linux下使用AsmJit生成简单代码触发非法指令错误

在aarch64 Linux上使用AsmJit生成ARM64汇编触发非法指令错误的排查与解决

我在aarch64 Linux系统上尝试使用GCC和AsmJit库动态生成并执行ARM64汇编代码,但即使是非常基础的程序也持续触发“非法指令”错误。以下是引发问题的示例代码:

#include <stdio.h>
#include "asmjit.h"
#include "a64.h"
using namespace asmjit;

typedef int (*SumFunc)(int, int);

int main() {
  // Signature of the generated function.

  for (int nop_num = 0; nop_num < 10; nop_num += 1) {
    JitRuntime rt;    // Create a runtime specialized for JIT.
    CodeHolder code;  // Create a CodeHolder.

    code.init(
        rt.environment());    // Initialize code to match the JIT environment.
    a64::Assembler a(&code);  // Create and attach a64::Assembler to code.

    // a64::Gp s1 = a64::w0;
    // a64::Gp s2 = a64::w1;
    // a64::Gp result = a64::w11;
    a.add(a64::w0, a64::w0, a64::w1);
    a.ret(a64::w0);

    SumFunc fn;
    Error err = rt.add(&fn, &code);  // Add the generated code to the runtime.
    if (err) return 1;  // Handle a possible error returned by AsmJit.
    int final_result = fn(10, 20);  // Execute our constructed function fn
    printf("%d", final_result);
    rt.release(fn);  // Explicitly remove the function from the runtime
    code.reset();
  }
  return 0;
}

为何这段简单的ARM64汇编代码会在我的aarch64 Linux系统上触发“非法指令”错误?是否需要配置或修改AsmJit的某些设置以适配aarch64架构?

已尝试步骤:

  • 确认系统为aarch64架构且GCC编译设置正确;
  • 尝试AsmJit示例中的其他代码片段,仍出现相同问题;
  • 查询AsmJit文档相关配置选项或兼容性问题,但未找到明确线索。

希望能找到在aarch64 Linux上正确使用AsmJit的方法,或了解该问题的潜在原因。


问题原因与解决方案

1. ARM64返回指令的用法错误

ARM64架构中,ret指令不需要指定寄存器参数——返回值已经通过w0(32位整数)或x0(64位整数)寄存器传递,直接调用无参数的a.ret()即可。你当前使用的a.ret(a64::w0)会被汇编成非法机器码,这是触发错误的核心原因。

修正后的汇编指令:

a.ret();  // 移除ret指令的寄存器参数

2. CodeHolder初始化需明确架构信息

初始化CodeHolder时,需要显式指定ARM64架构类型,避免环境检测的潜在偏差:

CodeInfo codeInfo;
codeInfo.init(rt.environment(), a64::Arch::kAArch64);
code.init(codeInfo);

3. 显式配置JIT内存权限

部分aarch64 Linux环境下,需要确保JIT运行时分配的内存页具备可执行权限,可通过设置运行时标志实现:

JitRuntime rt;
rt.setAllocatorFlags(JitRuntime::kAllocatorFlagExecutable);

完整修正后的代码

#include <stdio.h>
#include "asmjit.h"
#include "a64.h"
using namespace asmjit;

typedef int (*SumFunc)(int, int);

int main() {
  for (int nop_num = 0; nop_num < 10; nop_num += 1) {
    JitRuntime rt;
    rt.setAllocatorFlags(JitRuntime::kAllocatorFlagExecutable);
    
    CodeHolder code;
    CodeInfo codeInfo;
    codeInfo.init(rt.environment(), a64::Arch::kAArch64);
    code.init(codeInfo);
    
    a64::Assembler a(&code);
    a.add(a64::w0, a64::w0, a64::w1);
    a.ret();  // 修正为符合ARM64规范的返回指令

    SumFunc fn;
    Error err = rt.add(&fn, &code);
    if (err) {
      fprintf(stderr, "AsmJit error: %s\n", DebugUtils::errorAsString(err));
      return 1;
    }
    
    int final_result = fn(10, 20);
    printf("%d\n", final_result);
    
    rt.release(fn);
    code.reset();
  }
  return 0;
}

编译命令参考

确保编译时链接AsmJit库并指定aarch64架构选项:

g++ -o jit_test jit_test.cpp -lasmjit -march=armv8-a

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:52:47