home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1987 / 12 / mariella / isqrt32.asm next >
Assembly Source File  |  1987-12-21  |  6KB  |  166 lines

  1. ;         ISQRT32.ASM - 32 bit integer test program for no 8087
  2. ;         By Ray Mariella, March 87
  3.            page    ,96
  4. ;
  5. crlf      macro
  6.           mov    dl,13
  7.           call   char_out
  8.           mov    dl,10
  9.           call   char_out
  10.           endm
  11. ;
  12. time_print macro byte_var, byte_string
  13.           local plenty
  14.           mov    dl,byte_string             ;output a colon or period
  15.           call   char_out
  16.           cmp    byte_var,9
  17.           ja     plenty
  18.           mov    dl,'0'                     ;space holder if var<10
  19.           call   char_out
  20. plenty:   mov    al,byte_var                ;minutes, secs, or hnds
  21.           xor    ah,ah
  22.           call   dec_out
  23.           endm
  24. ;
  25. ;
  26. data      segment  word public 'DATA'
  27. base             dw  10                       ;base for dec_out
  28. uper             db  ?                        ;for time_print routine
  29. secs             db  ?
  30. hnds             db  ?
  31. announc          db  ' 60000   32 bit square roots ',13,10,'$'
  32. data      ends
  33. ;
  34. ;
  35. stack     segment   stack
  36.                  dw  64  dup(?)       
  37. stack     ends
  38. ;
  39. ;
  40. code      segment  word public 'code'
  41.           assume cs:code, ds:data, ss:stack
  42. ;
  43. sqrt:     mov    ax,data
  44.           mov    ds,ax
  45. crlf
  46.           mov    dx,offset announc
  47.           mov    ah,9                    ;print string function
  48.           int    21h                     ;DOS interrrupt
  49.           mov    dl,13
  50.           call   char_out
  51. ;
  52. herald:   crlf
  53. ;
  54. rolling:  xor    di,di                  ;upper 16
  55.           mov    si,32767               ;lower 16 
  56. ;        
  57. goodies:  call  update
  58. ;
  59. ;      square root procedure of DI:SI via 8086, 
  60. ;
  61. start:    mov    bx,1                   ;initial value for infimum
  62.           mov    dx,di                  ;initial supremum, upper 16
  63.           mov    ax,si                  ;initial supremum, lower 16
  64.                                         ;
  65. biggest:  or     dx,dx                  ;test if upper 16 =0 yet
  66.           jz     words                  ;if yes, we don't need upper 16 now
  67.           rcr    dx,1                   ;supr. upper 16/2
  68.           rcr    ax,1                   ;supr. lower 16/2 + carry from upper
  69.           shl    bx,1                   ;infim.*2
  70.           jmp    short biggest
  71.                                         ;now infim. and supr. are 16 bits
  72. words:    or     bx,bx                  ;if BX was made 0, correct it!
  73.           jnz    checkem                ;if not, O.K. to continue
  74.           mov    bx,0ffffh              ;correction for the largest 32 bitters
  75. checkem:  mov    dx,ax                  ;supr. in ax,dx
  76.           mov    cx,bx                  ;infim. in bx,cx
  77.                                         ;
  78. logit:    shl    cx,1                   ;infimum*2
  79.           jc     average                ;necessary for large integers
  80.           cmp    cx,dx                  ;infimum*2 > supremum?
  81.           jae    average                ;if so, ready to average
  82.           shr    dx,1                   ;if not, supr/2
  83.           mov    ax,dx                  ;store latest values
  84.           mov    bx,cx
  85.           jmp    short logit
  86.                                         ;ready for averaging
  87. average:
  88.           add    bx,ax                  ;(infim.+ supr.)
  89.           rcr    bx,1                   ;average value for first guess
  90. Newton:   
  91.           REPT 2
  92.           mov    ax,si             ;lower 16 of target in ax,
  93.           mov    dx,di             ;upper 16 of in dx, for division
  94. ;         cmp    bx,dx             ;this is for near FFFE:0000 and up
  95. ;         je     cont              ;but not needed for FFFD:0000 and less
  96.           div    bx                ;N/(g1) in AX, now get g2
  97.           add    bx,ax             ;Newton's method   g2 = (g1 +N/g1)/2
  98.           rcr    bx,1              ;bx now has g2
  99.           endm
  100. ;
  101. cont:     inc    di
  102.           cmp    di, 60000
  103.           ja     quit
  104.           jmp    start
  105. ;
  106. quit:     call   update
  107.           xor    al,al
  108.           mov    ah,4Ch
  109.           int    21h
  110. ;
  111. ;         output a hex word in decimal
  112. ;
  113. ;         CX,AX,DX destroyed
  114. ;
  115. dec_out   proc   near
  116.           xor    cx,cx
  117. another:  inc    cx
  118.           xor    dx,dx
  119.           div    base                   ;base is 10 decimal!
  120.           push   dx                     ;remainder is less sig digits
  121.           or     ax,ax                  ;is the quotient zero?
  122.           jnz    another                ;if not, more number to convert
  123. print_dig:
  124.           pop    dx                     ;retrive digit from stack
  125.           add    dl,'0'                 ;ascii offset
  126.           call   char_out
  127.           loop   print_dig              ;do all of the digits
  128.           ret
  129. dec_out   endp
  130. ;
  131. ;         output a single character
  132. ;
  133. char_out  proc   near
  134.           mov    ah,2                   ;output char function
  135.           int    21h                    ;do it
  136.           ret
  137. char_out  endp
  138. ;
  139. ;
  140. update    proc  near
  141.           mov    ah,2ch                 ;get dos time
  142.           int    21h                    ;hour in ch, mins in cl,secs in dh
  143.           mov    uper,cl
  144.           mov    secs,dh
  145.           mov    hnds,dl
  146.           mov    al,ch
  147.           xor    ah,ah
  148.           call   dec_out
  149. ;
  150.           time_print uper,':'
  151. ;
  152.           time_print secs,':'
  153. ;
  154.           time_print hnds,'.'
  155. ;
  156.           crlf
  157.           ret
  158. update    endp
  159. ;
  160. code      ends
  161.           end    sqrt
  162.  
  163.  
  164.  
  165.  
  166.