2012-01-26 75 views
0

我有連接器錯誤(未定義的引用),我自己無法解決。我使用GCC Sourcery G ++ Lite 4.5.2 for ARM。c文件中彙編元素的未定義引用

我有很多未定義的引用,他們幾乎都引用程序集文件。下面一個例子:

在一個名爲cpu.sx彙編文件我已經 「_CPU_MmuConfigGet」 定義:

.global _CPU_MmuConfigGet 
CPU_MmuConfigGet: 
mrc p15,0,r0,c1,c0,0   
mov pc,lr 

交流文件名爲mmu.c,CPU_MmuConfigGet被稱爲:

#include "cpu.h" 
U32 MMU_ConfigGet(void) { 
    return CPU_MmuConfigGet(); 
} 

最後,在頭文件cpu.h中聲明CPU_MmuConfigGet:

extern U32 CPU_MmuConfigGet(void); 

這些樹文件s的位於下列文件夾:

Base/Common/src/mmu.c  
Base/Common/inc/cpu.h  
Base/Common/src/cpu.sx  

從不同的文章中,我紅上了網,我發現,我要補充一個下劃線CPU_MmuConfigGet(試過了,但並沒有解決我的問題)。我也在一些論壇上發現,鏈接時,目標文件順序很重要,但在其他論壇中,目標順序並不重要(我在這裏很困惑......)。我嘗試了-S參數來查看mmu.c的程序集版本,但是這並沒有幫助我找到關於我的錯誤的線索......

下面是使用的編譯器命令(我添加了-H這幫助尋找什麼是錯的...):

arm-none-eabi-gcc -c -g3 -gdwarf-2 -H -o"mmu.o" -Wall -Wa,-adhlns="mmu.o.lst" 
-fmessage-length=0 -MMD -MP -MF"mmu.d" -MT"mmu.d" -fpic -march=armv4t -mcpu=arm7tdmi -mlittle-endian 
-I"../../OS/ngos/hw/cdb89712" -I"../../OS/ngos" -I"../../OS/ngos/include" -I"../../OS/ngos/rtos/ucosii" 
-I"C:/Program Files/CodeSourcery/Sourcery G++ Lite/lib/gcc/arm-none-eabi/4.5.2/include" -I"./" 
-I"src/" -I"../../Common/inc" -I"../../OS/uCOS-II/SOURCE" -I"../../OS/ngos/drivers/arm" 
-I"../../OS/ngos/include/ngos" -I"../../OS/ngip/include" -I"../../OS/ngip/include/ngip" 
-I"../../Dvcscomponent/Inc" -I"../../Inc" "../../Common/src/mmu.c" 
. ../../Common/inc/base.h 
. ../../Common/inc/hw7312.h 
. ../../Common/inc/serial.h 
.. ../../Common/inc/base.h 
.. ../../Common/inc/hw7312.h 
. ../../Common/inc/base.h 
. ../../Common/inc/cpu.h 
.. ../../Common/inc/base.h 
.. ../../Common/inc/hw7312.h 
. ../../Common/inc/mmu.h 

現在裝配命令:

arm-none-eabi-gcc -g3 -gdwarf-2 -x assembler-with-cpp -Wa,-adhlns="cpu.o.lst" -Wall -c 
-fmessage-length=0 -MMD -MP -MF"cpu.d" -MT"cpu.d" -fpic -o"cpu.o" -march=armv4t -mcpu=arm7tdmi -mlittle-endian 
-I"../../OS/ngos/hw/cdb89712" -I"../../Common" -I"../../OS/ngos/drivers/arm" 
"../../Common/src/cpu.sx" 

最後有錯誤的鏈接命令:

arm-none-eabi-gcc -fpic -mcpu=arm7tdmi -T".\linker.ld" -Wl,-Map,BootLoad.map -g3 -gdwarf-2 -o "BootLoad.elf" 
InitMain.o tsk_main.o ecp.o memalloc.o tsk_ecp.o firmdesc.o crc.o flash.o eth.o firmflash.o 
firmdest.o bcfg.o bootdownload.o cinit.o serial.o cpu.o mmu.o ngucos.o cdbini.o cs712sio.o 
cs712eth.o ../../OS/ngos/lib/rtstub/arm/gcc/libngosd4m32l.a ../../OS/ngip/lib/rtstub/arm/gcc/libngipd4m32l.a 
mmu.o: In function `MMU_ConfigGet': 
C:\Working\SF2100-0074-BootLoaderMezz\Base\NexGen\BootLoader/../../Common/src/mmu.c:28: undefined reference to `CPU_MmuConfigGet' 

我有人有任何建議,我會很高興聽到他們!

在此先感謝!

+0

在彙編源代碼中定義符號,但不帶前導下劃線。這是一個愚蠢的蘋果公約使用領先的下劃線;在任何其他的GNU環境中,它都沒有被使用。 – 2012-01-26 21:47:36

+0

感謝您的評論,我注意到有或沒有前導下劃線,我仍然有我的鏈接錯誤。我只提到了領先的下劃線,以避免一些答案,如「嘗試添加領先的下劃線」,然後必須解釋說我已經嘗試過... –

+0

沒有建議?仍然停留在這裏。嘗試了一些其他的東西,如改變我的外部調用:extern U32 CPU_MmuConfigGet(void)asm(「CPU_MmuConfigGet」);手動編譯文件(不使用makefile),更改文件位置等等。什麼都沒發現! –

回答

1

最後,在查閱了cpu.sx的列表後,我驚訝地發現文件的一部分「缺失」。我意識到該文件包含另一個程序集文件。這包括彙編文件被結尾...由

.end 

指令。

我刪除了這條指令並編譯了項目。

0

問題似乎是,您的源在某些地方有一個前導下劃線,但在其他地方沒有。你不需要需要他們與工具鏈,雖然你可以,如果你喜歡,但它必須是一致的。

甚至更​​好,也許你應該完全拋棄小的彙編文件,並使用匯編插入到C文件中?

E.g.

int CPU_MmuConfigGet() 
{ 
    int config; 
    asm ("mrc p15,0,%0,c1,c0,0" : "=r" (config)); 
    return config; 
} 

這個小功能隱藏所有的鏈接廢話,清理你的項目樹,和你的makefile和編譯器甚至是免費的,如果它可以將它內聯到其他功能。

編譯器手冊現在詳細介紹瞭如何指定輸入和輸出來插入插入。起初他們有點混亂,但從長遠來看,這是值得的。

當然,有些地方還需要彙編程序文件 - 例如crt0.s。

+0

在這種特殊情況下,使用內聯彙編很複雜,但對於遇到類似問題的其他人來說,這似乎是一個很好的建議。 –