x64汇编中COMISS与COMISD差异及程序崩溃原因咨询
Win64下NASM浮点指令问题解析
1. comisd xmm10, xmm6崩溃的原因
- 数据格式不匹配:
comisd是双精度浮点数比较指令,要求操作数是合法的64位双精度浮点数。如果你的代码里用movss这类单精度指令给xmm10/xmm6赋值,寄存器的高64位会是未初始化的垃圾数据,组合起来的64位值可能是非法的双精度格式(比如无效的指数位、NaN的非法编码),执行comisd时会触发CPU无效操作异常(#IA),直接导致程序崩溃。而comiss是单精度比较,只看寄存器的低32位,只要这部分是合法单精度值就能正常运行。 - 寄存器状态异常:Win64微软调用约定中,xmm6-xmm15属于非易失性寄存器,如果你的函数调用前后没有正确保存/恢复这些寄存器的状态,可能导致寄存器数据被破坏,执行
comisd时因数据异常触发崩溃。
2. subss xmm10, xmm6搭配jz .end无效的原因
subss是单精度浮点数减法指令,它只会修改MXCSR寄存器里的浮点状态标志,不会更新通用状态寄存器EFLAGS中的ZF(零标志位)。而jz指令检测的是EFLAGS的ZF位,所以不管浮点数相减结果是否为0,jz都不会触发跳转。
要实现单精度浮点数相等判断,正确的做法是用comiss xmm10, xmm6,这条指令会根据比较结果设置EFLAGS的ZF、PF、CF等标志位,之后用je .end(对应相等时跳转)就能正常工作。
内容的提问来源于stack exchange,提问作者Angad Warhadpande
相关产品推荐
相关产品推荐

