home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 June / SIMTEL_0692.cdr / msdos / sysutl / convrt12.arc / CONVRT12.ASM < prev   
Encoding:
Assembly Source File  |  1989-11-29  |  26.6 KB  |  557 lines

  1. ;---------------------------------------------------------------;
  2. ;  Convert.com - Converts either a number or character          ;
  3. ;  to complementary radices.                                    ;
  4. ;  Decimal, Hexadecimal, Octal and Binary supported; ASCII too. ;
  5. ;  PC Magazine * Michael J. Mefford                             ;
  6. ;---------------------------------------------------------------;
  7. ;
  8. ; v1.2 (TapirSoft Gisbert W.Selke):
  9. ; - expanded to accept 32 bit unsigned integers
  10. ;
  11. ; v1.1 (TapirSoft Gisbert W.Selke)
  12. ; - fixed a bug that screwed up hex input containing the digit B
  13.  
  14. _Text          segment public 'CODE'
  15.                assume  cs:_Text,ds:_Text,es:_Text,ss:_Text
  16.                org     100H
  17. Start:         jmp     Main
  18.  
  19. ;              DATA AREA
  20. ;              ---------
  21. Syntax         db      CR
  22. Copyright      db      "CONVERT 1.2 (C) 1989 Ziff Communications Co.",CR,LF
  23. Programmer     db      "PC Magazine ",BOX," Michael J. Mefford"
  24.                db      "/TapirSoft Gisbert W.Selke",CR,LF,LF
  25.  
  26.                db      "Usage:  CONVERT <from>[-<to>] | "
  27.                db      Quotes,"<char(s)>",Quotes,CR,LF
  28.                db      "numbers may have radix (one of b,d,h,o) appended; "
  29.                db      "default is d"
  30.                db      Ctrl_Z,Backspace,Blank,'$'
  31.  
  32. Backspace      equ     8
  33. Tab            equ     9
  34. CR             equ     13
  35. LF             equ     10
  36. Ctrl_Z         equ     26
  37. Blank          equ     ' '
  38. Quotes         equ     34
  39. Box            equ     254
  40. Space_Cnt      equ     5
  41.  
  42. Invalid_Msg    db      "Invalid parameter; number range: 0..4294967295"
  43.                db      CR,LF,"$"
  44.  
  45. Radix_Type     db      "HOB"                   ;Hex, octal, binary.
  46. Radix_Cnt      equ     $ - Radix_Type
  47.  
  48. Input_Calls    dw      Decimal_Input, Hex_Input, Octal_Input, Binary_Input
  49. CALLS_end      equ     $ - 2
  50.  
  51. ;
  52. ;              CODE AREA
  53. ;              ---------
  54.  
  55. Main           proc    near
  56.                cld                             ;All string moves forward.
  57.                cmp     byte ptr ds:[80H],0     ;Are there parameters?
  58.                jnz     Parse                   ;If yes, continue.
  59.                jmp     Error_Exit              ;Else, exit with syntax message.
  60.  
  61. ;------------------------------------------------------------------------------;
  62. ; Parse the parameters by looking for either carriage return, quotes, or dash. ;
  63. ;------------------------------------------------------------------------------;
  64. Parse:         mov     si,82H                  ;Point to parameters again.
  65. Next_Input:    mov     bp,si                   ;parameter start.
  66. NEXT_PARSE:    lodsb                           ;Get a byte.
  67.                cmp     al,CR                   ;Is it carriage return?
  68.                jz      Evaluate                ;If yes, done here.
  69.                cmp     al,Quotes               ;Is it quotes?
  70.                jz      Character               ;If yes, character entry.
  71.                cmp     al,"-"                  ;Is it delimiting dash?
  72.                jnz     Next_Parse              ;If no, find parameter end.
  73.                cmp     bp,82H                  ;Else, is this first dash?
  74.                jnz     Evaluate                ;If no, evaluate just the two.
  75.                push    si                      ;Save our position.
  76.                call    Get_Number              ;Get the parameter.
  77.                pop     si                      ;Restore our position.
  78.                push    bx                      ;Save the number.
  79.                push    dx
  80.                jmp     short Next_Input        ;Get second parameter.
  81.  
  82. ;-----------------------------------------------------------------------;
  83. ; If quotes were detected, store up to four characters to be evaluated. ;
  84. ;-----------------------------------------------------------------------;
  85. Character:     xor     bx,bx                   ;Assume no characters.
  86.                xor     dx,dx
  87. Character1:    lodsb                           ;Get a byte.
  88.                cmp     al,CR                   ;End of parameter?
  89.                jz      Got_Char
  90.                cmp     al,Quotes               ;Is it quotes?
  91.                jnz     Character2              ;If no, valid character.
  92.                cmp     byte ptr [si],Quotes    ;Is it followed by quotes?
  93.                jnz     Got_Char                ;If no, not quotes in quotes.
  94.                inc     si                      ; skip 2nd quotes
  95. Character2:    or      dh,dh                   ; overflow?
  96.                jnz     Error_Exit              ; if yes, error exit
  97.                mov     dh,dl                   ; shift new letter in
  98.                mov     dl,bh
  99.                mov     bh,bl
  100.                mov     bl,al
  101.                jmp short Character1            ; netx character
  102.  
  103. Got_Char:      mov     ax,bx                   ;duplicate argument
  104.                mov     cx,dx
  105.                jmp     short Output            ;Convert the string
  106.  
  107. ;-------------------------------------------------------------;
  108. ; Find range of numbers and display the complementry radices. ;
  109. ;-------------------------------------------------------------;
  110. Evaluate:      call    Get_Number              ;Get the parameter.
  111.                mov     ax,bx                   ; and save it
  112.                mov     cx,dx
  113.                cmp     bp,82H                  ;Where there more than one?
  114.                jz      Output                  ;If no, convert just the one.
  115.                pop     cx                      ;Else, retrieve the first one.
  116.                pop     ax
  117.                cmp     cx,dx                   ;Is it the larger of the two?
  118.                ja      Output                  ;If yes, find range.
  119.                jb      Swap_Range
  120.                cmp     ax,bx
  121.                jae     Output
  122. Swap_Range:    xchg    dx,cx                   ;Else, swap numbers.
  123.                xchg    bx,ax
  124.  
  125. Output:        push    ax                      ; Save upper limit
  126.                push    cx
  127.                xor     si,si                   ; si=0: 4-byte; si=1: 2-byte form
  128.                or      cx,cx
  129.                jne     Output1
  130.                inc     si
  131. Output1:       call    Decimal_Output          ; Display decimal, hexadecimal,
  132.                call    Space_It                ; octal and binary equivalents
  133.                call    Hex_Output              ; with spaces in between.
  134.                call    Spacing
  135.                call    Octal_Output
  136.                call    Spacing
  137.                call    Binary_Output
  138.                call    Spacing
  139.                call    Ascii_Output
  140.                mov     al,CR
  141.                call    PRINT_Char
  142.                mov     al,LF
  143.                call    Print_Char
  144.                add     bx,1                    ; Get ready for next number.
  145.                adc     dx,0
  146.                pop     cx                      ; get back upper limit
  147.                pop     ax
  148.                cmp     dx,cx                   ; are we through?
  149.                jb      Output                  ; no -> loop
  150.                ja      Output2                 ; yes -> exit
  151.                cmp     bx,ax                   ; maybe; another test...
  152.                jbe     Output                  ; no after all; loop
  153.  
  154. Output2:       xor     al,al                   ;Exit with ErrorLevel of zero.
  155.                jmp     short Exit
  156.  
  157. ;---------------------------------------------------------------------------;
  158. ; Exit with syntax message and ErrorLevel of 1 if error, else ErrorLevel 0. ;
  159. ;---------------------------------------------------------------------------;
  160. Error_Exit:    mov     dx,offset Syntax        ;Display syntax.
  161.                mov     ah,9
  162.                int     21h
  163.                mov     al,1                    ; ErrorLevel 1
  164. Exit:          mov     ah,4CH
  165.                int     21H                     ; Terminate.
  166. Main           endp
  167.  
  168. ;              *************
  169. ;              *SUBROUTINES*
  170. ;              *************
  171.  
  172. ;------------------------------------------------------------------------------;
  173. ; INPUT:  SI points to byte after parameter end; BP points to parameter start. ;
  174. ; OUTPUT: DX:BX = number.                                                      ;
  175. ; CALLS:  Decimal_Input, Hex_Input, Octal_Input, Binary_Input.                 ;
  176. ;------------------------------------------------------------------------------;
  177. Get_Number     proc    near
  178.                dec     si                      ;Adjust pointer to parameter end.
  179.                mov     cx,si                   ;Save SI.
  180.                mov     si,bp                   ;Point to parameter start.
  181.                xor     ah,ah                   ; initialize radix to default
  182. Next_Cap:      cmp     si,cx                   ;Are we at end of parameter?
  183.                jz      String_Length           ;If yes, done here.
  184.                lodsb                           ;Get a byte.
  185.                cmp     al,Blank                ; skip blanks
  186.                jz      Next_Cap
  187.                cmp     al,Tab                  ; skip tabs
  188.                jz      Next_Cap
  189.                cmp     al,'a'                  ; need to capitalize?
  190.                jb      Next_Cap1
  191.                cmp     al,'z'
  192.                ja      Next_Cap1
  193.                and     al,5Fh
  194.                mov     byte ptr[si-1],al
  195. Next_Cap1:     mov     ah,al                   ; tentatively jot down radix
  196.                jmp short Next_Cap
  197.  
  198. String_Length: mov     si,bp                   ;Point to parameter start.
  199.                sub     cx,bp                   ;Find parameter length.
  200.                push    cx                      ;Save it.
  201.  
  202. Next_Radix:    mov     cx,Radix_Cnt            ; Count of radices in CX.
  203.                mov     di,offset Radix_Type    ; Point to radix collection
  204.                mov     al,ah                   ; retrieve possible radix
  205.                repnz   scasb                   ; Is it one?
  206.                jz      Input                   ;If yes, evaluate.
  207.                mov     cx,Radix_Cnt            ;default radix
  208.  
  209. Input:         shl     cx,1                    ;Convert count to word pointer.
  210.                mov     di,offset Calls_End     ;Point to input calls end.
  211.                sub     di,cx                   ;Point to appropriate call.
  212.                pop     cx                      ;Retrieve parameter length.
  213.                mov     si,bp                   ;Point to parameter start.
  214.                xor     bx,bx                   ;Start with a zero number.
  215.                xor     dx,dx
  216.                call    [di]                    ;Get the number.
  217.                jnc     End_Number
  218.                mov     dx,offset Invalid_Msg   ;Print error message if invalid
  219.                mov     ah,9
  220.                int     21h
  221.                jmp     short Error_Exit
  222. End_Number:    ret                             ;Else, return with number in BX.
  223. Get_Number     endp
  224.  
  225. ;----------------------------------------------------------------------;
  226. ; INPUT:  SI points to parameter start; CX = parameter length; BX,DX=0.;
  227. ; OUTPUT: DX:BX=number; CY= 0 if valid entry; CY = 1 if invalid entry. ;
  228. ;----------------------------------------------------------------------;
  229. Decimal_Input  proc    near
  230. Next_Decimal:  lodsb                           ;Get a character.
  231.                sub     al,"0"                  ;ASCII to binary.
  232.                jc      Loop_Decimal            ;If not between 0 and 9, skip.
  233.                cmp     al,9
  234.                ja      Loop_Decimal
  235.                cbw                             ;Convert to word.
  236.                shl     bx,1                    ; multiply old dx:bx by 10
  237.                rcl     dx,1
  238.                jc      End_Decimal             ;If carry, too big.
  239.                push    dx
  240.                add     ax,bx
  241.                shl     bx,1
  242.                rcl     dx,1
  243.                jc      End_Dec1                ;If carry, too big.
  244.                shl     bx,1
  245.                rcl     dx,1
  246.                jc      End_Dec1                ;If carry, too big.
  247.                add     bx,ax
  248.                pop     ax
  249.                adc     dx,ax
  250.                jc      End_Decimal             ;If carry, too big.
  251. Loop_Decimal:  loop    Next_Decimal
  252.                clc
  253.                jmp short End_Decimal
  254. End_Dec1:      pop     ax                      ; clean up stack
  255. End_Decimal:   ret
  256. Decimal_Input  endp
  257.  
  258. ;-----------------------------------------------------------------------;
  259. ; INPUT  : SI points to parameter start; CX = parameter length; BX,DX=0.;
  260. ; OUTPUT : DX:BX=number; CY= 0 if valid entry; CY = 1 if invalid entry. ;
  261. ;-----------------------------------------------------------------------;
  262. Binary_Input   proc    near
  263. Next_Bin:      lodsb                           ;Get a byte.
  264.                sub     al,"0"                  ;ASCII to binary.
  265.                jc      Loop_Bin                ;If not 0 or 1, skip.
  266.                cmp     al,1
  267.                ja      Loop_Bin
  268.                shl     bx,1                    ;Shift old number left one bit.
  269.                rcl     dx,1
  270.                jc      End_Bin                 ;If carry, too big.
  271.                or      bl,al                   ;Else, add it to the number.
  272. Loop_Bin:      loop    Next_Bin
  273.                clc
  274. End_Bin:       ret
  275. Binary_Input   endp
  276.  
  277. ;-----------------------------------------------------------------------;
  278. ; INPUT  : SI points to parameter start; CX = parameter length; BX,DX=0.;
  279. ; OUTPUT : DX:BX=number; CY= 0 if valid entry; CY = 1 if invalid entry. ;
  280. ;-----------------------------------------------------------------------;
  281. Hex_Input      proc    near
  282. Next_Hex:      lodsb                           ;Get a byte.
  283.                sub     al,"0"                  ;ASCII to binary.
  284.                jc      Loop_Hex                ;If below 0, skip.
  285.                cmp     al,9                    ;Is it 9 or below?
  286.                jle     Not_Alpha               ;If yes, OK.
  287.                sub     al,7                    ;Else, adjust for alpha.
  288.                cmp     al,10                   ;Is it punctuation?
  289.                jb      Loop_Hex                ;If yes, skip.
  290.                cmp     al,15                   ;Is it valid?
  291.                ja      Loop_Hex                ;If no, skip.
  292. Not_Alpha:     test    dx,0F000h               ;Is the number going to overflow?
  293.                stc                             ;Assume yes.
  294.                jnz     End_Hex                 ;If yes, too big.
  295.                shl     bx,1                    ; shift old number left 4 bits
  296.                rcl     dx,1
  297.                shl     bx,1
  298.                rcl     dx,1
  299.                shl     bx,1
  300.                rcl     dx,1
  301.                shl     bx,1
  302.                rcl     dx,1
  303.                or      bl,al                   ;Add to number.
  304. Loop_Hex:      loop    Next_Hex
  305.                clc
  306. End_Hex:       ret
  307. Hex_Input      endp
  308.  
  309. ;-----------------------------------------------------------------------;
  310. ; INPUT  : SI points to parameter start; CX = parameter length; BX,DX=0.;
  311. ; OUTPUT : DX:BX=number; CY= 0 if valid entry; CY = 1 if invalid entry. ;
  312. ;-----------------------------------------------------------------------;
  313. Octal_Input    proc    near
  314. Next_Octal:    lodsb                           ;Get a byte.
  315.                sub     al,"0"                  ;ASCII to binary.
  316.                jc      Loop_Octal              ;If not 0 through 7, skip.
  317.                cmp     al,7
  318.                ja      Loop_Octal
  319.                test    dx,0E000h               ;Is the number going to overflow?
  320.                stc                             ;Assume yes.
  321.                jnz     End_Octal               ;If yes, too big.
  322.                shl     bx,1                    ; shift old number left 3 bits
  323.                rcl     dx,1
  324.                shl     bx,1
  325.                rcl     dx,1
  326.                shl     bx,1
  327.                rcl     dx,1
  328.                or      bl,al                   ;Add to number.
  329. Loop_Octal:    loop    Next_Octal
  330.                clc
  331. End_Octal:     ret
  332. Octal_Input    endp
  333.  
  334. ;----------------------------------------;
  335. ; display number in decimal format       ;
  336. ; INPUT: DX:BX = number                  ;
  337. ;----------------------------------------;
  338. Decimal_Output proc    near
  339.                push    bx                      ; save number
  340.                push    dx
  341.                xor     cx,cx                   ; zero digit count
  342.                mov     ax,10                   ; divisor
  343.                mov     di,ax
  344.  
  345. Get_Digits:    mov     ax,dx                   ; hi word first;
  346.                xor     dx,dx                   ; supplement with 0 on the left
  347.                div     di                      ; divide; remainder in dx
  348.                xchg    ax,bx                   ; result -> bx; lo word -> ax
  349.                div     di                      ; divide lower half
  350.                xchg    dx,bx                   ; remainder -> bx; hi result->dx
  351.                xchg    bx,ax                   ; remainder -> ax; lo result->bx
  352.                push    ax                      ; one digit on stack
  353.                inc     cx                      ; increment digit count
  354.                or      dx,dx                   ; more to do?
  355.                jnz     Get_Digits              ; yes -> loop
  356.                or      bx,bx
  357.                jnz     Get_Digits              ; yes -> loop
  358.                mov     bl,cl                   ; Save the number of characters.
  359.  
  360. Next_Number:   pop     ax                      ; Retrieve digit
  361.                call    Print_Hex               ; And write it
  362.                loop    Next_Number             ; repeat...
  363.                mov     cx,11                   ; max # width (assume 4-byte)
  364.                or      si,si                   ; check for 2-byte form
  365.                je      Next_Num2               ; skip if 4-byte
  366.                mov     cl,Space_Cnt+5          ; no, use 2-byte
  367. Next_Num2:     sub     cl,bl                   ; return with tabbing count
  368.                pop     dx                      ; restore number
  369.                pop     bx
  370.                ret
  371. Decimal_Output endp
  372.  
  373. ;----------------------------------------;
  374. ; display number in hex format           ;
  375. ; INPUT: DX:BX = number                  ;
  376. ;----------------------------------------;
  377. Hex_Output     proc    near
  378.                push    bx                      ; save number
  379.                push    dx
  380.                mov     cx,0804h                ; ch: 8 digits; cl: 4-bit shifts
  381.                mov     ax,680Fh                ; ah: 'h' radix; al: 1111b mask
  382.                or      si,si                   ; 4-byte form?
  383.                je      Hex_Out2                ; yes, skip
  384.                mov     dx,bx                   ; no; shift in lo word
  385.                mov     ch,4                    ; 4 digits only
  386. Hex_Out2:      call    Display_Number
  387.                pop     dx                      ; restore number
  388.                pop     bx
  389.                ret
  390. Hex_Output     endp
  391.  
  392. ;----------------------------------------;
  393. ; display number in octal format         ;
  394. ; INPUT: DX:BX = number                  ;
  395. ;----------------------------------------;
  396. Octal_Output   proc    near
  397.                push    bx                      ; save number
  398.                push    dx
  399.                mov     cx,0A03h                ; ch: 10 digits; cl: 3bit shifts
  400.                mov     al,03h                  ; al: 11b mask(!)
  401.                cmp     ah,dh                   ; left bit is special!
  402.                rcl     bx,1
  403.                rcl     dx,1
  404.                or      si,si                   ; 4-byte form?
  405.                jne     Octal_Out1              ; no -> skip
  406.                cmp     ah,dh                   ; yes; 2nd-left bit special, too
  407.                rcl     bx,1
  408.                rcl     dx,1
  409.                jmp short Octal_Out2
  410. Octal_Out1:    mov     ch,5                    ; 5 digits for 2-byte form
  411.                mov     al,1                    ; al: 1b mask(!)
  412.                mov     dx,bx                   ; shift in lo word
  413. Octal_Out2:    and     al,bl                   ; mask bit(s)
  414.                call    Print_Hex               ; display hi bit(s)
  415.  
  416.                mov     ax,6F07h                ; ah: 'o' radix; al: 111b mask
  417.                call    Display_Number
  418.                pop     dx                      ; retrieve number
  419.                pop     bx
  420.                ret
  421. Octal_Output   endp
  422.  
  423. ;----------------------------------------;
  424. ; display number in binary format        ;
  425. ; INPUT: DX:BX = number                  ;
  426. ;----------------------------------------;
  427. Binary_Output  proc    near
  428.                push    bx                      ; save number
  429.                push    dx
  430.                mov     cx,622Dh                ; ch: 'b' radix; cl: '-'separator
  431.                or      si,si                   ; 4-byte form?
  432.                je      Binary_Out2             ; yes -> skip
  433. Binary_Out1:   mov     dx,bx                   ; shift in lo word
  434.                xchg    ch,cl                   ; no separator after 16 bits
  435. Binary_Out2:   push    cx                      ; save separators
  436.                mov     cx,16                   ; digit count (first half)
  437. Binary_Out3:   rol     dx,1                    ; shift by 1 bit
  438.                mov     al,dl                   ; move for output
  439.                and     al,1                    ; mask lo bit
  440.                call    Print_Hex               ; show it
  441.                cmp     cl,9                    ; mid-word?
  442.                jne     Binary_Out4             ; no -> skip
  443.                mov     al,'-'                  ; yes, show separator
  444.                call    Print_Char
  445. Binary_Out4:   loop    Binary_Out3             ; loop through this word
  446.                pop     cx                      ; get back separators
  447.                mov     al,cl                   ; show one
  448.                call    Print_Char
  449.                cmp     cl,'b'                  ; done?
  450.                jne     Binary_Out1             ; go for lo word
  451.                pop     dx                      ; retrieve number
  452.                pop     bx
  453.                ret
  454. Binary_Output  endp
  455.  
  456. ;----------------------------------------;
  457. ; INPUT: DX:BX = number                  ;
  458. ;----------------------------------------;
  459. Ascii_Output   proc    near
  460.                push    bx                      ; save number
  461.                push    dx
  462.                mov     dx,bx                   ; lo word
  463.                mov     bx,0070h                ;Page zero.
  464.                mov     ax,0E22H                ;Write TTY a quote mark.
  465.                int     10H                     ; via BIOS.
  466.  
  467.                mov     cx,5                    ;Display 5 quotation marks and
  468.                or      si,si
  469.                je      Ascii_Out2
  470.                mov     cl,3
  471. Ascii_Out2:    mov     ax,0A22H                ; do not update cursor position.
  472.                int     10H
  473.                dec     cx                      ; Display the lowest byte 4 times
  474.                mov     al,dl
  475.                int     10H
  476.                dec     cx                      ;Display byte #2 three times
  477.                mov     al,dh                   ; at current cursor position
  478.                int     10H
  479.                pop     dx                      ; get back hi word
  480.                or      si,si
  481.                jne     Ascii_Out3
  482.                dec     cx                      ;Display byte #3 twice
  483.                mov     al,dl
  484.                int     10H
  485.                dec     cx                      ;Display the high byte once
  486.                mov     al,dh                   ; at current cursor position
  487.                int     10H
  488. Ascii_Out3:    pop     bx                      ; retrieve lo word
  489.                ret
  490. Ascii_Output   endp
  491.  
  492.  
  493. ;----------------------------------------------------------------------------;
  494. ; Display a complete number                                                  ;
  495. ; INPUT: dx:bx : number to display; ch : number of digits; cl : shift amount ;
  496. ;        ah : terminating radix designator; al : bit mask                    ;
  497. ;----------------------------------------------------------------------------;
  498. Display_Number proc    near
  499. Disp_Num1:     push    cx                      ; save masks
  500.                push    ax
  501.                xor     ch,ch                   ; first, shifts only
  502.                mov     ah,7Fh                  ; for testing hi bit
  503. Rotate_Num:    cmp     ah,dh                   ; do the shifts
  504.                rcl     bx,1
  505.                rcl     dx,1
  506.                loop    Rotate_Num
  507.                and     al,bl                   ; mask bits
  508.                call    Print_Hex               ; show digit
  509.                pop     ax                      ; retrieve masks
  510.                pop     cx
  511.                dec     ch                      ; are we through?
  512.                jne     Disp_Num1               ; no, loop
  513.                mov     al,ah                   ; yes; show radix
  514.                call    Print_Char
  515. Disp_Num2:     ret
  516. Display_Number endp
  517.  
  518. ;----------------------------------------;
  519. ; INPUT: al : hex byte to display        ;
  520. ;----------------------------------------;
  521. Print_Hex      proc    near
  522.                add     al,"0"                  ;Convert to ASCII.
  523.                cmp     al,"9"                  ;Is it above 9?
  524.                jle     Print_Char              ;If no, print it.
  525.                add     al,7                    ;Else, adjust.
  526.  
  527. ;------------------------------;
  528. ; Display the character in al  ;
  529. ;------------------------------;
  530. Print_Char:    push    dx                      ; save dx
  531.                mov     dl,al
  532.                mov     ah,2                    ; display on StdOut
  533.                int     21H
  534.                pop     dx                      ; retrieve dx
  535.                ret
  536. Print_Hex      endp
  537.  
  538. ;---------------------------------------------------------------------------;
  539. ; print a few spaces: Spacing: standard width; Space_It: as indicated by cx ;
  540. ;---------------------------------------------------------------------------;
  541. Spacing        proc    near
  542.                mov     cx,1                    ; default: 1
  543.                or      si,si                   ; 2-byte form?
  544.                je      Space_It                ; no, skip
  545.                mov     cx, Space_Cnt           ; yes, use wider tabs
  546. Space_It:      mov     ah,02                   ; outputs and print via DOS.
  547.                push    dx                      ; save dx
  548.                mov     dl,Blank                ; show blanks
  549. Space_Loop:    int     21h
  550.                loop    Space_Loop
  551.                pop     dx                      ; retrieve dx
  552.                ret
  553. Spacing        endp
  554.  
  555. _Text          ends
  556.                end     Start
  557.