home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Graphics Programming Black Book (Special Edition)
/
BlackBook.bin
/
disk1
/
source
/
chapter52
/
xsharp14.exe
/
L9.ASM
< prev
next >
Wrap
Assembly Source File
|
1994-12-17
|
3KB
|
73 lines
; 386-specific fixed point multiply and divide.
; C near-callable as:
; Fixedpoint FixedMul(Fixedpoint M1, Fixedpoint M2);
; Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor);
; Tested with TASM 4.0.
.model small
.386
.code
public _FixedMul,_FixedDiv
; Multiplies two fixed-point values together.
FMparms struc
dw 2 dup(?) ;return address & pushed BP
M1 dd ?
M2 dd ?
FMparms ends
align 2
_FixedMul proc near
push bp
mov bp,sp
mov eax,[bp+M1]
imul dword ptr [bp+M2] ;multiply
add eax,8000h ;round by adding 2^(-16)
adc edx,0 ;whole part of result is in DX
shr eax,16 ;put the fractional part in AX
pop bp
ret
_FixedMul endp
; Divides one fixed-point value by another.
FDparms struc
dw 2 dup(?) ;return address & pushed BP
Dividend dd ?
Divisor dd ?
FDparms ends
align 2
_FixedDiv proc near
push bp
mov bp,sp
sub cx,cx ;assume positive result
mov eax,[bp+Dividend]
and eax,eax ;positive dividend?
jns FDP1 ;yes
inc cx ;mark it's a negative dividend
neg eax ;make the dividend positive
FDP1: sub edx,edx ;make it a 64-bit dividend, then shift
; left 16 bits so that result will be
; in EAX
rol eax,16 ;put fractional part of dividend in
; high word of EAX
mov dx,ax ;put whole part of dividend in DX
sub ax,ax ;clear low word of EAX
mov ebx,dword ptr [bp+Divisor]
and ebx,ebx ;positive divisor?
jns FDP2 ;yes
dec cx ;mark it's a negative divisor
neg ebx ;make divisor positive
FDP2: div ebx ;divide
shr ebx,1 ;divisor/2, minus 1 if the divisor is
adc ebx,0 ; even
dec ebx
cmp ebx,edx ;set Carry if remainder is at least
adc eax,0 ; half as large as the divisor, then
; use that to round up if necessary
and cx,cx ;should the result be made negative?
jz FDP3 ;no
neg eax ;yes, negate it
FDP3: mov edx,eax ;return result in DX:AX; fractional
; part is already in AX
shr edx,16 ;whole part of result in DX
pop bp
ret
_FixedDiv endp
end