《汇编语言 基于x86处理器》第十二章浮点数部分的代码

▶ 书中第十二章的程序,主要讲了 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
原文地址:https://www.cnblogs.com/cuancuancuanhao/p/9627408.html