转载易语言论坛文章,文章说易语言的加减乘除运算全部是浮点运算,经过笔者反汇编查看,确实是浮点运算,但是说浮点运算蓝屏,作者写的驱动没发现此问题,一直很稳定,只是备份下,说不定只是那篇文章作者自己代码不严谨造成的蓝屏,跟浮点无关
众所周知易语言的加减乘除运算,90%都是使用浮点运算,经过测试发现在驱动函数中,一旦使用浮点运算,90%的几率直接蓝屏.
特别是暴露的接口,,比如,你Hook
ZwOpenProcess ,那么,你那个替换的函数,就是一个接口,
经过测试,发现接口如果使用了浮点运算
100%蓝屏(蓝屏的钙,好喝~).(即使加载时没蓝屏,不出3分钟也会蓝.)
分析:
查阅资料,原来是这样,浮点运算,只要cpu运行浮点运算,就会检查fpu寄存器里面的数值,检查是否为无效啊,什么的.如果发现无效数(亲,每条指令都会检查哦),就检查
浮点标志寄存器,查看是否允许抛出异常.如果允许,就抛出异常,直接蓝屏
解决方案:
1:不使用易语言来做运算,构建自己的汇编运算库,(代价太大.)
2:微软还是很多精英的,专门为了咱们易语言提供了2个函数
KeSaveFloatingPointState
和 KeRestoreFloatingPointState 来保存浮点寄存器,且把浮点异常标志位全部禁用.
最后吐槽
论坛99%的驱动代码都有这个隐患,只有几个大牛知道这一回事.
顺带贴个代码,下面的类,专门解决这个问题.
.版本 2
.程序集 浮点运算, , 公开, 利用类来巧妙的保存FPU寄存器
.程序集变量 浮点缓冲区, 整数型
.子程序 _初始化, , , 当基于本类的对象被创建后,此方法会被自动调用
浮点缓冲区 = 申请内存 (256)
.如果真 (取反
(NT_SUCCESS (KeSaveFloatingPointState (浮点缓冲区))))
释放内存
(浮点缓冲区)
浮点缓冲区 = 0 ‘ 清空
.如果真结束
.子程序 _销毁, , , 当基于本类的对象被销毁前,此方法会被自动调用
.如果真 (浮点缓冲区 ≠
0)
KeRestoreFloatingPointState
(浮点缓冲区)
释放内存 (浮点缓冲区)
.如果真结束
.子程序 初始化, 逻辑型, 公开,
初始化成功则返回真
返回 (浮点缓冲区 ≠ 0)
调用的话,先声明一个局部变量,然后,调用初始化,就good了~~~