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
相关产品推荐
相关产品推荐

