comment #
input:
 BX - pointer to string
output:
 AX - length of string
 BX - pointer to end of string
#
StrLen             PROC  NEAR
                   XOR   AX,AX
@@NextChar:        CMP   BYTE PTR [BX],0
                   JZ    @@Done
                   INC   AX
                   INC   BX
                   JMP   @@NextChar
@@Done:
                   RET
StrLen             ENDP

comment #
input:
 AL - character to insert
 BX - position where to insert
output:
 BX - pointer to end of string
#
StrIns             PROC  NEAR
                   XCHG  AL,[BX]
                   INC   BX
                   OR    AL,AL
                   JNZ   StrIns
                   MOV   [BX],AL

                   RET
StrIns             ENDP

comment #
input:
 BX - position where to delete
outputL
 BX - pointer to end of string
#
StrDel             PROC  NEAR
                   MOV   AX,[BX]
                   OR    AL,AL
                   JZ    @@Done
                   MOV   [BX],AH
                   INC   BX
                   JMP   StrDel
@@Done:
                   RET
StrDel             ENDP

comment #
input:
 AL - token delimiter
 BX - pointer to string
 DI - buffer for token
output:
 BX - points after token
 DI - points to end of copied token
#
StrTok             PROC  NEAR
                   MOV   AH,AL
@@NextBlank:       MOV   AL,[BX]
                   OR    AL,AL
                   JZ    @@Done
                   INC   BX
                   CMP   AL,AH
                   JZ    @@NextBlank
                   JMP   @@Store

@@NextChar:        MOV   AL,[BX]
                   OR    AL,AL
                   JZ    @@Done
                   CMP   AL,AH
                   JZ    @@Done
                   INC   BX
@@Store:           MOV   [DI],AL
                   INC   DI
                   JMP   @@NextChar

@@Done:            MOV   BYTE PTR [DI],0
                   RET
StrTok             ENDP

comment #
input:
 BX - source
 DI - destination
output:
 BX points to end of sorce
 DI points to end of destination
#

StrCpy             PROC  NEAR
                   MOV   AL,[BX]
                   OR    AL,AL
                   JZ    @@Done
                   INC   BX
                   MOV   [DI],AL
                   INC   DI
                   OR    AL,AL
                   JMP   StrCpy
@@Done:            MOV   BYTE PTR [DI],0
                   RET
StrCpy             ENDP

comment #
input:
 BX - string 1 (source)
 DI - string 2 (dest)
output:
 AX = 0  s = d
    = 1  s < d
    = -1 s > d
#

StrCmp             PROC  NEAR
                   MOV   DL,[BX]
                   MOV   DH,[DI]
                   OR    DX,DX
                   JZ    @@Equal
                   OR    DL,DL
                   JZ    @@dgreat
                   OR    DH,DH
                   JZ    @@sgreat
                   INC   BX
                   INC   DI
                   CMP   DL,DH
                   JZ    StrCmp
                   JA    @@sgreat
                   JMP   @@dgreat
@@Equal:           XOR   AX,AX
@@Done:
                   RET
@@dgreat:          MOV   AX,1
                   JMP   @@Done
@@sgreat:          MOV   AX,-1
                   JMP   @@Done

StrCmp             ENDP

comment #
input: BX - source
       DI - pointer to dest
output:
       BX - pointer to 0 after source
       DI - pointer to 0 after dest
#
StrUp              PROC  NEAR
                   MOV   AL,[BX]
                   INC   BX
                   CMP   AL,'a'
                   JB    @@Store
                   CMP   AL,'z'
                   JA    @@Store
                   SUB   AL,32
@@Store:           MOV   [DI],AL
                   INC   DI
                   OR    AL,AL
                   JNZ   StrUp
                   DEC   BX
                   DEC   DI
                   RET
StrUp              ENDP

comment #
 convert long into string
input:
 DX.AX 32 bit signed value
output:
 DI - pointer to ASCIIZ string with value
#
ltoa               PROC  NEAR
                   PUSH  AX
                   PUSH  BX
                   PUSH  CX
                   PUSH  DX
                   MOV   CL,' '
                   MOV   DI,OFFSET @@Buffer
                   OR    DX,DX
                   PUSHF
                   JNS   @@SkipSign1
                   NOT   DX
                   NOT   AX
                   ADD   AX,1
                   ADC   DX,0
@@SkipSign1:
                   MOV   BX,OFFSET @@Convertor
@@NextDigit:       XOR   CL,CL
@@NextSub:         SUB   AX,WORD PTR [BX]
                   SBB   DX,WORD PTR [BX+2]
                   JL    @@DigitDone
                   INC   CL
                   JMP   @@NextSub
@@DigitDone:       ADD   AX,WORD PTR [BX]
                   ADC   DX,WORD PTR [BX+2]
                   ADD   CL,'0'
                   MOV   [DI],CL
                   INC   DI
                   ADD   BX,4
                   CMP   BX,OFFSET @@ConvEnd
                   JNZ   @@NextDigit
@@Done:            MOV   BYTE PTR [DI],0
                   MOV   DI,OFFSET @@Buffer
                   MOV   BYTE PTR [DI-1],' '
@@LeadZeros:       CMP   BYTE PTR [DI],'0'
                   JNZ   @@Kicker
                   CMP   BYTE PTR [DI+1],0
                   JZ    @@Kicker
                   MOV   BYTE PTR [DI],' '
                   INC   DI
                   JMP   @@LeadZeros
@@Kicker:          POPF
                   JNS   @@SkipSign2
                   MOV   BYTE PTR [DI-1],'-'
@@SkipSign2:
                   MOV   DI,OFFSET @@Buffer-1
                   POP   DX
                   POP   CX
                   POP   BX
                   POP   AX
                   RET
                   DB    ' '
@@Buffer           DB    16D DUP(0)
@@Convertor        DD    1000000000D
                   DD    100000000D
                   DD    10000000D
                   DD    1000000D
                   DD    100000D
                   DD    10000D
                   DD    1000D
                   DD    100D
                   DD    10D
                   DD    1D
@@ConvEnd:
ltoa               ENDP
