我想在 linux 内核(32 位处理器)上执行以下代码:
#define UQ64 long long int
#define UI32 long int
UQ64 qTimeStamp;
UQ64 qSeconds;
UI32 uTimeStampRes;
qTimeStamp = num1;
uTimeStampRes = num2;
// 64 division !
qSeconds = qTimeStamp / uTimeStampRes;
有计算64位的算法吗?
谢谢。
GCC C 编译器生成代码调用 libgcc 库中的函数来实现 /
和 %
在 32 位 CPU 上使用 64 位操作数进行操作。但是,Linux 内核未链接到 libgcc 库,因此在为 32 位 Linux 内核构建代码时,此类代码将无法链接。 (构建外部内核模块时,问题可能不明显,直到您尝试将模块动态加载到正在运行的内核中。)
最初,Linux 内核只有 do_div(n,base)
#include <asm/div64.h>
定义的宏.这个宏的用法是不寻常的,因为它修改了它的第一个参数 in place 以成为除法所得的商,并产生(返回)除法的余数作为其结果。这样做是出于代码效率的原因,但使用起来有点麻烦。此外,它仅支持将 64 位无符号被除数除以 32 位除数。
Linux 内核版本 2.6.22 引入了 #include <linux/math64.h>
header,它定义了一组功能,比旧的do_div(n,base)
更全面宏并且更易于使用,因为它们的行为类似于普通的 C 函数。
#include <linux/math64.h>
声明的函数下面列出了 64 位除法。除非另有说明,所有这些都自内核版本 2.6.26 以来可用。
下面 italics
中列出的函数之一 从内核版本 4.18-rc8 开始还不存在。谁知道它是否会实现? (后面内核版本的乘法和移位运算相关的头文件声明的其他一些函数,下面省略了。)
-
u64 div_u64(u64 dividend, u32 divisor)
— 64 位被除数除以 32 位除数的无符号除法。
-
s64 div_s64(s64 dividend, s32 divisor)
— 签署了 64 位被除数除以 32 位除数。
-
u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder)
— 64 位被除数除以 32 位除数和余数的无符号除法。
-
s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder)
— 签署了 64 位被除数除以 32 位除数和余数。
-
u64 div64_u64(u64 dividend, u64 divisor)
— 64 位被除数除以 64 位除数的无符号除法。
-
s64 div64_s64(s64 dividend, s64 divisor)
— (自 2.6.37 起) 将 64 位被除数除以 64 位除数。
-
u64 div64_u64_rem(u64 dividend, u64 divisor, u64 *remainder)
— (自 3.12.0 起) 64 位被除数除以 64 位除数和余数的无符号除法。
-
s64 div64_s64_rem(s64 dividend, s64 divisor, s64 *remainder)
— (截至 4.18-rc8 尚不存在) 签署了 64 位除数除以 64 位除数和余数的除法。
-
div64_long(x,y)
— (自 3.4.0 起) 宏,用 long int
对 64 位被除数进行有符号除法除数(32 位或 64 位,具体取决于架构)。
-
div64_ul(x,y)
— (自 3.10.0 起) 宏对 64 位被除数进行无符号除法 unsigned long int
除数(32 位或 64 位,具体取决于架构)。
-
u32 iter_div_u64_rem(u64 dividend, u32 divisor, u64 *remainder)
— 64 位除法除以 32 位除数的无符号除法,方法是从被除数中重复减去除数,余数(如果被除数预计不会比除数大很多,则可能比常规除法更快)。