Kip Irvine 汇编语言 基于x86处理器 Chapter12 代码(含习题)

案例代码

01.加载浮点数数值



.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	array	REAL8	10 DUP(0.0)			;定义一个具有10个元素的数组类型为扩展双精度

.code
	main PROC
		mov		esi,0
		mov		ebx,offset array
		fld		array					;直接寻址
		fld		[array+6]				;直接偏移寻址
		;fld		REAL8 PTR[esi]			;间接寻址
		fld		array[esi]				;变址寻址
		fld		array[esi+8]			;带比例因子的变址
		fld		array[esi*TYPE array]	;带比例因子的变址
		fld		REAL8 PTR[ebx+esi]		;基址变址寻址
		;fld		array[ebx+esi]			;基址变址偏移量
		;fld		array[ebx+esi*TYPE array];带比例因子的基址-变址-偏移量

		invoke ExitProcess,0
	main ENDP
END main

02.加载浮点数到指定的堆栈

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	dblOne	REAL8 234.56
	dblTwo  REAL8 10.1

.code
	main PROC

		fld		dblOne
		fld		dblTwo

		call	showFPUStack

		invoke ExitProcess,0
	main ENDP
END main

03.测试特定常数加载指令

include irvine32.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data


.code
	main PROC

		;加载常数到FPU Stack
		fld1		;压入1.0
		fldl2t		;压入log?10
		fldl2e		;压入log?E
		fldpi		;压入π
		fldlg2		;压入lg2
		fldln2		;压入ln2
		fldz		;加载0
		
		call	showFPUStack

		invoke ExitProcess,0
	main ENDP
	END main

04.FST 与 FSTP 命令 ---- 保存浮点数的值

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	dblThree	REAL8	10.1
	dblFour		REAL8	234.56
	
.code
	main PROC

		;显示FPU中的内容
		call	ShowFPUStack
		call	Crlf

		;加载几个浮点数到FPU中
		fld		dblThree
		fld		dblFour
		call	ShowFPUStack
		call	Crlf

		;使用FST指令获得栈顶元素 但是不删除栈顶元素 相当于C++中的 stack<T>::top()
		fst		dblThree
		fst		dblFour			;这时dblFour中的元素与dblThree中的元素的值是一样的
		call	ShowFPUStack	
		call	Crlf

		;使用FSTP指令获得栈顶元素 但是删除栈顶元素 相当于C++中的 stack<T>::pop()
		fstp	dblThree
		fstp	dblFour			;这时dblFour中的元素与dblThree中的元素的值是不一样的
		call	ShowFPUStack	;FPU stack was empty
		call	Crlf



		invoke ExitProcess,0
	main ENDP
	END main

05.FIST指令的应用

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	Z	REAL4	0.0

.code
	main PROC

		fld1
		fist	Z		;将栈顶元素加载到Z中


		invoke ExitProcess,0
	main ENDP
	END main

06.FCHS AND FABS

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	NUM		REAL4	2.0		;定义一个浮点数

.code
	main PROC

		;定义一个REAL4类型的变量 将其压入FPU Stack中
		fld		NUM
		call	ShowFPUStack

		;使用FCHS更改栈顶元素的符号
		FCHS
		call	Crlf
		call	WriteFloat		;输出栈顶元素

		;使用FABS将栈顶元素变成他的绝对值
		FCHS
		call	Crlf
		call	WriteFloat		;输出栈顶元素

		invoke ExitProcess,0
	main ENDP
	END main

07.算术运算指令–加法

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	array		REAL4	1.0,2.0,3.0
	myInteger	DWORD	1

.code
	main PROC
		
		;fadd
		fld		REAL4 PTR [array+0]
		fld		REAL4 PTR [array+4]
		fld		REAL4 PTR [array+8]

		call	ShowFPUStack

		fadd

		call	Crlf
		call	ShowFPUStack

		;faddp

		faddp
		call	Crlf
		call	ShowFPUStack

		;fiadd

		fiadd	myInteger
		call	Crlf
		call	ShowFPUStack

		invoke ExitProcess,0
	main ENDP
END main

08.算术运算指令–减法

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	array		REAL4	1.0,2.0,3.0
	myInteger	DWORD	1

.code
	main PROC
		
		;fsub
		fld		REAL4 PTR [array+0]
		fld		REAL4 PTR [array+4]
		fld		REAL4 PTR [array+8]

		call	ShowFPUStack

		fsub

		call	Crlf
		call	ShowFPUStack

		;fsubp

		fsubp
		call	Crlf
		call	ShowFPUStack

		;fisub

		fisub	myInteger
		call	Crlf
		call	ShowFPUStack

		invoke ExitProcess,0
	main ENDP
END main

09.算术运算指令–乘法

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	array		REAL4	1.0,2.0,3.0
	myInteger	DWORD	1

.code
	main PROC
		
		;fmul
		fld		REAL4 PTR [array+0]
		fld		REAL4 PTR [array+4]
		fld		REAL4 PTR [array+8]

		call	ShowFPUStack

		fmul

		call	Crlf
		call	ShowFPUStack

		;fmulp

		fmulp
		call	Crlf
		call	ShowFPUStack

		;fisub

		fimul	myInteger
		call	Crlf
		call	ShowFPUStack

		invoke ExitProcess,0
	main ENDP
END main

10.算术运算指令–除法

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	array		REAL4	1.0,2.0,3.0
	myInteger	DWORD	1

.code
	main PROC
		
		;fdiv
		fld		REAL4 PTR [array+0]
		fld		REAL4 PTR [array+4]
		fld		REAL4 PTR [array+8]

		call	ShowFPUStack

		fdiv

		call	Crlf
		call	ShowFPUStack

		;fdivp

		fdivp
		call	Crlf
		call	ShowFPUStack

		;fidiv

		fidiv	myInteger
		call	Crlf
		call	ShowFPUStack

		invoke ExitProcess,0
	main ENDP
END main

11.fld fdiv fstp的综合运用

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	dblOne	REAL8	1234.56
	dblTwo	REAL8	10.0
	dblQuot	REAL8	?
	
.code
	main PROC
		
		fld		dblOne		;加载到ST(0)
		fdiv	dblTwo		;ST(0)除以dblTwo 结果保存在栈顶
		fstp	dblQuot		;将ST(0)保存到dbQuot

		;输出结果
		fld		dblQuot
		call	WriteFloat
		
		invoke ExitProcess,0
	main ENDP
END main

12.比较浮点数的值

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	X		REAL8	1.2
	Y		REAL8	3.0
	N		DWORD	?
	str1	BYTE	"greater",0
	str2	BYTE	"lesser",0

.code
	main PROC

		fld		X					;ST(0)=X
		fcomp	Y					;将Y与X进行比较
		fnstsw	ax					;将浮点数比较状态字送入ax
		sahf						;将状态字转存至EFLAGS
		jnb		L1					;如果>=跳转
			mov		edx,offset str1
			call	WriteString
			jmp		quit
		L1:
			mov		edx,offset str2
			call	WriteString
		quit:
			;do something else
			exit

		invoke ExitProcess,0
	main ENDP
	END main

13.FCOMI比较浮点数的值并直接设置ZF PF CF

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	X		REAL8	1.2
	Y		REAL8	3.0
	N		DWORD	?
	str1	BYTE	"greater",0
	str2	BYTE	"lesser",0

.code
	main PROC

		fld		X					;ST(0)=X
		fld		Y					;ST(1)=Y
		fcomi	ST(0),ST(1)			;比较ST(0)ST(1)
		jnb		L1					;如果>=跳转
			mov		edx,offset str1
			call	WriteString
			jmp		quit
		L1:
			mov		edx,offset str2
			call	WriteString
		quit:
			;do something else
			exit

		invoke ExitProcess,0
	main ENDP
END main

14.使用汇编语言近似的比较两个浮点数

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	epsilon		REAL8	1.0e-12
	val2		REAL8	0.0			;比较的数值
	val3		REAL8	1.001e-13	;认为等于val2

	prompt		BYTE	"Values are eqaul",0

.code
	main PROC
		
		;如果val2==val3 显示Values are equal
		fld		epsilon
		fld		val2
		fsub	val3
		fabs						;对栈顶元素取绝对值
		fcomi	ST(0),ST(1)
		ja		skip

	
		mWrite	<"Values are eqaul!",0>
	skip:
		call	WaitMsg
		invoke ExitProcess,0
	main ENDP
END main

15.floatTest32

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	
	first	REAL8	123.456
	second	REAL8	10.0
	third	REAL8	?

.code
	main PROC

		finit						;初始化FPU
		;两个浮点数入栈并且显示当前的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(0),ST(1)				;相乘

		mWrite		"The product is :"
		call		WriteFloat
		call		Crlf

		invoke ExitProcess,0
	main ENDP
END main

16.计算表达式

;本例对应p423下面的例子
;表达式求解实例

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	valA	REAL8	1.5
	valB	REAL8	2.5
	valC	REAL8	3.0
	valD	REAL8	?		;+6.0

.code
	main PROC

		fld		valA		;ST(0) = valA
		fchs				;修改栈顶元素的符号
		fld		valB		;将valB加载到ST(0)
		fmul	valC		;ST(0) *= valC
		fadd				;ST(0) += ST(1)
		fstp	valD		;ST(0)保存到valD

		mWrite	<"当前FPU Stack中的内容为:",0dh,0ah>
		call	ShowFPUStack

		call	Crlf

		;显示valD的值
		mWrite	<"ValD=">
		fld		valD
		CALL	WriteFloat

		invoke ExitProcess,0
	main ENDP
	END main

17.浮点数组求和程序

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	ARRAY_SIZE	=		20
	sngArray	REAL8	ARRAY_SIZE DUP(2.0)

.code
	main PROC

		mov		esi,0				;数组索引
		fldz						;0.0入栈
		mov		ecx,ARRAY_SIZE		

	L1:
		fld		sngArray[esi]		;将内存操作数加载到ST(0)
		fadd						;ST(0)+ST(1),出栈
		add		esi,type real8		;指向下一个元素

		loop	L1

		call	WriteFloat			;显示ST(0)中的和数

		invoke ExitProcess,0
	main ENDP
	END main

18.计算平方根之和

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	valA	REAL8	25.0
	valB	REAL8	36.0

.code
	main PROC

		fld		valA		;ValA入栈
		call	ShowFPUStack
		fsqrt				;ST(0) = sqrt(valA)
		call	ShowFPUStack
		fld		valB		;ValB入栈
		call	ShowFPUStack
		fsqrt				;ST(0) = sqrt(valB)
		call	ShowFPUStack
		fadd	
		call	ShowFPUStack
		invoke ExitProcess,0
	main ENDP
END main

19.计算数组的点积

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	array	REAL4	6.0,2.0,4.5,3.2

.code
	main PROC

		fld		array
		fmul	[array+4]
		fld		[array+8]
		fmul	[array+12]
		fadd
		call	WriteFloat
		invoke ExitProcess,0
	main ENDP
END main

20.混合模式运算01

;本程序对应 p425程序 01    fild 将整数加载到FPU Stack

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data

	N	SDWORD	20
	X	REAL8	3.5
	Z	REAL8	?			;保存计算结果

.code
	main PROC

		fild	N		;将整数进行格式变换之后加载到FPU Stack
		fadd	X
		fstp	Z		;ST(0)保存至内存操作数

		fld		Z
		call	WriteFLoat

		invoke ExitProcess,0
	main ENDP
	END main

21.混合模式运算02

include irvine32.inc
include macros.inc

.686p


.model flat,stdcall


.stack 4096


	ExitProcess PROTO,dwExitCode:DWORD


.data
	N	SDWORD	20
	X	REAL8	3.5
	Z	SDWORD	?			;保存计算结果

.code
	main PROC

		fild	N			;将整数加载到ST(0)
		fadd	X			;将内存操作数与ST(0)相加
		fist	Z			;将栈顶的计算结果保存至内存Z中

		;输出Z的值
		mov		eax, Z
		call	WriteInt

		invoke ExitProcess,0
	main ENDP
END main

习题

12.7.01

; Chapter 12, Exercise 1					(FloatingPointComparison.asm)

; Description: This program implement the following C++ code in assembly 
; language:
; 	double X;
; 	double Y;
; 	if( X < Y )
; 		printf("X is lower\n");
; 	else
; 		printf("X is not lower\n");
; 		
; Note: I have chosen to make the solution program more interactive than
; required in the project specifications. 

; The user should run the program several times, assigning a range of values 
; to X and Y that test your program抯 logic.

INCLUDE Irvine32.inc

.data
X REAL8 ?
Y REAL8 ?
str1 BYTE "X is lower",0dh,0ah,0
str2 BYTE "X is not lower",0dh,0ah,0
str3 BYTE "Enter the value of X: ",0
str4 BYTE "Enter the value of Y: ",0

.code
main PROC
	call Clrscr

	finit
	mov	edx,OFFSET str4
	call	WriteString
	call	ReadFloat			; push Y

	mov	edx,OFFSET str3
	call	WriteString
	call	ReadFloat			; push X
	
	fcomi st(0),st(1)		; compare X to Y
	jnb	L1
	mov	edx,OFFSET str1
	jmp	L2	

L1:	mov	 edx,OFFSET str2
L2:	call WriteString

	exit
main ENDP

END main

12.7.02

; Chapter 12, Exercise 2					(DisplayFPBinary.asm)

; Description: This program contains procedure named ShowSingleFloat that 
; receives a single-precision floating-point binary value and displays it
; in the following format: sign: display  or ; significand: binary floating-point, 
; prefixed by ?.? exponent: display in decimal, unbiased, preceded by the 
; letter E and the exponent抯 sign. Sample:
;	.data
;	sample REAL4 -1.75
;	Displayed output:
;	-1.11000000000000000000000 E+0
; 
; Note that the binary exponent does not match the decimal exponent.
; For example, converting 10.75 decimal to binary produces binary 1010 to the 
; left of the binary point. After normalizing the binary number, the binary 
; exponent is +3.

INCLUDE Irvine32.inc
INCLUDE macros.inc

; Writes the contents of AL to the console as a binary bit.

mWriteBitAL MACRO
	.IF AL == 1
	mWrite "1"
	.ELSE
	mWrite "0"
	.ENDIF
ENDM

.data
sample REAL4 10.75

.code
main PROC
	call Clrscr

	mov	ebx,sample
	mov	eax,0
	shld	eax,ebx,1		; shift the sign bit into EAX
	.IF eax == 1		; write the leading sign
	mWrite "-"
	.ELSE
	mWrite "+"
	.ENDIF
	mWriteBitAL		; write the value of AL
	mWrite "."
	shl	ebx,9		; remove the sign & exponent bits
	
; Display the bits of the significand, starting with the MSB.

	mov	ecx,23		; loop counter for 23 bits
	
L1:	mov	eax,0
	shld	eax,ebx,1		; get the next bit
	mWriteBitAL	
	shl	ebx,1		; remove the bit
	loop L1

; Display the unbiased exponent

	mWrite " "
	mov	eax,sample
	shr	eax,23		; remove significand
	and	eax,011111111b	; remove the sign bit
	sub	eax,127		; remove the bias value
	mWrite "E"
	call	WriteInt		; write the signed exponent

	call	Crlf
	exit
main ENDP

END main

12.7.03

; Chapter 12, Exercise 3					(SetRoundingModes.asm)

; Description: This program contains a macro that sets the FPU
; rounding mode. The single input parameter is a two-letter code:
;
;	?RE: Round to nearest even
;	?RD: Round down toward negative infinity
;	?FU: Round up toward positive infinity
;	?RZ: Round toward zero (truncate)
;
; Sample macro calls (case does not matter):
;		mRound Re
;		mRound rd
;		mRound RU
;		mRound rZ
;
; A short test program uses the FIST (store integer) instruction 
; to test each of the possible rounding modes.

INCLUDE Irvine32.inc

;-------------------------------------------------------
mRound MACRO mode
;-------------------------------------------------------
LOCAL ctrlWord

.data
ctrlWord WORD ?
.code
fstcw ctrlWord					; store control word

IFIDNI <mode>,<RE>				; RE = 00
	and	 ctrlWord,001111111111b	
ENDIF

IFIDNI <mode>,<RD>				; RD = 01
	or	ctrlWord,010000000000b
	and	ctrlWord,011111111111b
ENDIF

IFIDNI <mode>,<RU>				; RU = 10
	or	ctrlWord,100000000000b
	and	ctrlWord,101111111111b
ENDIF

IFIDNI <mode>,<RZ>				; RZ = 11
	or	 ctrlWord,110000000000b
ENDIF

	fldcw ctrlWord				; load control word
ENDM
;-----------------------------------------------------------

.data
N SDWORD 20
X REAL8 3.5
Z SDWORD ?

.code
main PROC
	call Clrscr

	mRound Re			; round to nearest even
	call	testRounding

	mRound rd			; Round down toward negative infinity
	call	testRounding

	mRound RU			; Round up toward positive infinity
	call	testRounding

	mRound rZ			; round toward zero
	call	testRounding

	exit
main ENDP

;-------------------------------------------------------
testRounding PROC
;-------------------------------------------------------

	fild N		; load integer into ST(0)
	fadd X		; add mem to ST(0)
	fist Z		; store ST(0) to mem int

; Display the rounded value.

	mov	eax,Z
	call	WriteInt
	call	Crlf

	ret
testRounding ENDP

END main

12.7.04

; Chapter 12, Exercise 4					(ExpressionEvaluation.asm)

; Description: This program evaluates the following arithmetic 
; expression:
;		((A + B) / C) * ((D - A) + E)

; Reverse polish: B A + C / D A - E + *
;
; It assigns test values to the variables and displays the 
; resulting value.

INCLUDE Irvine32.inc
.data
Av REAL8 6.0
Bv REAL8 4.0
Cv REAL8 2.0
Dv REAL8 5.0
Ev REAL8 3.0

; sample evaluation:
; ((6 + 4) / 2) * ((5 - 6) + 3)
; (10 / 2) * (-1 + 3)
; 5 * 2
; 10

.code
main PROC
	call Clrscr

; Reverse polish: B A + C / D A - E + *

	fld	Bv	; B + A
	fadd	Av
	fdiv Cv	; (B + A) / C	 <1>
	fld	Dv	; D - A
	fsub	Av
	fadd	Ev	; (D - A) + E	 <2>
	
; At this point, ST(0) = <2>, and ST(1) = <1>

	call	ShowFPUStack	; just for debugging

	fmul				; ST(1) * ST(0)
	call	WriteFloat	; shows ST(0)
	call	Crlf
	
	exit
main ENDP

END main

12.7.05

; Chapter 12, Exercisse 5				(AreaOfCircle.asm)

; Description: This program prompts the user for the radius of 
; a circle. It calculates and displays the circle抯 area. We use the 
; ReadFloat and WriteFloat procedures from the book抯 library. 
; The FLDPI instruction is used to load PI onto the register stack.
;		area = PI * radius^2

INCLUDE Irvine32.inc

.data
radius REAL8 ?
str1 BYTE "Please enter the circle's radius: ",0
str2 BYTE "The area of the circle is: ",0

.code
main PROC
	call Clrscr
	finit

	mov	edx,OFFSET str1
	call	WriteString
	call	ReadFloat		; ST(0) = radius
	
; Exponentiation has the highest precedence in this expression.
		
	fmul ST(0),ST(0)	; ST(0) = radius * radius

	fldpi			; ST(0) = PI, ST(1) = radius * radius
	fmul				; multiply ST(1) by ST(0), then pop
	
	mov	edx,OFFSET str2
	call	WriteString
	
	call	WriteFloat	; display ST(0): area of circle
	call	Crlf

	exit
main ENDP

END main

12.7.06

; Chapter 12, Exercisse 6				(QuadraticFormula.asm)

; Description: This program prompts the user for coefficients a, b, 
; and c of a polynomial in the form ax^2 + bx + c = 0. It calculates
; and displays the real roots of the polynomial using the quadratic 
; formula. If any root is imaginary, an appropriate message is displayed.
; Sample I/O used when testing the program:
;
;	Coefficient (A) for Ax^2 + Bx + C: 1
;	Coefficient (B) for Ax^2 + Bx + C: 6
;	Coefficient (C) for Ax^2 + Bx + C: 2
;	Root 1: -3.5424868E-001
;	Root 2: -5.6457513E+000

INCLUDE Irvine32.inc

.data
radius REAL8 ?
str1 BYTE "Coefficient (A) for Ax^2 + Bx + C: ",0
str2 BYTE "Coefficient (B) for Ax^2 + Bx + C: ",0
str3 BYTE "Coefficient (C) for Ax^2 + Bx + C: ",0
str4 BYTE "This polynomial has an imaginary root", 0
str5 BYTE "Root 1: ",0
str6 BYTE "Root 2: ",0

coeffA	REAL8 ?
coeffB	REAL8 ?
coeffC	REAL8 ?

two	REAL8 2.0
four	REAL8 4.0
zero REAL8 0.0
junk REAL8 0.0

part1 REAL8 ?		; sqrt( B^ - 4AC )

.code
main PROC

	call Clrscr
	finit
	call	getCoefficients
	
; B^2 - 4AC	
	
	fld	coeffB
	fmul	ST(0),ST(0)
	fld	four
	fmul	coeffA
	fmul	coeffC
	fsub			; ST(0) = B^2 - 4AC
	
	; Expression under the radical must be positive.
	fld	zero
	fcomi ST(0),ST(1)		; compare zero to ST(0)
	ja	imaginary_root		; must be negative (don't use JG!)
	
	; Expression is positive.
	fstp junk				; pop the zero value
	fsqrt				; square root of ST(0)
	fst	part1			; save part 1

; Calculate the first root
	
	fld	coeffB
	fchs					; negate B
	fadd	part1			; -B + part1
	
	fld	coeffA			; 2.0 * A
	fmul	two
	
	fdivp ST(1),ST(0)		; ST(0) = root 1

	; Display the first root.
	mov	edx,OFFSET str5
	call	WriteString
	call	WriteFloat
	call Crlf
	
; Calculate the second root
	
	fld	coeffB
	fchs					; negate B
	fsub	part1			; -B - part1
	
	fld	coeffA			; 2.0 * A
	fmul	two
	
	fdivp ST(1),ST(0)		; ST(0) = root 1

	; Display the second root.
	mov	edx,OFFSET str6
	call	WriteString
	call	WriteFloat
	call Crlf
	jmp	normal_finish

imaginary_root:
	mov	edx,OFFSET str4
	call	WriteString

normal_finish:
	call	Crlf

	exit
main ENDP

;------------------------------------
getCoefficients PROC
;------------------------------------
	mov	edx,OFFSET str1
	call	WriteString
	call	ReadFloat		
	fstp	coeffA

	mov	edx,OFFSET str2
	call	WriteString
	call	ReadFloat		
	fstp	coeffB

	mov	edx,OFFSET str3
	call	WriteString
	call	ReadFloat		
	fstp	coeffC

	ret
getCoefficients ENDP


END main

12.7.07

; Chapter 12, Exercise 7          (ShowingRegisters.asm)

COMMENT @
Write a program that pushes two or more values on the FPU 
stack, displays the stack by calling ShowFPUStack, displays 
the Tag value of each FPU data register, and displays the 
register number that corresponds to ST(0). (For the latter, 
call the FSTSW instruction to save the status word in a 16-bit 
integer variable, and extract the stack TOP indicator from 
bits 11 through 13.)
@

INCLUDE Irvine32.inc
INCLUDE macros.inc

.code
main PROC
	finit

.data
val1 REAL8 2.0
val2 REAL8 1.5
environment FPU_ENVIRON <>

statusWord WORD ?

.code
	finit
	fld	val1
	fld	val2
	call	ShowFPUStack
	call	Crlf

; Get the Tag word.
	fstenv environment
	movzx	edx,environment.tagWord

; Use a loop to display the status of each register.

	mov 	ecx,0	; register counter

L1:	mWrite "R"
	mov	eax,ecx
	call	WriteDec
	mWrite " "

	push	edx
	and	dl,11b
	.IF dl == 00b
	  mWrite <" is valid",0dh,0ah>
	.ELSE
	  mWrite <" is empty",0dh,0ah>
	.ENDIF
	pop	edx
	shr	edx,2
	inc	ecx
	cmp	ecx,8
	jb	L1
	call	Crlf

; Show which register is at ST(0).

	fstsw	statusWord
	movzx	eax,statusWord
	shr	ax,11	; shift TOP into low bits
	and	ax,111b	; mask low 3 bits

	mWrite "ST(0) = R"
	call	WriteDec
	call	Crlf
 
    exit
main ENDP

END main
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值