一、裸機沒有除法和取模運算
針對ARM裸機環境,當除數是變量時,報錯:
undefined reference to `__aeabi_uidivmod'
undefined reference to `__aeabi_uidiv'
ARM芯片沒有實現除法的硬件結構,因此是採用軟件去實現除法。編譯器支持軟浮點,軟浮點的實現是在libgcc.a中。
所以,程序鏈接時要加上libgcc.a這個靜態庫;
下面是友善工具鏈中libgcc.a的路徑
LIBPATH = -L /home/username/ubuntu/bin/4.9.3/lib/gcc/arm-cortexa9-linux-gnueabihf/4.9.3 -lgcc
加上後又報了新的錯誤:
4.9.3/lib/gcc/arm-cortexa9-linux-gnueabihf/4.9.3/libgcc.a(_dvmd_lnx.o): In function `__aeabi_ldiv0':
/work/toolchain/build/src/gcc-4.9.3/libgcc/config/arm/lib1funcs.S:1331: undefined reference to `raise'
解決undefined reference to `__aeabi_uidivmod’ 提供了一種解決方法;
還一種麻煩點的;
先將libgcc.a
中的_dvmd_lnx.o
提取出來;
ar x libgcc.a _dvmd_lnx.o
查看_dvmd_lnx.o
的反彙編代碼;
arm-linux-objdump -S _dvmd_lnx.o
將BL raise
改成 NOP
,機器碼是e1a00000
;
然後將.o文件添加進libgcc.a
ar r libgcc.a _dvmd_lnx.o
然後編譯鏈接,還是報上面的錯誤,我想應該是節表裏應該是有raise相關的信息,使用readelf命令打印;
我們要做的是將.rel.text
段的信息刪掉,便試着將它的Size改成0;
將文件用十六進制編輯器打開,搜索98030000(小端)
,這4個字節緊接着的就是08000000
,表示Size,改成00
,再打印節表信息;
沒有顯示.rel.text
段,再添加進libgcc.a
,編譯鏈接,成功;