Я пытаюсь использовать типы данных 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. И внутри кода то же самое, что и я, и я получил идеальные значения HEX спецификации IEEE754. В этом случае 22,27/7,25 = 3,071724138 и 3,071724138 нормализуют значение IEEE754 в шестнадцатеричном формате 0x40449721. dmesg показывает мне 0x40449721 при загрузке модуля.
Итак, теперь вопросы,
1) Как увидеть разборку моего модуля ядра? поэтому я могу проверить для хранилища данных с плавающей запятой и подразделения, какая инструкция используется. (моя платформа x86_64).
2) Если я могу видеть идеальное шестнадцатеричное значение деления, то какова роль API, такого как kernel_fpu_begin()/kernel_fpu_end(), потому что без его использования я могу выполнять деление с плавающей запятой? разделение выполняется каким оборудованием? как насчет аппаратного FPU?
3) Это разделение выполняется инструкциями SSE2 или чем-то еще (поэтому мне и нужен сборочный файл LKM)
objdump -d .../foo.ko
. Re: все остальное: это работает, но вы испортили состояние регистра XMM или x87 переключателя контекста пользовательского пространства. - person Peter Cordes   schedule 21.06.2018x
иy
volatile
или не сделаете что-то еще, чтобы предотвратить это, gcc выполнит распространение констант и эффективно превратит ваш код вfloat z=3.07172413793103448276f
(т.е. просто поместите ближайший представимый бит с плавающей запятой шаблон в вашу программу без итерацийdivsd
,divss
,fdiv
илиrcpps
+ newton.) Оказывается, ваш пример не является дубликатом; на самом деле вы не используете математику FP, просто печатаете 32-битное целое число, поэтому ищитеmov esi, 0x????
передcall printk
. - person Peter Cordes   schedule 21.06.2018memcpy
или союз. - person Peter Cordes   schedule 21.06.2018-mno-sse
, чтобы запретить ему использовать векторы для копирования структур и так далее. (И gcc не будет использовать x87 сам по себе.) - person Peter Cordes   schedule 04.07.2018