Windows x64汇编中扩展精度浮点数无法正确打印的原因排查
问题分析与修复
你的代码输出0.000000e+00的核心原因是浮点数转整数时溢出,加上后续错误的类型转换操作:
1.234567e20远大于64位整数的最大值(约9.2e18),用fistp将80位浮点数转成整数时直接溢出,导致temp存储的结果无效。- 后续又错误地把
temp当作32位整数转成double,进一步放大了错误。
修复后的代码
bits 64 default rel segment .data real_number_1 dt 1.234567e20 ; 扩展精度浮点数 format_1 db "real_number_1: %le", 0xa, 0 segment .text global main extern ExitProcess extern printf main: push rbp mov rbp, rsp sub rsp, 32 ; 直接将80位浮点数转换为双精度(double),无需中转整数 fld TWORD [real_number_1] ; 加载80位浮点数到FPU栈顶ST0 fstp QWORD [rsp+16] ; 将ST0转成双精度并存入栈上的printf第二个参数位置 lea rcx, [format_1] ; 第一个参数:格式化字符串 call printf xor rax, rax call ExitProcess
关键修改说明
- 移除了无用的
.bss段和temp变量,不需要通过整数中转 - 用
fstp QWORD [rsp+16]直接将80位浮点数转成双精度(double),匹配printf的%le格式要求 - 如果你更倾向于用XMM寄存器传递浮点参数(符合x86-64标准调用约定),可以用下面的写法:
; 在.data段添加临时变量 temp resq 1 ; 替换main里的转换代码 fld TWORD [real_number_1] fstp QWORD [temp] ; 将80位浮点数转成双精度存入temp movsd xmm0, QWORD [temp] ; 加载到xmm0(printf的浮点参数需通过XMM寄存器传递) lea rcx, [format_1] call printf
内容的提问来源于stack exchange,提问作者zackjj
相关产品推荐
相关产品推荐

