我有这个代码是假设添加两个数字,一个浮点数(3.25)和一个整数(2)。
编辑:
extern _printf, _scanf global _main section .bss num1: resb 4 section .data format_num: db "%f", 10, 0 section .text _main: mov dword [num1], __float32__(3.25) add num1, 2 sub esp, 8 fld dword [num1] mov dword [num1], eax fstp qword [esp] push format_num call _printf add esp, 12 ret
我得到的输出是:
test.asm:11:错误:操作码和操作数无效组合
我期望的结果是:
5.250000
x87 FPU的一个很好的教程超出了Stackoverflow的范围,但我可以推荐一个在MASM论坛上 。 另一个很好的来源是英特尔指令集参考 。 特别是大多数以F
开头的函数都是x87浮点单元(FPU)的相关指令。
一般来说,你不能只是将一个浮点值添加到一个整数。 他们是两种不同的表述。 你可以做的是将整数转换为浮点值,然后用它做浮点计算。 具体来说,以FI
开头的指令是涉及将整数内存操作数转换为浮点的浮点操作。
皮肤有很多种皮肤的方法,但是如果你回顾一下上面链接的FPU教程,你可能会意识到一个简单的方法就是这样做:
sub esp, 8 ; Allocate space on stack to store integer mov dword [esp], 2 ; Move the 32-bit integer value onto stack temporarily fild dword [esp] ; Load integer 2 from stack into top of FPU stack at st(0) ; Converting it to 2.0 in the process mov dword [esp], __float32__(3.25) ; Move 3.25 onto stack temporarily fadd dword [esp] ; Add 3.25 to st(0). Result in st(0). So st(0)=5.25 fstp qword [esp] ; Store 64-bit double to stack for printf and pop FPU stack.
我暂时不使用全局变量将值存储在主存储器中,而是使用我们预留的堆栈空间作为临时暂存区域来加载/操作x87 FPU。
如果您使用的是支持SSE2指令集(包括32位模式下的任何X86-64处理器)的CPU,则还有其他选项。 一种是使用SIMD指令和寄存器来执行32位和64位浮点运算。 使用指令集引用可以找到一些有用的指令,例如:
标量单精度FP值是一个32位浮点数。 标量双精度是64位双精度。
sub esp, 8 mov dword [esp], 2 ; Load integer 2 (32-bit signed value) onto stack temporarily cvtsi2sd xmm0, [esp] ; Convert 2 on stack to 64-bit float and store in XMM0 mov dword [esp], __float32__(3.25) ; Load 32-bit float value of 3.25 onto stack cvtss2sd xmm1, [esp] ; Load 32-bit single and convert it to 64-bit double. Store in XMM1 addsd xmm0, xmm1 ; Add 64-bit float in XMM0 and XMM1 store XMM0 movsd qword [esp], xmm0 ; Move 64-bit float back onto stack to be printed by printf
解决方案是:
extern _printf global _main section .bss num1: resb 4 num2: resb 4 section .data format_float: db "The result is %f", 10, 0 _main: mov dword [num1], 2 mov dword [num2], __float32__(3.25) sub esp, 8 fild dword [num1] fadd dword [num2] fstp qword [esp] push format_float call _printf add esp, 12 ret
我得到的输出是:
5.250000
fild
将2.0000000推入ST0
,然后fadd
可以添加两个浮点数。 结果是一个浮点数。 int + float = float
。
我很抱歉,我的英语不好。