经典汇编语言教程:例11.11 编写一个子程序,求解一元二次方程的根

例11.11 编写一个子程序,求解一元二次方程的根

;调用参数:方程的系数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 

经典汇编语言教程·相关目录

第1章 汇编语言的由来,数据类型第2章 CPU资源和存储器
第3章 操作数的寻址方式第4章 标识符和表达式
第5章 微机CPU的指令系统第6章 程序的基本结构
第7章 子程序和库第8章 输入输出和中断
第9章 宏第10章 应用程序设计
第11章 数值运算协处理器第12章 汇编语言和C语言
汇编语言重要附录Windows API函数大全
版权所有 © 中山市飞娥软件工作室 证书:粤ICP备09170368号