home *** CD-ROM | disk | FTP | other *** search
- ; 3X+1 solver using FREELIB
-
- Ideal
-
- Public main
- Extrn startup:near
-
- Macro lcall p,a,b,c,d,e,f,g,h ;; library call
-
- ifnb <a>
- push a ;; if args, push first arg
- lcall p,b,c,d,e,f,g,h ;; and recurse . . .
- else
- extrn p:near ;; declare procedure
- call p ;; call procedure
- endif
-
- EndM
-
- Model Tiny
- CodeSeg
- P186
- Org 100h
-
- Start: jmp startup
-
- ;****************** Data Section
-
- rtn db 13,0
- buf db 15 dup(0)
- BadFmt db 13,10,13,10,'Number %d went out of range',13,10,0
- BadArg dw ?,?
- OkStr db 'No anomaly found',0
-
- ;****************** 'main' procedure
-
- Proc main
-
- mov ax,3 ;Start with 3
- xor dx,dx
-
- MLoop: pusha ;Save all registers
- mov bp,dx ;CX:BX:AX = number
- mov bx,dx ;BP = threshold
- xor cx,cx
-
- CLoop: test cx,cx ;Out of range, quit
- jl Quit
- jnz CCont
- cmp bx,bp ;CX = 0, check if less
- jb CDone ;Quit if less than the
- test bx,bx ;original number
- jz CDone
-
- CCont: test ax,1 ;Check for odd
- jz CSkip
-
- mov dx,ax ;N = 3 * N + 1
- add ax,ax
- mov si,bx
- adc bx,bx
- mov di,cx
- adc cx,cx
- add ax,dx
- adc bx,si
- adc cx,di
- add ax,1
- adc bx,0
- adc cx,0
-
- CSkip: shr cx,1 ;N = N / 2
- rcr bx,1
- rcr ax,1
- jmp CLoop ;Loop back
-
- CDone: popa ;Restore all registers
-
- cmp ax,3 ;Low word = 3, display
- jne MSkip
-
- lcall ltoa dx,ax,offset(buf) ;Display the number
- lcall puts offset(buf)
- lcall puts offset(rtn)
-
- MSkip: add ax,4 ;Add 4 (increment)
- adc dx,0
- cmp dx,230 ;Loop while < 15 million
- jb MLoop
-
- lcall puts offset(OkStr) ;Print OK message
- ret ;Return
-
- Quit: popa ;Overflowed...
- mov [BadArg],ax ;Print out-of-range message
- mov [BadArg+2],dx
- lcall printf offset(BadFmt),offset(BadArg)
- ret ;Return
-
- EndP main
-
- End Start