home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1987
/
12
/
mariella
/
isqrt32.asm
next >
Wrap
Assembly Source File
|
1987-12-21
|
6KB
|
166 lines
; ISQRT32.ASM - 32 bit integer test program for no 8087
; By Ray Mariella, March 87
page ,96
;
crlf macro
mov dl,13
call char_out
mov dl,10
call char_out
endm
;
time_print macro byte_var, byte_string
local plenty
mov dl,byte_string ;output a colon or period
call char_out
cmp byte_var,9
ja plenty
mov dl,'0' ;space holder if var<10
call char_out
plenty: mov al,byte_var ;minutes, secs, or hnds
xor ah,ah
call dec_out
endm
;
;
data segment word public 'DATA'
base dw 10 ;base for dec_out
uper db ? ;for time_print routine
secs db ?
hnds db ?
announc db ' 60000 32 bit square roots ',13,10,'$'
data ends
;
;
stack segment stack
dw 64 dup(?)
stack ends
;
;
code segment word public 'code'
assume cs:code, ds:data, ss:stack
;
sqrt: mov ax,data
mov ds,ax
crlf
mov dx,offset announc
mov ah,9 ;print string function
int 21h ;DOS interrrupt
mov dl,13
call char_out
;
herald: crlf
;
rolling: xor di,di ;upper 16
mov si,32767 ;lower 16
;
goodies: call update
;
; square root procedure of DI:SI via 8086,
;
start: mov bx,1 ;initial value for infimum
mov dx,di ;initial supremum, upper 16
mov ax,si ;initial supremum, lower 16
;
biggest: or dx,dx ;test if upper 16 =0 yet
jz words ;if yes, we don't need upper 16 now
rcr dx,1 ;supr. upper 16/2
rcr ax,1 ;supr. lower 16/2 + carry from upper
shl bx,1 ;infim.*2
jmp short biggest
;now infim. and supr. are 16 bits
words: or bx,bx ;if BX was made 0, correct it!
jnz checkem ;if not, O.K. to continue
mov bx,0ffffh ;correction for the largest 32 bitters
checkem: mov dx,ax ;supr. in ax,dx
mov cx,bx ;infim. in bx,cx
;
logit: shl cx,1 ;infimum*2
jc average ;necessary for large integers
cmp cx,dx ;infimum*2 > supremum?
jae average ;if so, ready to average
shr dx,1 ;if not, supr/2
mov ax,dx ;store latest values
mov bx,cx
jmp short logit
;ready for averaging
average:
add bx,ax ;(infim.+ supr.)
rcr bx,1 ;average value for first guess
Newton:
REPT 2
mov ax,si ;lower 16 of target in ax,
mov dx,di ;upper 16 of in dx, for division
; cmp bx,dx ;this is for near FFFE:0000 and up
; je cont ;but not needed for FFFD:0000 and less
div bx ;N/(g1) in AX, now get g2
add bx,ax ;Newton's method g2 = (g1 +N/g1)/2
rcr bx,1 ;bx now has g2
endm
;
cont: inc di
cmp di, 60000
ja quit
jmp start
;
quit: call update
xor al,al
mov ah,4Ch
int 21h
;
; output a hex word in decimal
;
; CX,AX,DX destroyed
;
dec_out proc near
xor cx,cx
another: inc cx
xor dx,dx
div base ;base is 10 decimal!
push dx ;remainder is less sig digits
or ax,ax ;is the quotient zero?
jnz another ;if not, more number to convert
print_dig:
pop dx ;retrive digit from stack
add dl,'0' ;ascii offset
call char_out
loop print_dig ;do all of the digits
ret
dec_out endp
;
; output a single character
;
char_out proc near
mov ah,2 ;output char function
int 21h ;do it
ret
char_out endp
;
;
update proc near
mov ah,2ch ;get dos time
int 21h ;hour in ch, mins in cl,secs in dh
mov uper,cl
mov secs,dh
mov hnds,dl
mov al,ch
xor ah,ah
call dec_out
;
time_print uper,':'
;
time_print secs,':'
;
time_print hnds,'.'
;
crlf
ret
update endp
;
code ends
end sqrt