移动时无效的浮点运算? [英] Invalid float point operation on Move?

查看:99
本文介绍了移动时无效的浮点运算?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个从未见过的怪异问题,在Delphi 2010中,有时在使用例程CopyMemory时(​​内部调用Move)时,我收到一个无效的浮点操作异常,当使用Move时会发生这种情况吗??

I´m experiencing an weird issue that I have never seen before, in Delphi 2010 sometimes when using the routine CopyMemory (Which internally calls Move) I get an Invalid Float Point Operation exception, when such thing could happen when using Move??

我在汇编器中有调试信息,我检查了Move的源代码,并且FILD指令中发生了问题,我发现FILD将内存中的整数值转换为寄存器中的浮点数,并且可能触发该无效操作,但是为什么会这样呢?我已经坚持了两天了

I have a debug information in assembler, I have checked the source code of Move and the problem happens in FILD instruction, I found that FILD converts an integer value from memory to float point in a register and it could trigger that invalid operation, but why that happens? I´m stuck with this for 2 days now

Assembler Information:
; System.Move (Line=0 - Offset=1)
;
00404E0C cmp eax, edx
00404E0E jz System.Move
00404E10 cmp ecx, +$20
00404E13 jnbe System.Move
00404E15 sub ecx, +$08
00404E18 jnle System.Move
00404E1A jmp dword ptr [System.Move+ecx*4]
00404E21 fild qword ptr [ecx+eax]
00404E24 fild qword ptr [eax] ; <-- EXCEPTION
00404E26 cmp ecx, +$08
00404E29 jle System.Move
00404E2B fild qword ptr [eax+$08]
00404E2E cmp ecx, +$10
00404E31 jle System.Move
00404E33 fild qword ptr [eax+$10]
00404E36 fistp qword ptr [edx+$10]
00404E39 fistp qword ptr [edx+$08]
00404E3C fistp qword ptr [edx]
00404E3E fistp qword ptr [ecx+edx]

Registers:
EAX: 0E3A4694 EDI: 0000000D
EBX: 00001B5C ESI: 0ECF7928
ECX: 00000005 ESP: 0612FC1C
EDX: 0E3A2B38 EIP: 00404E24

什么可能导致该错误?

推荐答案

我以前见过此问题.问题在于,在进入Move方法之前,x87寄存器的堆栈包含一些无效的浮点值,而不是变空.这是由于较早发生的异常所致,并因此留下了x87堆栈.

I have seen this problem before. The problem was that before entering into the Move method the stack of the x87 registers contained some invalid floating point values instead of beging empty. This was due to an exception that occured earlier and left the x87 stack like that.

Move命令使用x87寄存器,因为它们允许快速移动数据而无需依赖SSE指令,但它假定堆栈为空.

The Move command uses the x87 registers because they allow for fast movement of data without depending on SSE instructions but it assumes the stack is empty.

寻找解决方案:

  • 在"Move"命令的开头设置一个断点,并使用FPU调试窗口来验证FPU堆栈确实已被废弃.
  • 从此处开始:使用相同的窗口,在您的应用程序中追溯此FPU堆栈损坏的原因.这是造成您问题的原因.

这篇关于移动时无效的浮点运算?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆