home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS - Coast to Coast / simteldosarchivecoasttocoast.iso / pcmag / vol7n03.zip / PP703.ZIP / ATOL.ASM < prev    next >
Assembly Source File  |  1987-12-15  |  3KB  |  107 lines

  1.         name    atol
  2.         page    55,132
  3.         title   ATOL - ASCII to long integer
  4.  
  5. ;
  6. ; ATOL.ASM - convert ASCII string to 
  7. ;            long (32-bit) decimal integer.
  8. ;
  9. ;  Copyright 1987, Ziff Communications Co.
  10. ;  Ray Duncan
  11. ;
  12. ; Call with:    DS:SI = address of string
  13. ;
  14. ;               where 'string' is in the form
  15. ;               
  16. ;                  [whitespace][sign][digits]
  17. ;
  18. ; Returns:      DX:AX = result (high word in DX)
  19. ;               DS:SI = address+1 of terminator 
  20. ;
  21. ;               other registers preserved
  22. ;
  23. ; Like the C library 'atol', this routine gives no 
  24. ; warning in the event of overflow, and terminates 
  25. ; on the first invalid character.
  26. ;
  27.  
  28. blank   equ     20h             ; ASCII blank character
  29. tab     equ     09h             ; ASCII tab character
  30.  
  31. _TEXT   segment word public 'CODE'
  32.  
  33.         assume  cs:_TEXT
  34.  
  35.         public  atol
  36. atol    proc    near            ; ASCII to 32-bit integer
  37.  
  38.         push    bx              ; save registers
  39.         push    cx
  40.         push    di
  41.  
  42.         xor     bx,bx           ; initialize forming answer
  43.         xor     dx,dx           ; in DX:BX
  44.         xor     cx,cx           ; initialize sign flag
  45.  
  46. atol1:  lodsb                   ; scan off whitespace
  47.         cmp     al,blank        ; ignore leading blanks
  48.         je      atol1
  49.         cmp     al,tab          ; ignore leading tabs
  50.         je      atol1
  51.  
  52.         cmp     al,'+'          ; if + sign proceed
  53.         je      atol2
  54.         cmp     al,'-'          ; is it - sign?
  55.         jne     atol3           ; no, test if numeric
  56.         dec     cx              ; was - sign, set flag
  57.                                 ; for negative result
  58.  
  59. atol2:  lodsb                   ; get next character
  60.  
  61. atol3:  cmp     al,'0'          ; is character valid?
  62.         jb      atol4           ; jump if not '0' to '9'
  63.         cmp     al,'9'
  64.         ja      atol4           ; jump if not '0' to '9'
  65.  
  66.         and     ax,0fh          ; isolate lower four bits
  67.         push    ax              ; and save digit value
  68.  
  69.         mov     ax,bx           ; previous answer x 10
  70.         mov     di,dx           ; DI:AX = copy of DX:BX
  71.  
  72.         add     bx,bx           ; * 2
  73.         adc     dx,dx
  74.  
  75.         add     bx,bx           ; * 4
  76.         adc     dx,dx
  77.  
  78.         add     bx,ax           ; * 5
  79.         adc     dx,di
  80.  
  81.         add     bx,bx           ; * 10
  82.         adc     dx,dx
  83.  
  84.         pop     ax              ; add this digit
  85.         add     bx,ax           ; to forming answer
  86.         adc     dx,0
  87.         
  88.         jmp     atol2           ; convert next digit
  89.  
  90. atol4:  mov     ax,bx           ; result low half to AX
  91.         jcxz    atol5           ; jump if sign flag clear
  92.  
  93.         not     ax              ; take 2's complement
  94.         not     dx              ; of DX:AX
  95.         add     ax,1
  96.         adc     dx,0
  97.  
  98. atol5:  pop     di              ; restore registers
  99.         pop     cx
  100.         pop     bx
  101.         ret                     ; back to caller
  102.  
  103. atol    endp
  104.  
  105. _TEXT   ends
  106.         end
  107.