解决嵌入式arm编译除法,报error:__umodsi3和__udivsi3的问题

前言

SOC原型验证,编译程序的时候遇到不支持除法的问题。网上没有一个方便的解决方法,我利用sed替换实现了一个好一点的方法。
文章以遇到问题的顺序来记录。

问题1:不支持除法

这个问题的乐音还是比较简单的,网上讲的很清楚,arm是精简指令集,本身不支持除法需要调用第三方的库软件实现。这里调用lgcc的库,需要再连接的时候加上,如下图所示。

这里-l 后面加库名gcc
库可以到gcc的官网上,找架构相同的版本下载,也可以再自己编译环境下搜索一下,有时就藏在其他>目录下面,拷贝过去就行了。

在这里插入图片描述

问题2:bl跳转问题

上面加上库之后,还是有问题。提示

relocation truncated to fit:

这个可以通过编译的汇编文件查看,可以看到汇编文件里面调用__umodsi3和__udivsi3使用的是bl指令。bl指令跳转的范围很小。这里需要使用ldr指令代替跳转。

替换前:bl __umodsi3
替换后:ldr pc, =__umodsi3

这个可以使用sed命令进行批量替换。

sed -i 's/bl\s__umodsi3/ldr\tpc, =__umodsi3/' 汇编文件名
sed -i 's/bl\s__udivsi3/ldr\tpc, =__udivsi3/' 汇编文件名

问题3:no memory region specified for

上面改完单文件已经可以编译了。这个问题和我的链接脚本有关。和编译除法应该没有关系。
编译多文件的时候,使用include把其他的c文件都include进来。然后进行编译。报错

no memory region specified for

这个设计到链接脚本,原因是没有给编译的.o文件里面的text字段设置空间。
贴上来我的链接脚本:
在这里插入图片描述
类似的问题应该有一个共同的解决方法:你把提示缺少的字段加到链接脚本里面分配空间即可。
可以用*匹配多个文件。

参考文献

  1. 未定义对__modsi3 #267的引用
  2. bl跳转指令使用错误导致编译出现错误–relocation truncated to fit: R_ARM_PC24 init_irq
  3. ARM 常见问题总结
  4. 使用sed命令查找和替换文件中字符串方法的总结
  5. Shell 使用sed替换文本
  6. GCC -T link option issue
  7. linking error when using sprintf()
  8. Linker Script - RAM and ROM same Memory Space

猜你喜欢

转载自blog.csdn.net/weixin_44681954/article/details/122156557