注意:自从我从事这种工作以来已经有一段时间了。希望我的答案在球场上。
您需要捕获发生这种情况时发生的 div-0 异常——我相信MSR.FE0
并且 需要进行操作,以确保以您想要的方式进行MSR.FE1
处理FPSCR.VE
。FPSCR.ZE
因此,一旦您完成设置并开始工作,您将需要:
控制这些场景(0/0 和 1/0)的异常处理。在我使用的大多数小型实时内核中,所有源代码都可用,我知道该怎么做。不确定您的 RTOS 是什么或您拥有多少控制权。很有可能,如果它是一个“重量级”的操作系统,它不会让你摆弄异常处理程序逻辑。我认为0/0
会触发“无效操作”异常(FPSCR.VE
),而1/0
会触发 IEEE 浮点除零异常(FPSCR.ZE
)。
如果您得到 Invalid Operation 异常,您需要确定原因是0/0
什么或其他。随着0/0
,FPSCR.VXZDZ
将被设置(我认为)。还有其他方法可以触发此异常,所以这FPSCR
是您的朋友。
如果你得到 IEEE FP div-0 异常,你需要确定原因是1/0
什么还是其他什么(例如2/0
)。我认为为此,您必须检查中断上下文的寄存器,以查看分子是否1
在导致异常的除法运算时。FPU 不在乎您是否尝试了1/0
or 2/0
,但显然您的应用程序确实如此。
接下来,您需要更改返回的上下文,以便获得所需的结果。这可能类似于更改操作中使用的 FP 寄存器,以便当您从异常返回并重新尝试 FP 除法时,它会产生零。例如,制作分子0
和除数1
。
然后当你从异常中返回时,你应该得到你想要的结果。抱歉,我对特定的寄存器和值生疏了,我希望这足以完成工作。
您还询问了仅为您的应用程序进程选择性地启用此行为。我以前不得不做这样的事情,但更多的是在平面地址空间中,“单进程,多线程”类型的内核(每个任务实际上都是一个线程,都在同一个平面地址空间中运行)。我已经完成了几种不同的方式,这里有一些可能对你有用的想法:
我以前继承过这样的遗留代码,我感到你的痛苦。您想对安装这种愚蠢行为的人挥舞拳头,但现在挥舞拳头并不能帮助您发布产品。你需要一个解决方案。祝你好运。