如何在NASM中实现两个浮点数相加并将结果存储到变量?
在NASM中存储x87浮点运算结果到变量
你的核心问题是没搞清楚x87浮点寄存器栈的工作逻辑:浮点运算的结果存在ST0(x87浮点栈的栈顶寄存器)里,这是专用的浮点寄存器空间,不能用通用寄存器的mov指令直接存取,必须用x87专属的存储指令。
错误原因
你之前写的mov eax, dword [esp]取的是栈上原来存放的3.25单精度值,根本没触及浮点运算的结果(结果在ST0里,和普通内存/通用寄存器是完全独立的空间),所以自然得不到正确结果。
正确实现步骤
定义对应精度的变量:根据你要存储的浮点数精度,在
.bss或.data段定义变量:- 单精度浮点数(4字节):
res resd 1 - 双精度浮点数(8字节):
res resq 1 - 扩展精度浮点数(10字节):
res rest 1
- 单精度浮点数(4字节):
用x87指令操作ST0:
fst:将ST0的内容复制到内存变量,保留ST0在浮点栈中fstp:将ST0的内容复制到内存变量,同时弹出ST0(清理浮点栈,避免栈溢出)
完整示例代码
section .bss res resd 1 ; 定义单精度浮点数变量,用于存储运算结果 section .text global _start _start: sub esp, 8 mov dword [esp], 2 fild dword [esp] ; 将整数2加载到ST0(自动转换为80位扩展精度浮点数) mov dword [esp], __float32__(3.25) ; 栈中存入单精度3.25的二进制值 fadd dword [esp] ; ST0 = 2.0 + 3.25 = 5.25(仍为80位扩展精度) ; 将ST0的结果存储到res变量(自动转换为单精度) fstp dword [res] ; 存值后弹出ST0,清理浮点栈 ; 后续可对res进行操作,比如打印或其他运算 ; ... ; 退出程序 mov eax, 1 xor ebx, ebx int 0x80
额外说明
- 如果需要存储双精度结果,只需把变量改成
res resq 1,存储指令改成fstp qword [res]即可 - x87浮点栈的所有元素都是80位扩展精度,使用
fst/fstp时会自动转换为你指定的内存精度 - 建议用
fstp清理浮点栈,否则多次操作后可能导致栈溢出,引发程序异常
内容的提问来源于stack exchange,提问作者hberkayy
相关产品推荐
相关产品推荐

