为什么我的内核模块可以完美地执行浮点除法?

时间:2018-06-21 05:26:47

标签: linux-kernel floating-point linux-device-driver x86-64 sse2

我正在尝试在内核模块中使用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汇编文件的原因)

0 个答案:

没有答案