在Ubuntu虚拟机上编译ARMv8代码失败,寻求技术帮助
问题描述
我有一套包含C代码、Makefile和ARMv8汇编代码的项目,想在谷歌云的Ubuntu 20.04虚拟机上编译。这台虚拟机原本用来运行C课程代码,装的是GNU g编译器,但编译ARMv8相关代码时失败了。这些代码在64位树莓派4上能正常运行,我希望能在虚拟机上完成编译,方便用笔记本开发。
执行Makefile后报错如下:
gcc -g -O0 -c main.c -o main.o gcc -g -O0 -c test.S -o test.o test.S: Assembler messages: test.S:6: Error: no such instruction: `adrp X0,msg1' test.S:7: Error: too many memory references for `add' test.S:8: Error: no such instruction: `adr X1,msg2' test.S:9: Error: no such instruction: `adrp X6,num1' test.S:10: Error: too many memory references for `add' test.S:11: Error: no such instruction: `ldurb w2,[X6,0]' test.S:12: Error: no such instruction: `ldursh X3,[X6,1]' test.S:13: Error: no such instruction: `ldursw X4,[X6,3]' test.S:14: Error: no such instruction: `ldur X5,[X6,7]' test.S:15: Error: no such instruction: `br X30' test.S:21: Warning: value 0xcafebabe truncated to 0xbabe make: *** [Makefile:24: test.o] Error 1
相关代码
C代码(main.c)
extern long long int test(); int main(void) { test(); return 0; }
ARMv8汇编代码(test.S)
.section .text globl test test: ADRP X0, msg1 ADD X0,X0, :lo12:msg1 ADR X1, msg2 ADRP X6, num1 ADD X6,X6, :lo12:num1 LDURB w2, [X6,0] LDURSH X3,[X6,1] LDURSW X4,[X6,3] LDUR X5,[X6,7] BR X30 .section .data msg1: .asciz "A 17 byte message" msg2: .asciz "Another message of 27 bytes" num1: .byte 45 num2: .hword 0xf654 num3: .word 0xcafebabe num4: .quad 0xfeedface
Makefile
TARGET=Lab02 CC=gcc LD=gcc FLAGS=-g -O0 all: $(TARGET) clean: rm *.o rm $(TARGET) main.o: main.c # Compile for best debug view (lowest optimization) $(CC) $(FLAGS) -c $^ -o $@ test.o: test.S # Compile for best debug view (lowest optimization) $(CC) $(FLAGS) -c $^ -o $@ $(TARGET): main.o test.o $(LD) main.o test.o -o $@
解决方案
问题核心是当前使用的gcc是x86架构的编译器,无法识别ARMv8(64位)的汇编指令,需要安装ARMv64交叉编译工具链来编译目标代码。
步骤1:安装ARMv64交叉编译工具
在Ubuntu 20.04终端执行以下命令:
sudo apt update sudo apt install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu
步骤2:修改Makefile
将编译器替换为ARMv64交叉编译工具:
TARGET=Lab02 CC=aarch64-linux-gnu-gcc LD=aarch64-linux-gnu-gcc FLAGS=-g -O0 all: $(TARGET) clean: rm *.o rm $(TARGET) main.o: main.c # Compile for best debug view (lowest optimization) $(CC) $(FLAGS) -c $^ -o $@ test.o: test.S # Compile for best debug view (lowest optimization) $(CC) $(FLAGS) -c $^ -o $@ $(TARGET): main.o test.o $(LD) main.o test.o -o $@
步骤3:编译与验证
- 执行
make命令编译项目,编译成功后会生成ARMv64架构的可执行文件。 - 用以下命令确认文件架构:
file Lab02
输出应类似:Lab02: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, BuildID[sha1]=..., for GNU/Linux 3.7.0, with debug_info, not stripped
- 若要在x86虚拟机上运行该ARM程序,需安装QEMU模拟器:
sudo apt install qemu-user
运行程序:
qemu-aarch64 ./Lab02
额外说明
- 汇编代码中的
LDUR*等是ARMv8专属指令,交叉编译器配套的汇编器能正确识别,而x86架构的汇编器无法解析。 - 关于
num3: .word 0xcafebabe的警告:.word是32位类型,0xcafebabe本身就是32位值,该警告不影响编译与程序运行,若需消除可确保值符合有符号32位范围,或改用对应类型声明。
内容的提问来源于stack exchange,提问作者Jedi1308
相关产品推荐
相关产品推荐

