C linux内核上的64位除法
我正在寻找一个64位除法算法,但不依赖于GPL许可证 我在Hacker Delight book中发现了以下代码(图9-5):C linux内核上的64位除法,c,linux-kernel,C,Linux Kernel,我正在寻找一个64位除法算法,但不依赖于GPL许可证 我在Hacker Delight book中发现了以下代码(图9-5): unsigned long udivdi3(unsigned long u, 无符号长(v) 如果(v>>32==0){ 如果(u>>32
unsigned long udivdi3(unsigned long u,
无符号长(v)
如果(v>>32==0){
如果(u>>32
问题是‘return DIVU’计算的除法是64/32,所以它不是我想要的。
怎么办?这就是编译器rt存在的原因。关于
\uuUDIVDI3
最终调用的内容,但请注意,也使用特定于平台的程序集版本,例如在x86上
但实际上,避免使用libgcc是没有意义的——它更加成熟,支持更多的平台,除了运行时库例外,GPL基本上是被定义的——你绝对不应该为此修改上游源代码,因此没有修改过的源代码可用。在Linux内核代码中进行64位除法似乎很棘手。我不确定你是否遇到了和我一样的问题,但我知道的是 看起来指令集不能完全处理64位算术运算。它看起来像是gcc发出了对helper函数的调用。例如,在手臂上,如果我写
t /= 86400;
当t
是一个64位变量时,我的内核构建会失败,并出现“未定义对“\uu aeabi\u ldivmod”
”的引用。很明显,内核没有链接到完整的C库,而C库中存在类似\uu aeabi\u ldivmod
的函数
解决方案似乎是调用do_div
do_div
实际上不是一个函数;它是在特定于体系结构的头文件中声明的宏。(对于ARM,它位于arch/ARM/include/asm/div64.h
中。x86也有类似的文件。)
解决方案是将t/=86400
替换为
(void)do_div(t, 86400);
do_div
将其第一个参数除以第二个参数,然后返回余数(在本例中我将忽略该余数)
div64.h
中有一条很大的注释,告诉您有关do_div
以及如何使用它的更多信息。您可以使用伪函数do_div()
?这就是我在内核中使用的64位除法。为什么要在Linux内核代码中避免GPL依赖?GPL依赖需要使我的项目开源@你能发布你的代码吗@SteveSummit@EliAvraham我把它贴出来作为答复。
(void)do_div(t, 86400);