▶ 书中第十二章的程序,主要讲了 FPU 的指令和浮点数计算的过程
● 代码,简单的 32 为浮点数测试
1 INCLUDE Irvine32.inc 2 INCLUDE macros.inc 3 4 .data 5 first REAL8 123.456 6 second REAL8 10.0 7 third REAL8 ? 8 9 .code 10 main PROC 11 finit ; 初始化 FPU 12 13 fld first 14 fld second 15 call ShowFPUStack ; 展示栈中的浮点数 16 17 mWrite "Please enter a real number: " ; 输入两个浮点数相乘 18 call ReadFloat 19 mWrite "Please enter a real number: " 20 call ReadFloat 21 22 fmul ST(0),ST(1) ; 乘法 23 24 mWrite "Product: " 25 call WriteFloat 26 call Crlf 27 call waitmsg 28 exit 29 main ENDP 30 31 END main
● FPU 表达式计算 (6.0 * 2.0) + (4.5 * 3.2)
1 INCLUDE Irvine32.inc 2 3 .data 4 array REAL4 6.0, 2.0, 4.5, 3.2 5 dotProduct REAL4 ? 6 7 .code 8 main PROC 9 finit ; 初始化 10 11 fld array ; push 6.0 12 fmul array + 4 ; ST(0) = 6.0 * 2.0 13 call ShowFPUStack 14 15 fld array + 8 ; push 4.5 16 fmul array + 12 ; ST(0) = 4.5 * 3.2 17 call ShowFPUStack 18 19 fadd ; ST(0) = ST(0) + ST(1) 20 call ShowFPUStack 21 fstp dotProduct ; 栈中数据转入内存 22 call waitmsg 23 exit 24 main ENDP 25 26 END main
● FPU 比较和分支
1 INCLUDE Irvine32.inc 2 3 .data 4 x real8 1.2 5 y real8 2.0 6 XLessThanY BYTE "x < y",0 7 XGreaterThanY BYTE "x >= y",0 8 9 .code 10 main PROC ; 第一种方法 11 finit ; 初始化 12 fld x ; 分别压入 x 和 y 13 fcomp y 14 fnstsw ax ; 状态字放入 ax 15 sahf ; AH 复制到 EFLAGS 16 jnb L1 ; x >= y 则跳到 L1 17 mov edx, OFFSET XLessThanY 18 call writeString 19 jmp L2 20 L1: 21 mov edx, OFFSET XGreaterThanY 22 call writeString 23 24 L2: 25 call crlf 26 call waitmsg 27 exit 28 main ENDP 29 30 main2 PROC ; 第二种方法,使用指令 fcomi 31 finit 32 fld y ; 先压入 y 再压入 x 33 fld x 34 fcomi ST(0), ST(1) ; 在栈中比较 35 jnb L1 ; 直接使用EFLAG 作分支,不再搬运两次 36 mov edx, OFFSET XLessThanY 37 call writeString 38 jmp L2 39 L1: 40 mov edx, OFFSET 41 call writeString 42 43 L2: 44 call crlf 45 call waitmsg 46 exit 47 main2 ENDP 48 49 END main