⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fp.asm

📁 汇编编程艺术
💻 ASM
📖 第 1 页 / 共 5 页
字号:
		jae	BadSEFPA
		test	fpacc.Sign, 80h
		jz	StoreSEFPA
		or	ah, 80h
StoreSEFPA:	mov	es:[di]+8, ax
		mov	ax, fpacc.Mantissa [0]
		mov	es:[di], ax
		mov	ax, fpacc.Mantissa [2]
		mov	es:[di] + 2, ax
		mov	ax, fpacc.Mantissa [4]
		mov	es:[di] + 4, ax
		mov	ax, fpacc.Mantissa [6]
		mov	es:[di] + 6, ax
		clc
		jmp	SEFPADone
;
BadSEFPA:	stc
SEFPADone:	pop	fpacc.Exponent
		pop	fpacc.Mantissa[6]
		pop	fpacc.Mantissa[4]
		pop	fpacc.Mantissa[2]
		pop	fpacc.Mantissa[0]
		pop	ax
		pop	ds
		ret
		assume	ds:nothing
sl_SEFPA        endp
;
;
;
; sl_LSFPO- 	Loads a single precision (32-bit) IEEE format number into
;		the floating point operand.  ES:DI points at the # to
;		load into FPOP.
;
		public	sl_LSFPO
sl_LSFPO	proc	far
		push	ax
		push	bx
		mov	ax, es:[di]
		mov	word ptr StdGrp:fpop.mantissa[5], ax
		mov	ax, es:2[di]
		mov	bx, ax
		shl	ax, 1
		mov	al, ah
		mov	ah, 0
		add	ax, 32767-127		;Adjust exponent bias.
		mov	word ptr StdGrp:fpop.exponent, ax
		mov	StdGrp:fpop.sign, bh	;Save sign away.
		mov	al, es:2[di]
		and	al, 7fh			;Strip out L.O. exp bit.
		or	al, 80h			;Add in implied bit.
		mov	byte ptr StdGrp:fpop.mantissa[7], al
		xor	ax, ax
		mov	word ptr StdGrp:fpop.mantissa, ax
		mov	word ptr StdGrp:fpop.mantissa[2], ax
		mov	byte ptr StdGrp:fpop.mantissa[4], al
		pop	bx
		pop	ax
		ret
sl_LSFPO	endp
;
;
;
;
;
; sl_LDFPO-	Loads the double precision (64-bit) IEEE format number pointed
;		at by ES:DI into FPOP.
;
		public	sl_LDFPO
sl_LDFPO	proc	far
		push	ax
		push	bx
		push	cx
		mov	ax, es:6[di]
		mov	StdGrp:fpop.sign, ah	;Save sign bit.
		mov	cl, 4
		shr	ax, cl			;Align exponent field.
		and	ah, 111b		;Strip the sign bit.
		add	ax, 32767-1023		;Adjust bias
		mov	word ptr StdGrp:fpop.exponent, ax
;
; Get the mantissa bits and left justify them in the FPOP.
;
		mov	ax, es:5[di]
		and	ax, 0fffh		;Strip exponent bits.
		or	ah, 10h			;Add in implied bit.
		mov	cl, 3
		shl	ax, cl
		mov	bx, es:3[di]
		rol	bx, cl
		mov	ch, bl
		and	ch, 7
		or	al, ch
		mov	word ptr StdGrp:fpop.mantissa[6], ax
;
		and	bl, 0f8h
		mov	ax, es:1[di]
		rol	ax, cl
		mov	ch, al
		and	ch, 7
		or	bl, ch
		mov	word ptr StdGrp:fpop.mantissa[4], bx
;
		and	al, 0f8h
		mov	bh, es:[di]
		rol	bh, cl
		mov	ch, bh
		and	ch, 7
		or	al, ch
		mov	word ptr StdGrp:fpop.mantissa[2], ax
		and	bh, 0f8h
		mov	bl, 0
		mov	word ptr StdGrp:fpop.Mantissa[0], bx
;
		pop	cx
		pop	bx
		pop	ax
		ret
sl_LDFPO	endp
;
;
;
;
;
; sl_LEFPO-	Loads an extended precision (80-bit) IEEE format number
;		into the floating point operand.  ES:DI points at the
;		number to load into FPACC.
;
		public	sl_LEFPO
sl_LEFPO	proc	far
		push	ax
		mov	ax, es:8[di]
		mov	StdGrp:fpop.Sign, ah
		and 	ah, 7fh
		add	ax, 4000h
		mov	StdGrp:fpop.Exponent, ax
		mov	ax, es:[di]
		mov	StdGrp:fpop.Mantissa, ax
		mov	ax, es:2[di]
		mov	StdGrp:fpop.Mantissa[2], ax
		mov	ax, es:4[di]
		mov	StdGrp:fpop.Mantissa[4], ax
		mov	ax, es:6[di]
		mov	StdGrp:fpop.Mantissa[6], ax
		pop	ax
		ret
sl_LEFPO	endp
;
;
;
;
; sl_LEFPOL-	Loads an extended precision (80-bit) IEEE format number
;		into the floating point operand.  The number to load
;		follows the call instruction in the code stream.
;
		public	sl_LEFPOL
sl_LEFPOL	proc	far
		push	bp
		mov	bp, sp
		push	es
		push	di
		push	ax
		les	di, 2[bp]
;
		mov	ax, es:8[di]
		mov	StdGrp:fpop.Sign, ah
		and 	ah, 7fh
		add	ax, 4000h
		mov	StdGrp:fpop.Exponent, ax
		mov	ax, es:[di]
		mov	StdGrp:fpop.Mantissa, ax
		mov	ax, es:2[di]
		mov	StdGrp:fpop.Mantissa[2], ax
		mov	ax, es:4[di]
		mov	StdGrp:fpop.Mantissa[4], ax
		mov	ax, es:6[di]
		mov	StdGrp:fpop.Mantissa[6], ax
;
		add	word ptr 2[bp], 10	;Skip rtn adrs past #.
;
		pop	ax
		pop	di
		pop	es
		pop	bp
		ret
sl_LEFPOL	endp
;
;
;
;
;
;
;
;--------------------------------------------------------------------------
; 		Integer <=> FP Conversions
;--------------------------------------------------------------------------
;
;
;
; ITOF-		Converts 16-bit signed value in AX to a floating point value
;		in FPACC.
;
		public	sl_itof
sl_itof		proc	far
		assume	ds:stdgrp
		push	ds
		push	ax
		push	cx
		mov	cx, StdGrp
		mov	ds, cx
;
		mov	cx, 800Fh		;Magic exponent value (65536).
;
; Set the sign of the result:
;
		mov	fpacc.Sign, 0		;Assume a positive value.
		or	ax, ax			;Special case for zero!
		jz	SetFPACC0
		jns	DoUTOF			;Take care of neg values.
		mov	fpacc.sign, 80h		;This guy is negative!
		neg	ax			;Work with abs(AX).
		jmp	DoUTOF
sl_ITOF		endp
;
;
; UTOF-		Like ITOF above except this guy works for unsigned 16-bit
;		integer values.
;
		public	sl_utof
sl_UTOF		proc	far
		push	ds
		push	ax
		push	cx
;
;
		mov	cx, StdGrp
		mov	ds, cx
		mov	cx, 800Fh		;Magic exponent value (65536).
		or	ax, ax
		jz	SetFPACC0
		mov	fpacc.Sign, 0
;
sl_UTOF		endp
;
;
; Okay, convert the number to a floating point value:
; Remember, we need to end up with a normalized number (one where the H.O.
; bit of the mantissa contains a one).  The largest possible value (65535 or
; 0FFFFh) is equal to 800E FFFF 0000 0000 0000.  All other values have an
; exponent less than or equal to 800Eh.  If the H.O. bit of the value is
; not one, we must shift it to the left and dec the exp by 1.  E.g., if AX
; contains 1, then we will need to shift it 15 times to normalize the value,
; decrementing the exponent each time produces 7fffh which is the proper
; exponent for "1".
;
; Note: this is not a proc!  Making it a proc makes it incompatible with
; one or more different assemblers (TASM, OPTASM, MASM6).
; Besides, this has to be a near label with a far return!
;
DoUTOF:
UTOFWhlPos:	dec	cx
		shl	ax, 1
		jnc	UTOFWhlPos
		rcr	ax, 1			;Put bit back.
		mov	fpacc.Exponent, cx	;Save exponent value.
		mov	fpacc.Mantissa [6], ax	;Save Mantissa value.
		xor	ax, ax
		mov	fpacc.Mantissa [4], ax	;Zero out the rest of the
		mov	fpacc.Mantissa [2], ax	; mantissa.
		mov	fpacc.Mantissa [0], ax
		jmp     UTOFDone
;
; Special case for zero, must zero all bytes in FPACC.  Note that AX already
; contains zero.
;
SetFPACC0:	mov	fpacc.Exponent, ax
		mov	fpacc.Mantissa [6], ax
		mov	fpacc.Mantissa [4], ax
		mov	fpacc.Mantissa [2], ax
		mov	fpacc.Mantissa [0], ax
		mov	fpacc.Sign, al
;
UTOFDone:	pop	cx
		pop	ax
		pop	ds
		retf
;
;
;
;
;
;
; LTOF-		Converts 32-bit signed value in DX:AX to a floating point
;		value in FPACC.
;
		public	sl_ltof
sl_ltof		proc	far
		assume	ds:stdgrp
		push	ds
		push	ax
		push	cx
		push	dx
		mov	cx, StdGrp
		mov	ds, cx
;
; Set the sign of the result:
;
		mov	fpacc.Sign, 0		;Assumed a positive value.
		mov	cx, dx
		or	cx, ax
		jz	SetUL0
		or	dx, dx			;Special case for zero!
		jns	DoULTOF			;Take care of neg values.
		mov	fpacc.sign, 80h		;This guy is negative!
		neg	dx			;Do a 32-bit NEG operation
		neg	ax			; (yes, this really does
		sbb	dx, 0			;  work!).
		jmp	DoULTOF
sl_LTOF		endp
;
;
; ULTOF-	Like LTOF above except this guy works for unsigned 32-bit
;		integer values.
;
		public	sl_ultof
sl_ULTOF	proc	far
		push	ds
		push	ax
		push	cx
		push	dx
;
		mov	cx, StdGrp
		mov	ds, cx
;
		mov	cx, dx
		or	cx, ax
		jz	SetUL0
		mov	fpacc.Sign, 0
;
sl_ULTOF		endp
;
;
;
DoULTOF:
		mov	cx, 801Fh		;Magic exponent value (65536).
ULTOFWhlPos:	dec	cx
		shl	ax, 1
		rcl	dx, 1
		jnc	ULTOFWhlPos
		rcr	dx, 1			;Put bit back.
		rcr	ax, 1
		mov	fpacc.Exponent, cx	;Save exponent value.
		mov	fpacc.Mantissa [6], dx	;Save Mantissa value.
		mov	fpacc.Mantissa [4], ax
		xor	ax, ax			;Zero out the rest of the
		mov	fpacc.Mantissa [2], ax	; mantissa.
		mov	fpacc.Mantissa [0], ax
		jmp     ULTOFDone
;
; Special case for zero, must zero all bytes in FPACC.  Note that AX already
; contains zero.
;
SetUL0:		mov	fpacc.Exponent, ax
		mov	fpacc.Mantissa [6], ax
		mov	fpacc.Mantissa [4], ax
		mov	fpacc.Mantissa [2], ax
		mov	fpacc.Mantissa [0], ax
		mov	fpacc.Sign, al
;
ULTOFDone:	pop	dx
		pop	cx
		pop	ax
		pop	ds
		retf
;
;
;
;
; FTOI- Converts the floating point value in FPACC to a signed 16-bit
;	integer and returns this integer in AX.
;	Returns carry set if the number is too big to fit into AX.
;
		public	sl_FTOI
sl_FTOI		proc	far
		assume	ds:stdgrp
		push	ds
		push	cx
		mov	cx, StdGrp
		mov	ds, cx
;
		mov	cx, fpacc.Exponent
		cmp	cx, 800eh
		jb	FTOIok
;
; Handle special case of -32768:
;
		call	DoFToU
		cmp	ax, 8000h
		je	FtoiOk2
		stc
		jmp	TooBig
;
FTOIok:		call	DoFTOU
FtoiOk2:	cmp	fpacc.Sign, 0
		jns	FTOIJustRight
		neg	ax
FTOIJustRight:	clc
TooBig:		pop	cx
		pop	ds
		ret
sl_FTOI		endp
;
;
;
;
; FTOU- Like FTOI above, except this guy converts a floating point value
; 	to an unsigned integer in AX.
;	Returns carry set if out of range (including negative numbers).
;
		public	sl_FTOU
sl_FTOU		proc	far
		assume	ds:stdgrp
		push	ds
		push	cx
		mov	cx, StdGrp
		mov	ds, cx
;
		mov	cx, fpacc.Exponent
		cmp	cx, 800fh
		jb	FTOUok
BadU:		stc
		jmp	UTooBig
;
FTOUok:		call	DoFTOU
		cmp	fpacc.Sign, 0
		js	BadU
;
FTOUJustRight:	clc
UTooBig:	pop	cx
		pop	ds
		ret
sl_FTOU		endp
;
;
; DoFTOU- This code does the actual conversion!
;
DoFTOU		proc	near
		mov	ax, fpacc.Mantissa [6]
		cmp	cx, 7fffh
		jb	SetFTOU0
		sub	cx, 800eh
		neg	cx
		shr	ax, cl
		ret
;
SetFTOU0:	xor	ax, ax
		ret
DoFTOU		endp
;
;
;
;
;
; FTOL- Converts the floating point value in FPACC to a signed 32-bit
;	integer and returns this integer in DX:AX.
;	Returns carry set if the number is too big to fit into DX:AX.
;
		public	sl_FTOL
sl_FTOL		proc	far
		assume	ds:StdGrp
		push	ds
		push	cx
		mov	cx, StdGrp
		mov	ds, cx
;
		mov	cx, fpacc.Exponent
		cmp	cx, 801eh
		jb	FTOLok
		stc
		jmp	LTooBig
;
FTOLok:		call	DoFTOUL
		cmp	fpacc.Sign, 0
		jns	FTOLJustRight
		neg	dx    		;32-bit negate operation.
		neg	ax
		sbb	dx, 0
FTOLJustRight:	clc
LTooBig:	pop	cx
		pop	ds
		ret
sl_FTOL		endp
;
;
;
;
; FTOUL-Like FTOL above, except this guy converts a floating point value
; 	to a 32-bit unsigned integer in DX:AX.
;	Returns carry set if out of range (including negative numbers).
;
		public	sl_FTOUL
sl_FTOUL	proc	far
		assume	ds:StdGrp
		push	ds
		push	cx
		mov	cx, StdGrp
		mov	ds, cx
;
		mov	cx, fpacc.Exponent
		cmp	cx, 801fh
		jb	FTOULok
BadUL:		stc
		jmp	ULTooBig
;
FTOULok:	call	DoFTOUL
		cmp	fpacc.Sign, 0
		js	BadUL
;
		clc				;If the # is okay.
ULTooBig:	pop	cx
		pop	ds
		ret
sl_FTOUL	endp
;
;
; DoFTOUL- This code does the actual conversion!
;
DoFTOUL		proc	near
		mov	dx, fpacc.Mantissa [6]
		mov	ax, fpacc.Mantissa [4]
		cmp	cx, 7fffh
		jb	SetFTOUL0
		sub	cx, 801eh
		neg	cx
		jcxz	SetFTOULDone
FTOULLp:	shr	dx, 1
		rcr	ax, 1
		loop	FTOULLp
SetFToULDone:	ret
;
SetFTOUL0:	xor	ax, ax
		xor	dx, dx
		ret
DoFTOUL		endp
;
;
;
;
;
;
;
;
;
;
;
;
;
;---------------------------------------------------------------------------
;		Floating Point Addition & Subtraction
;---------------------------------------------------------------------------
;
;
;
;
; FADD- Adds FOP to FACC
; FSUB- Subtracts FOP from FACC
;	These routines destroy the value in FPOP!
;
		public	sl_fsub
		public	sl_fadd
;
		assume	ds:nothing
sl_fsub		proc	far
		xor	StdGrp:fpop.sign, 80h
sl_fsub		endp
;
		assume	ds:StdGrp
sl_fadd		proc	far
		push	ds
		push	ax
		push	bx
		push	cx
		push	dx
		push	si

; Use the current CS as the data segment to get direct access to
; the floating point accumulator and operands.

		mov	ax, StdGrp
		mov	ds, ax

; Kludge Alert!  Check to see if either operand is zero.  This code doesn't
; deal with zero very gracefully, so we have to specially check for zero
; here.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -