[英]undefined reference of assembly element in c file
我有自己无法解决的链接器错误(未定义参考)。 我将GCC Sourcery G ++ Lite 4.5.2用于ARM。
我有很多未定义的引用,它们几乎都引用了程序集文件。 这里是一个例子:
我在名为cpu.sx的程序集文件中定义了“ _CPU_MmuConfigGet”:
.global _CPU_MmuConfigGet
CPU_MmuConfigGet:
mrc p15,0,r0,c1,c0,0
mov pc,lr
在名为mmu.c的ac文件中,CPU_MmuConfigGet称为:
#include "cpu.h"
U32 MMU_ConfigGet(void) {
return CPU_MmuConfigGet();
}
最后,在头文件cpu.h中,声明CPU_MmuConfigGet:
extern U32 CPU_MmuConfigGet(void);
论文树文件位于以下文件夹中:
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'
我有人有任何建议,我很高兴听到他们的建议!
提前致谢!
最后,在查询了cpu.sx的列表之后,我惊讶于文件的一部分“丢失”。 我意识到该文件包含另一个程序集文件。 该包含的程序集文件以...结尾
.end
指示。
我删除了该指令,并编译了项目。
问题似乎是您的来源在某些地方带有下划线,而在其他地方则没有。 您不需要使用该工具链,尽管可以(如果愿意),但是必须保持一致。
更好的是,也许您应该完全放弃小汇编程序文件,并在C文件中使用汇编程序插入?
例如
int CPU_MmuConfigGet ()
{
int config;
asm ("mrc p15,0,%0,c1,c0,0" : "=r" (config));
return config;
}
这个小功能隐藏了所有不必要的链接器,清理了项目树和makefile,并且编译器甚至可以随意将其内联到其他函数中。
编译器手册现在提供了完整的详细信息,以指定对assmber插入的输入和输出。 我发现它们一开始有点令人困惑,但从长远来看还是值得的。
当然,在某些地方仍然需要汇编程序文件,例如crt0.s。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.