home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / math / div_f.asm < prev    next >
Assembly Source File  |  1986-01-17  |  6KB  |  128 lines

  1. ;*************************************************************
  2. ;                        FLOATING POINT
  3. ;                       DIVISION ROUTINE
  4. ;*************************************************************
  5. DIV_F    PROC     NEAR
  6.          PUSH     SI              ;save index registers
  7.          PUSH     DI
  8. ;                             divide by zero?
  9.          MOV      DX,[SI]         ;get op2 (divisor) in CX:DX
  10.          MOV      CX,[SI]+2
  11.          MOV      BX,10           ;set error flag
  12.          MOV      AX,DX           ;is op2 zero?
  13.          OR       AX,CX
  14.          JNZ      D1              ;if zero, quit with BX=10
  15.          JMP      EXIT
  16. ;                           compute result sign
  17. D1:      MOV      AL,CL           ;OP1 high byte in AL
  18.          XOR      AL,[DI]+2       ;XOR with OP2 high byte
  19.          AND      AX,0080H        ;isolate sign bit
  20.          PUSH     AX              ;save it
  21. ;                           compute exponent
  22.          SUB      AX,AX
  23.          MOV      BX,AX
  24.          MOV      AL,CH           ;E2 in AX
  25.          MOV      BL,[DI]+3       ;E1 in BX
  26.          SUB      AX,128          ;remove bias
  27.          SUB      BX,AX           ;E1-E2
  28.          INC      BX              ;add 1 since shift right later
  29. ;
  30.          CMP      BX,255          ;overflow if
  31.          JLE      D3              ;E>255
  32.          JMP      D13
  33. ;
  34. D3:      CMP      BX,0            ;underflow if
  35.          JGE      D5              ;E<0
  36.          JMP      D14
  37. ;                            compute 1-(OP2LO/OP2HI)/2^16
  38. D5:      PUSH     BX              ;save E in BL
  39.          SUB      AX,AX
  40.          MOV      BH,CL           ;OP2HI in BX
  41.          MOV      BL,DH
  42.          OR       BH,10000000B    ;restore leading 1  
  43.          MOV      DH,DL           ;OP2LO in DX           
  44.          MOV      DL,AL
  45.          OR       DX,DX           ;if OP2LO is zero
  46.          JNZ      D6
  47.          XCHG     BX,AX           ;put OP2HI in AX   
  48.          MOV      SI,BX           ;set result in BX:SI to zero
  49.          JMP SHORT D8             ;and skip this step
  50. ;                             compute OP2LO/OP2HI first
  51. D6:      SUB      CX,CX
  52.          CMP      DX,BX           ;if OP2LO>=OP2HI, quotient>=1
  53.          JB       D7                   
  54.          SUB      DX,BX           ;subtract OP2HI to prevent overflow
  55.          MOV      CX,1            ;save quotient 1 or 0 in CX
  56. ;
  57. D7:      DIV      BX              ;OP2LO/OP2HI now in CX:AX
  58. ;         
  59.          PUSH     CX              ;save OP2LO/OP2HI
  60.          PUSH     AX
  61.          SUB      AX,AX           ;divide remainder in DX:AX
  62.          DIV      BX
  63.          POP      DX
  64.          POP      CX              ;OP2LO/OP2HI in CX:DX:AX
  65. ;                            subtract it from 1
  66.          PUSH     DI              ;save DI & OP2HI
  67.          PUSH     BX
  68.          SUB      DI,DI           ;clear registers
  69.          MOV      SI,DI
  70.          MOV      BX,DI
  71.          SUB      DI,AX
  72.          SBB      SI,DX
  73.          SBB      BX,CX
  74.          POP      AX              ;retrieve OP2HI & DI
  75.          POP      DI
  76. ;                            compute OP1/OP2HI
  77. D8:      PUSH     BX              ;save 1-OP1LO/OP2HI
  78.          PUSH     SI
  79.          MOV      BX,AX           ;OP2HI in BX
  80.          SUB      AX,AX           ;clear AX & SI
  81.          MOV      SI,AX
  82.          MOV      DX,[DI]+1       ;OP1 in DX:AX
  83.          OR       DH,10000000B    ;restore leading 1
  84.          MOV      AH,[DI]
  85. ;
  86.          CMP      DX,BX           ;if OP1>=OP2HI
  87.          JB       D9
  88.          SUB      DX,BX           ;subtract OP2HI to prevent overflow
  89.          INC      SI              ;and save quotient of one in SI
  90. ;
  91. D9:      DIV      BX              ;divide OP1/OP2HI
  92.          MOV      CX,AX           ;save quotient in CX
  93.          SUB      AX,AX
  94.          DIV      BX              ;divide remainder in DX
  95.          MOV      DX,CX           ;OP1/OP2HI now in SI:DX:AX
  96.          SHR      SI,1            ;shift it right 
  97.          RCR      DX,1
  98.          RCR      AX,1            ;now in DX:AX
  99. ;                            compute (OP1/OP2HI)*(OP2LO/OP2HI)/2^16
  100.          POP      BX              ;1-OP2LO/OP2H9)/2^16 in CX:BX
  101.          POP      CX
  102.          MOV      SI,BX           ;if OP2LP/OP2HI was zero
  103.          OR       SI,CX           ;product is OP1/OP2HI
  104.          JZ       D10             ;so no need to multiply
  105.          CALL     MUL32           ;do the multiplication
  106. ;                            normalize
  107. D10:     POP      BX              ;get exponent in BX
  108. D11:     OR       DX,DX
  109.          JS       D12             ;if sign bit off
  110.          SHL      CX,1            ;shift it left
  111.          RCL      AX,1
  112.          RCL      DX,1
  113.          DEC      BX              ;decrement exponent
  114.          JMP      D11             ;see if normalized
  115. ;                            reformat for output
  116. D12:     MOV      BH,BL           ;exponent in BH
  117.          XCHG     AH,AL           ;move trailing bits up to DH
  118.          XCHG     DL,AH           ;4 byte mantissa in DL:AX:DH
  119.          XCHG     DH,DL
  120.          SUB      CX,CX
  121.          POP      DI              ;result sign in DI
  122.          JMP      R0              ;ROUND in addition routine
  123. ;
  124. D13:     POP      DI              ;get sign in DI
  125.          JMP      OVER_F
  126. D14:     POP      AX              ;remove sign from stack
  127.          JMP      UNDER_F
  128. DIV_F    ENDP