例11.11 编写一个子程序,求解一元二次方程的根ax2 + bx + c = 0的根。
|     
 解:  |  
  |||
|     
 ;调用参数:方程的系数a、b和c,R1和R2是指向存放根的指针;  |  
  |||
|     
 ;返回参数:返回值存于AX中,其含义:0—有二个根,1—有一个根R1,2—无实根。  |  
  |||
| Quadratic |  
       PROC USES DS DI SI, AA:DWORD, BB:DWORD, CC:DWORD, R1:PDWORD, R2:PDWORD  |    
  ||
| LES | DI, R1 | ;(ES:DI) → 1st Root-R1 | |
| LDS | SI, R2 | ;(DS:SI) → 2nd Root-R2 | |
| SUB | BX, BX | ;用BX来标识方程有根的情况 | |
| FLD1 | ;栈顶寄存器置1 | ||
| FADD | ST, ST | ;栈顶寄存器自加,变成2 | |
| FLD | ST | ;把数值2复制一份到新的栈顶 | |
| FMUL | AA | ;ST = 2A | |
| FTST | ;测试ST是否为0,即,考虑A=0的情况 | ||
| FSTSW | AX | ;把当前状态寄存器存入AX中 | |
| FWAIT | ;等待协处理器完成上面操作 | ||
| SAHF | ;AH装入到标志寄存器中 | ||
| JNZ | Notzero | ;考虑A = 0的情况 | |
| FLD | CC | ;常数项C进栈 | |
| FCHS | ;改变栈顶的符号,得到-C | ||
| FLD | BB | ;参数B进栈 | |
| FTST | ;测试当前栈顶是否为0 | ||
| FSTSW | AX | ||
| SAHF | |||
| JZ | EXIT2 | ;考虑B = 0的情况 | |
| FDIV | ;计算出-C/B | ||
| FSTP | dword ptr ES:[DI] | ;得到一个根,并弹出栈顶 | |
| FSTP | ST | ;弹出多余的堆栈数据 | |
| JMP | EXIT1 | ;返回,并标识有1个根 | |
| Notzero: | |||
| FMUL | ST(1), ST | ;ST(1) = 4A | |
| FXCH | ;ST和ST(1)交换 | ||
| FMUL | CC | ;ST = 4AC | |
| FTST | |||
| FSTSW | AX | ||
| SAHF | |||
| JP | EXIT2 | ;如果状态位C2=1,则4AC是无穷大 | |
| FLD | BB | ;装入参数B | |
| FMUL | ST, ST | ;ST = B2 | |
| FSUBR | ;ST = B2 - 4AC | ||
| FTST | |||
| FSTSW | AX | ||
| SAHF | |||
| JC | EXIT2 | ;如果C0=1,则B2 < 4AC | |
| JNZ | Tworoot | ;如果C3=1,则B2 = 4AC | |
| INC | BX | ;标志有1个根 | |
| Tworoot: | |||
| FSQRT | ;求出B2 - 4AC的平方根 | ||
| FLD | BB | ||
| FCHS | ;得到-B | ||
| FXCH | ;ST 和ST(1)交换 | ||
| FLD | ST | ;栈顶再复制一份 | |
| FADD | ST, ST(2) | ;ST = -B + SQRT(B2 - 4AC) | |
| FXCH | ;ST 和ST(1)交换 | ||
| FSUBP | ST(2), ST | ;ST = -B - SQRT(B2 - 4AC) | |
| FDIV | ST, ST(2) | ;得到一个根ST = ST/(2A) | |
| FSTP | dword ptr ES:[DI] | ;存储第一个根 | |
| FDIVR | ;得到另一个根ST = ST/(2A) | ||
| FSTP | dword ptr DS:[SI] | ;存储第二个根 | |
| JMP | EXIT | ||
| EXIT2: | |||
| INC | BX | ;无根时的返回出口 | |
| FSTP | ST | ;清除多余的堆栈数据 | |
| EXIT1: | |||
| INC | BX | ;有一个根时的返回出口 | |
| FSTP | ST | ;清除多余的堆栈数据 | |
| EXIT: | |||
| MOV | AX, BX | ||
| RET | |||
| Quadratic | ENDP | ||
| END | |||