已安装QEMU与ARM交叉工具链,如何在Linux子系统通用编译运行ARM汇编.s文件?
WSL 下 ARM 汇编编译运行操作指引
前置配置(仅需执行1次)
完成工具链路径适配,避免每次输入全路径:
- 打开bash配置文件:
nano ~/.bashrc - 在文件末尾追加环境变量配置:
export PATH=/opt/arm/10/gcc-arm-10.2-2020.11-x86_64-arm-none-linux-gnueabihf/bin:$PATH - 执行配置生效:
source ~/.bashrc - 验证配置有效性:执行
arm-none-linux-gnueabihf-gcc --version,正常输出版本号即为配置成功
通用编译命令
根据汇编文件的入口类型,选择对应编译参数,覆盖你提供的所有示例场景,命令逻辑和原生x86下的gcc编译体验完全一致
场景1:无libc依赖的裸汇编(入口标注.global _start,通过SWI软中断退出)
这类汇编不调用任何标准库函数,编译时禁止链接系统库,命令格式:
arm-none-linux-gnueabihf-gcc -o 输出可执行文件名 待编译的.s汇编文件 -nostdlib
示例操作:编译文件名为string_len.s的汇编程序,生成同名可执行文件:arm-none-linux-gnueabihf-gcc -o string_len string_len.s -nostdlib
该命令可直接适配你提供的勾股数判断、内存变量交换、二分查找、字符串长度统计这4个纯_start入口的程序,无需修改代码逻辑。
场景2:依赖libc的汇编(入口标注.global main,调用printf等标准库函数)
这类汇编依赖标准库提供的函数实现,编译时自动链接系统库,命令格式:
arm-none-linux-gnueabihf-gcc -o 输出可执行文件名 待编译的.s汇编文件
示例操作:编译文件名为hello.s的带printf的程序,生成同名可执行文件:arm-none-linux-gnueabihf-gcc -o hello hello.s
程序运行方法
因为WSL运行在x86架构上,无法直接执行ARM架构的二进制文件,使用已安装的qemu-user即可直接运行,统一运行命令格式:
qemu-arm ./编译生成的ARM可执行文件
- 查看程序返回值:程序运行结束后,执行
echo $?,即可得到ARM程序中存入R0寄存器的退出返回值,和原生Linux程序的返回值规则完全一致
常见报错排查
- 编译报
undefined reference to 'printf':代表当前汇编依赖标准库,但编译时误加了-nostdlib参数,移除该参数重新编译即可 - 运行报
Exec format error:代表未加qemu-arm前缀直接执行ARM二进制,补全qemu运行命令即可 - 代码中出现未定义符号(比如第一个示例里的X、Y、Z):属于汇编代码本身的规范问题,需要用
.equ 符号名, 常量值伪指令手动定义常量,和编译运行流程无关
内容的提问来源于stack exchange,提问作者Abdullah Meda
相关产品推荐
相关产品推荐

