GCC为什么无法对数字进行除法运算?

7

我遇到了一个非常奇怪的情况。每次尝试编译我的arm项目(LPC2378,codesourcery arm-none-eabi-gcc-4.5.1),在链接时总是出现相同的错误。

/media/data/Projects/arm/uart/main.c:39: undefined reference to `__aeabi_uidiv'
/media/data/Projects/arm/uart/main.c:40: undefined reference to `__aeabi_uidiv'

违规代码如下所示:
U0DLL = ((((PLLCFG & 0x7FFF) + 1) * F_OSC) / ((((PLLCFG & (0xFF << 16)) >> 16) + 1) * ((CCLKCFG & 0xFF) + 1) * 8 * BAUD * 1)) % 256;
U0DLM = ((((PLLCFG & 0x7FFF) + 1) * F_OSC) / ((((PLLCFG & (0xFF << 16)) >> 16) + 1) * ((CCLKCFG & 0xFF) + 1) * 8 * BAUD * 1)) / 256;

我搜索了一下,发现这个问题可能是由于没有使用LD的lgcc和lc选项造成的。我已经解决了这个问题,但错误仍然存在。

完整的项目可以在我的github库中找到

如果有人能帮忙解决这个问题,将不胜感激。谢谢。


6
链接器标志的顺序有时很重要,可以尝试:$(LD) -o main.out startup.o target.o fio.o irq.o main.o $(LDFLAGS) - Piotr Praszmo
Banthar,你真是个明星。我已经为此苦恼了很长时间,而从谷歌搜索到的最佳结果只有一些错误报告,其中最好的是6年前RMS发布的。 - regomodo
Banthar:那么将链接器标志放在最后是最好的选择吗? - regomodo
2
@Regomo:由于缺失符号的解析方式,您必须在自己的对象文件之后放置库文件。所有其他标志可以以任何顺序出现。 - Kerrek SB
5个回答

12

ARM系列的CPU没有原生的整数除法指令。因此,除法需要通过库函数来实现。GCC知道这一点,并创建一个对__aeabi_uidiv(对于无符号整数除法)的引用。

您需要链接到包含此函数的适当运行时支持库。


1
从链接目录中进行grep操作,找到了适当的库进行链接。结果发现正是链接顺序导致了错误,正如banthar所指出的那样。 - regomodo

2

我曾遇到此问题,并通过在Makefile中传递libgcc.a的正确位置来解决它。您可能需要添加以下内容:

"-L*path_to_libgcc.a* -lgcc" 

转到LDFLAGS


1
听起来像是工具链问题 - 也许你的gcc是为ARM EABI构建的,但你的库(如libgcc?)却是为传统ABI构建的?

0

我通常避免使用除法,但有时候不得不用,就会遇到这个问题。那些除法函数的(汇编)源代码在gcc源代码中,提取代码并在gcc不合作时链接进去并不太难。一旦你有了一个去掉宏等内容的版本,一个干净的源代码,你可以把它放在口袋里随时携带。我曾经通过谷歌搜索发现建议使用非Linux EABI,但正如你所发现的,这并不总是有效,有时候有效,有时候无效。


0

检查一下你的libgcc.a是否在应该存在的codesourcery目录中。我曾经遇到过与TI starterware相同的问题,通过修改其中一个makefile中的libgcc.a路径解决了这个问题。


您提供的产品网站链接并未包含有关此问题错误的任何信息。包含此类无关链接,尤其是自我推广的链接,是不合适的。我已经为您删除了该链接,以免您的答案被标记为垃圾邮件。 - Andrew Barber
我认为网页上的信息很清晰。我写下这篇文章是因为我遇到了完全相同的问题,但使用了不同的资源:1)如果没有链接到libgcc.a,则会出现__aeabi_uidiv错误;2)libgcc.a是CodeSourcery的一部分;3)它存储在版本化的目录中;4)如果您的makefile钩子连接到了错误的版本,则它根本无法工作。我不打算在这里重复我已经在其他地方写过的内容,因此提供链接。如果您认为这不合适,请忽略它。(实际上,我想删除这篇文章,但它并没有被删除,只是被标记了)。 - David Belohrad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接