我正在尝试为 arm7tdmi
编译一个小程序(即 armv4t
),使用命令 arm-linux-gnueabi-gcc -march=armv4t -mcpu=arm7tdmi -nostartfiles -static test.c -o test
在 Debian 上(gcc 版本 10.2.1、Debian 10.2.1-6)。然而,GCC 似乎忽略了 cpu 和 arch 标志,并生成 armv4t
上不支持的指令。 ,例如clz
,如objdump
所示:
104f4: 0a000071 beq 106c0 <.divsi3_skip_div0_test+0x1f0>
104f8: e16f2f13 clz r2, r3
104fc: e16f0f11 clz r0, r1
10500: e0402002 sub r2, r0, r2
10504: e272201f rsbs r2, r2, #31
我还使用 readelf
检查了二进制文件,它显示该架构实际上是 armv5te
:
File Attributes
Tag_CPU_name: "5TE"
Tag_CPU_arch: v5TE
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-1
请问这是怎么回事?为什么 GCC 忽略 -mcpu
和-march
标志?
这是test.c
的内容:
#include <stdint.h>
#include <stddef.h>
void _start() {
const size_t len = 8;
uint8_t arr[8] = {10, 12, 8, 5, 0, 2, 3, 55};
uint8_t *data = arr;
uint16_t a = 1, b = 0, m = 7;
for(int i=0; i<len; i++) {
a = (a + data[i]) % m;
b = (a + b) % m;
}
uint32_t res = (uint32_t)b << 16 | (uint32_t)a;
}
最佳答案
您还需要添加“-nostdlib”,否则它将拖入已使用 Armv5 编译的文件。 “arm-linux”内核不支持 ARMv4 CPU,因为它们没有 MMU。您正在查看来自 gcc 库的汇编程序,该库是为 Armv5 编译的。
示例标签 divsi3 显示您正在使用除法运算,这是在 libgcc 中编码的,它将与代码链接。它是由您的 % m
代码引入的。
您可以编码并提供自己的 divsi3,或者获取支持 Armv4 的编译器库。必须生成(降级)libgcc.a 才能支持该 CPU。 Gcc 的后端能够为 ARM32/Thumb 系列的所有成员生成代码,但不支持库(没有多库支持)。
编译器没有错误。如果您查看 _start 的汇编程序,它将不包含clz
。如果%7
可以是%8
,您可以降级到&7
并且不需要divsi3。
你可以明白为什么 here .
它是 this question 的变体。问题是链接器“gnu ld”没有标志可以拒绝 Armv5 代码。
- 提供配置了 Armv4 的
divsi3
。 - 提供您自己的
divsi3
与 Division algorithm . - 避免使用该功能(降级至
&
)。
关于c - GCC 忽略 `-mcpu=arm7tdmi` 标志并生成不支持的指令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72693275/