Android应用汇编代码运行失败:ndk-build编译报错求助
嘿,我之前在Android NDK里写ARM汇编时也碰到过一模一样的报错,你的问题根源是汇编语法不兼容——NDK默认用的是GNU Assembler(GAS)的语法,而你可能参考的是ARM官方汇编器(ARMASM)的示例,两者在注释符号、寄存器命名上都有区别。
错误原因分析
从报错信息看:
jni/multiple.s:6:2: error: unexpected token at start of statement @ Multiply by 10, input value and return value in r0
这里的@是ARMASM的单行注释符号,但GAS根本不认识它,会把@当成指令的一部分,自然就抛出“意外符号”的错误。另外如果你的目标架构是arm64-v8a,用r0寄存器也会报错——arm64的通用寄存器命名是x0-x30(64位)和w0-w30(32位),没有r0这个说法。
具体解决方案
1. 替换注释符号
把汇编代码里所有的@换成GAS支持的注释符号:
- 单行注释用
# - 多行注释用
/* */
比如你原来的代码行:
@ Multiply by 10, input value and return value in r0
要改成:
# Multiply by 10, input value and return value in r0
2. 根据目标架构调整寄存器和指令
如果目标是arm64-v8a(64位ARM)
把32位ARM的r0换成w0(32位操作)或者x0(64位操作),实现乘以10的汇编示例:
# arm64-v8a版本:输入在w0,结果存在w0 mov w1, w0 # 保存原始输入值到w1 lsl w0, w0, #3 # w0 = w0 * 8 lsl w1, w1, #1 # w1 = w1 * 2 add w0, w0, w1 # w0 = w0 + w1 = 8x + 2x = 10x ret # 返回结果
如果目标是armeabi-v7a(32位ARM)
寄存器用r0没问题,但注释要修改,实现乘以10的汇编示例:
# armeabi-v7a版本:输入在r0,结果存在r0 mov r1, r0 # 保存原始输入值到r1 lsl r0, r0, #3 # r0 = r0 * 8 lsl r1, r1, #1 # r1 = r1 * 2 add r0, r0, r1 # r0 = r0 + r1 = 10x bx lr # 返回结果
3. 重新编译
修改完代码后,回到项目根目录重新执行:
ndk-build
我当时就是因为直接照搬了ARMASM格式的代码,没注意GAS的语法差异才踩了这个坑,改完注释和寄存器之后就顺利编译通过了。如果还有其他报错,可以检查下指令的写法——GAS的指令是指令在前,操作数在后,和ARMASM格式一致,但大小写不敏感,核心还是要匹配GAS的语法规则。
内容的提问来源于stack exchange,提问作者Boooooooooms

