home *** CD-ROM | disk | FTP | other *** search
/ Graphics Programming Black Book (Special Edition) / BlackBook.bin / disk1 / source / chapter52 / xsharp14.exe / L9.ASM < prev    next >
Assembly Source File  |  1994-12-17  |  3KB  |  73 lines

  1. ; 386-specific fixed point multiply and divide.
  2. ; C near-callable as:
  3. ;       Fixedpoint FixedMul(Fixedpoint M1, Fixedpoint M2);
  4. ;       Fixedpoint FixedDiv(Fixedpoint Dividend, Fixedpoint Divisor);
  5. ; Tested with TASM 4.0.
  6.         .model small
  7.         .386
  8.         .code
  9.         public  _FixedMul,_FixedDiv
  10. ; Multiplies two fixed-point values together.
  11. FMparms struc
  12.         dw      2 dup(?)        ;return address & pushed BP
  13. M1      dd      ?
  14. M2      dd      ?
  15. FMparms ends
  16.         align   2
  17. _FixedMul       proc    near
  18.         push    bp
  19.         mov     bp,sp
  20.         mov     eax,[bp+M1]
  21.         imul    dword ptr [bp+M2] ;multiply
  22.         add     eax,8000h       ;round by adding 2^(-16)
  23.         adc     edx,0           ;whole part of result is in DX
  24.         shr     eax,16          ;put the fractional part in AX
  25.         pop     bp
  26.         ret
  27. _FixedMul       endp
  28. ; Divides one fixed-point value by another.
  29. FDparms struc
  30.         dw      2 dup(?)        ;return address & pushed BP
  31. Dividend dd     ?
  32. Divisor  dd     ?
  33. FDparms ends
  34.         align   2
  35. _FixedDiv       proc    near
  36.         push    bp
  37.         mov     bp,sp
  38.         sub     cx,cx           ;assume positive result
  39.         mov     eax,[bp+Dividend]
  40.         and     eax,eax         ;positive dividend?
  41.         jns     FDP1            ;yes
  42.         inc     cx              ;mark it's a negative dividend
  43.         neg     eax             ;make the dividend positive
  44. FDP1:   sub     edx,edx         ;make it a 64-bit dividend, then shift
  45.                                 ; left 16 bits so that result will be
  46.                                 ; in EAX
  47.         rol     eax,16          ;put fractional part of dividend in
  48.                                 ; high word of EAX
  49.         mov     dx,ax           ;put whole part of dividend in DX
  50.         sub     ax,ax           ;clear low word of EAX
  51.         mov     ebx,dword ptr [bp+Divisor]
  52.         and     ebx,ebx         ;positive divisor?
  53.         jns     FDP2            ;yes
  54.         dec     cx              ;mark it's a negative divisor
  55.         neg     ebx             ;make divisor positive
  56. FDP2:   div     ebx             ;divide
  57.         shr     ebx,1           ;divisor/2, minus 1 if the divisor is
  58.         adc     ebx,0           ; even
  59.         dec     ebx
  60.         cmp     ebx,edx         ;set Carry if remainder is at least
  61.         adc     eax,0           ; half as large as the divisor, then
  62.                                 ; use that to round up if necessary
  63.         and     cx,cx           ;should the result be made negative?
  64.         jz      FDP3            ;no
  65.         neg     eax             ;yes, negate it
  66. FDP3:   mov     edx,eax         ;return result in DX:AX; fractional
  67.                                 ; part is already in AX
  68.         shr     edx,16          ;whole part of result in DX
  69.         pop     bp
  70.         ret
  71. _FixedDiv       endp
  72.         end
  73.