▶ 书中第十二章的程序,主要讲了 FPU 的指令和浮点数计算的过程
● 代码,简单的 32 为浮点数测试
INCLUDE Irvine32.inc
INCLUDE macros.inc .data
first REAL8 .
second REAL8 .
third REAL8 ? .code
main PROC
finit ; 初始化 FPU fld first
fld second
call ShowFPUStack ; 展示栈中的浮点数 mWrite "Please enter a real number: " ; 输入两个浮点数相乘
call ReadFloat
mWrite "Please enter a real number: "
call ReadFloat fmul ST(),ST() ; 乘法 mWrite "Product: "
call WriteFloat
call Crlf
call waitmsg
exit
main ENDP END main
● FPU 表达式计算 (6.0 * 2.0) + (4.5 * 3.2)
INCLUDE Irvine32.inc .data
array REAL4 ., ., ., .
dotProduct REAL4 ? .code
main PROC
finit ; 初始化 fld array ; push 6.0
fmul array + ; ST(0) = 6.0 * 2.0
call ShowFPUStack fld array + ; push 4.5
fmul array + ; ST(0) = 4.5 * 3.2
call ShowFPUStack fadd ; ST(0) = ST(0) + ST(1)
call ShowFPUStack
fstp dotProduct ; 栈中数据转入内存
call waitmsg
exit
main ENDP END main
● FPU 比较和分支
INCLUDE Irvine32.inc .data
x real8 .
y real8 .
XLessThanY BYTE "x < y",
XGreaterThanY BYTE "x >= y", .code
main PROC ; 第一种方法
finit ; 初始化
fld x ; 分别压入 x 和 y
fcomp y
fnstsw ax ; 状态字放入 ax
sahf ; AH 复制到 EFLAGS
jnb L1 ; x >= y 则跳到 L1
mov edx, OFFSET XLessThanY
call writeString
jmp L2
L1:
mov edx, OFFSET XGreaterThanY
call writeString L2:
call crlf
call waitmsg
exit
main ENDP main2 PROC ; 第二种方法,使用指令 fcomi
finit
fld y ; 先压入 y 再压入 x
fld x
fcomi ST(), ST() ; 在栈中比较
jnb L1 ; 直接使用EFLAG 作分支,不再搬运两次
mov edx, OFFSET XLessThanY
call writeString
jmp L2
L1:
mov edx, OFFSET
call writeString L2:
call crlf
call waitmsg
exit
main2 ENDP END main