当前位置:  开发笔记 > 开发工具 > 正文

未定义的引用'__divdi3'

如何解决《未定义的引用'__divdi3'》经验,为你挑选了1个好方法。

在链接一些对类型long longI 的整数执行除法和模运算的代码时,会收到以下两个错误:

util.c:(.text+0x1af): undefined reference to '__divdi3'
util.c:(.text+0x1ef): undefined reference to '__moddi3'

我也试过使用unsigned long long,但是会导致以下错误:

util.c:(.text+0x1af): undefined reference to '__udivdi3'
util.c:(.text+0x1ef): undefined reference to '__umoddi3'

更换long longintlong解决问题,但我需要使用unsigned long long.

我使用以下命令行来编译和链接程序:

gcc -ffreestanding -c kernel/util.c -o kernel/util.o
ld -o kernel32.bin -Ttext 0x500 kernel/util.o kernel/kernel.o --oformat binary

这是功能:

char* itoa(unsigned long long i, char b[]){
    if (i == 0){
        b[0] = '0';
        b[1] = '\0';
        return b;
    }
    char const digit[] = "0123456789";
    char* p = b;
    if (i < 0){
        *p++ = '-';
        i *= -1;
    }
    unsigned long long shifter = i;
    while (shifter){
        ++p;
        shifter = shifter / 10;
    }
    *p = '\0';
    while (i){
        *--p = digit[i % 10];
        i = i / 10;
    }
    return b;
}

显然,编译器引用__udivdi3除以整数但链接器找不到它.

顺便说一下,二进制文件将用作32位操作系统,因此缺少许多标准库

编辑:我使用的是gcc 4.8.4和ld 2.24



1> John Bolling..:

当为不为GCC用作[ unsigned] 的数据类型提供硬件支持的体系结构构建代码时long long,GCC为该类型的值生成算术运算的代码,该代码涉及调用由其自己的支持库提供的函数libgcc.在__divdi3()等那些之中.这不是GCC可以做到的唯一方式,但它非常适合GCC支持许多架构的目标.

当被指示充当独立编译器时,GCC不会自动链接libgcc,结果是不会自动提供这些函数的实现.这一直是以前投诉的主题,例如这个和后来的投诉.GCC维护者采取的立场是,这不是GCC的缺陷,并且它不会使GCC不符合要求.我觉得他们的推理有问题,但不太可能改变.至少,这是一个实施质量问题.

我确实看到了GCC维护者的来源,但是:独立环境几乎不提供标准库,并且除了根据提供给它的代码之外,不得解释大多数函数调用.那么,如果该代码包含对与libgcc中某些函数具有相同名称的函数的显式调用,那该怎么办?除非用户明确表示他想要libgcc,否则编译器不应该假设它是所需函数的那些版本.但问题是,如果编译器插入这样的调用,那么它不仅知道哪些实现是预期的,而且如果链接了不兼容的实现,则结果是错误的.因此,这是海湾合作委员会自己制定的问题.

底线是您可以明确请求链接libgcc.您将需要指定它是静态链接的,因为您不能依赖上下文中的动态链接器.这些额外的链接选项应该这样做:

-static-libgcc -lgcc

或者,您可以编写自己的这些函数的实现,或者从GCC中获取源代码,但我不明白为什么您更喜欢这些选项.

推荐阅读
雯颜哥_135
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有