繁体   English   中英

C文件中装配元素的未定义引用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM