如何在FPU中修改st(x)(x>0)?以修改st(2)为例
如何修改FPU中的st(x)(x>0)寄存器
原方法的问题
你之前的操作出现QNaN主要有两个原因:
- 直接用
mov修改内存值时,xxx不是符合IEEE 754标准的单/双精度浮点数二进制格式,FLD加载时会被识别为无效值,从而变成QNaN。 - 虽然用
fstp弹出再fld加载的逻辑能恢复寄存器顺序,但操作繁琐且容易出错,一旦内存中的数据格式不对就会触发无效值。
正确修改方法(以修改st(2)为例)
方法1:用FXCH交换寄存器后替换
这是最简洁的方式,无需额外操作栈深度:
; 1. 将目标浮点数加载到栈顶st(0) ; 示例:加载双精度浮点数3.14(十六进制表示为0x40091EB851EB851F) mov qword ptr [temp_mem], 0x40091EB851EB851F fld qword ptr [temp_mem] ; 2. 交换st(0)和st(2)的内容,此时st(2)已变为新值 fxch st(2) ; 3. 弹出原st(2)的值(现在在st(0)),恢复栈深度 fstp st(0)
如果要修改的是整数转浮点数,可先用FILD转换:
; 将整数100转成浮点数加载到st(0) mov dword ptr [temp_int], 100 fild dword ptr [temp_int] fxch st(2) fstp st(0)
方法2:通过临时内存修改(保留原st(2)值的场景)
如果需要先读取st(2)的值修改后再写回:
; 1. 将st(2)的值存入临时内存(双精度用qword,单精度用dword) fst qword ptr [temp_mem] ; 2. 修改内存中的值(必须是合法的浮点数二进制格式) ; 示例:给原数值加1.0,可先FLD原数值、FADD后再存回 fld qword ptr [temp_mem] fld1 faddp st(1), st(0) fst qword ptr [temp_mem] ; 3. 加载修改后的值到st(0) fld qword ptr [temp_mem] ; 4. 交换到st(2)并弹出原值 fxch st(2) fstp st(0)
注意事项
- 确保所有内存操作的宽度匹配:双精度浮点数用
qword ptr,单精度用dword ptr,宽度不匹配会导致数据错误。 - 直接用
mov设置内存浮点数时,必须使用目标浮点数对应的十六进制二进制表示,不能直接用整数或十进制数值。
内容的提问来源于stack exchange,提问作者TONIKROOS050608
相关产品推荐
相关产品推荐

