我正在尝试在内核模块中使用float和double数据类型。 为了满足我的好奇心,我编写了简单的LKM。 在这里,
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
static int __init hello_start(void)
{
float x,y,z;
x = 22.27;
y = 7.25;
z = x/y;
unsigned int *u;
u = (unsigned int *)&z;
printk(KERN_INFO "0x%x\n", *u);
return 0;
}
static void __exit hello_end(void)
{
printk(KERN_INFO "Unload...\n");
}
module_init(hello_start);
module_exit(hello_end);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("XYZ");
因为float将按照IEEE754格式将值存储到内存/寄存器中,所以我可以将其分配为32位宽的数据类型,例如unsigned int。在代码内部做同样的事情,得到了IEEE754规范的完美十六进制值。在这种情况下,22.27 / 7.25 = 3.071724138和3.071724138规范化了十六进制的IEEE754值为0x40449721。 dmesg在加载模块时显示0x40449721。
所以现在的问题是
1)怎样才能看到我的内核模块的反汇编?因此我可以验证浮动数据存储区和除法是使用哪个指令。 (我的平台是x86_64)。
2)如果我能够看到完美的十六进制除法值,那么像kernel_fpu_begin()/ kernel_fpu_end()这样的API的作用是什么,因为不使用它就可以执行浮点除法?该划分由哪个硬件执行?硬件FPU呢?
3)这种划分是通过SSE2指令或其他方式执行的(这就是为什么我需要LKM汇编文件的原因)