home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / strings / strings.asm < prev    next >
Assembly Source File  |  2000-08-31  |  20KB  |  1,061 lines

  1. ; Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2. ; This library is free software; you can redistribute it and/or
  3. ; modify it under the terms of the GNU Library General Public
  4. ; License as published by the Free Software Foundation; either
  5. ; version 2 of the License, or (at your option) any later version.
  6. ; This library is distributed in the hope that it will be useful,
  7. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  9. ; Library General Public License for more details.
  10. ; You should have received a copy of the GNU Library General Public
  11. ; License along with this library; if not, write to the Free
  12. ; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  13. ; MA 02111-1307, USA
  14.  
  15. ; Note that if you don't have a macro assembler (like MASM) to compile
  16. ; this file, you can instead compile all *.c files in the string
  17. ; directory.
  18.  
  19.     TITLE   Stringfunctions that we use often at MSDOS / Intel 8086
  20.  
  21. ifndef M_I386
  22.     .8087
  23.     DOSSEG
  24.     .MODEL LARGE
  25.     .CODE
  26.  
  27.     ;
  28.     ; Some macros
  29.     ;
  30.  
  31. q_movs    MACRO                ; as rep movsb but quicker
  32.     shr    cx,1
  33.     rep    movsw            ; Move 2 bytes at a time
  34.     adc    cx,cx
  35.     rep    movsb            ; Move last byte if any
  36.     ENDM
  37.  
  38. q_stos    MACRO                ; as rep stosb but quicker
  39.     mov    ah,al            ; For word store
  40.     shr    cx,1
  41.     rep    stosw            ; Move 2 bytes at a time
  42.     adc    cx,cx
  43.     rep    stosb            ; Move last byte if any
  44.      ENDM
  45.  
  46. ifndef  ZTC                ; If not using ZORTECH compiler
  47.     ;
  48.     ; Compare memory
  49.     ; Args: s1,s2,length
  50.     ;
  51.  
  52.     PUBLIC    _bcmp
  53. _bcmp    PROC
  54.     mov    bx,bp            ; Save bp
  55.     mov    dx,di            ; Save di
  56.     mov    bp,sp
  57.     push    ds
  58.     push    si
  59.     les    di,DWORD PTR [bp+8]    ; s2
  60.     lds    si,DWORD PTR [bp+4]    ; s1
  61.     mov    cx,WORD PTR [bp+12]    ; Length of memory-area
  62.     jcxz    @F            ; Length = 0, return same
  63. ;    cld                ; Work uppward
  64.     repe    cmpsb            ; Compare strings
  65.     jz    @F            ; Match found
  66.     inc    cx            ; return matchpoint +1
  67. @@:    mov    ax,cx            ; Return 0 if match, else pos from end
  68.     pop    si
  69.     pop    ds
  70.     mov    di,dx
  71.     mov    bp,bx
  72.     ret
  73. _bcmp    ENDP
  74.  
  75.     ;
  76.     ; Find a char in a string
  77.     ; Arg: str,char
  78.     ; Ret: pointer to found char or NullS
  79.     ;
  80.  
  81. ifdef better_stringfunctions        ; Breaks window linkage (broken linking)
  82.  
  83.     PUBLIC    _strchr
  84. _strchr    PROC
  85.     mov    bx,bp            ; Save bp and di
  86.     mov    dx,di
  87.     mov    bp,sp
  88.     les    di,DWORD PTR [bp+4]    ; str
  89.     mov    ah,BYTE PTR [bp+8]    ; search
  90.     xor    al,al            ; for scasb to find end
  91.  
  92. @@:    cmp    ah,es:[di]
  93.     jz    @F            ; Found char
  94.     scasb
  95.     jnz    @B            ; Not end
  96.     xor    di,di            ; Not found
  97.     mov    es,di
  98. @@:    mov    ax,di
  99.     mov    di,dx            ; Restore
  100.     mov    dx,es            ; Seg adr
  101.     mov    bp,bx            ; Restore
  102.     ret
  103. _strchr    ENDP
  104.  
  105.     ;
  106.     ; Find length of string
  107.     ; arg: str
  108.     ; ret: length
  109.     ;
  110.  
  111.     PUBLIC    _strlen
  112. _strlen    PROC
  113.     mov    bx,sp
  114.     mov    dx,di
  115.     les    di,DWORD PTR ss:[bx+4]    ; Str
  116.     xor    al,al            ; Find end of string
  117.     mov    cx,-1
  118. ;    cld
  119.     repne    scasb            ; Find strend or length
  120.     inc    cx            ; Calc strlength
  121.     not    cx
  122.     mov    ax,cx
  123.     mov    di,dx            ; Restore register
  124.     ret
  125. _strlen    ENDP
  126.  
  127. endif
  128.  
  129.     ;
  130.     ; Move a string
  131.     ; arg: dst,src
  132.     ; ret: end-null of to
  133.     ;
  134.  
  135.     PUBLIC    _strmov
  136. _strmov    PROC
  137.     mov    bx,bp
  138.     mov    cx,si
  139.     mov    bp,sp
  140.     push    ds
  141.     push    di
  142.     les    di,DWORD PTR [bp+4]    ; dst
  143.     lds    si,DWORD PTR [bp+8]    ; src
  144. ;    cld
  145. @@:    mov    al,ds:[si]
  146.     movsb                ; move arg
  147.     and    al,al
  148.     jnz    @B            ; Not last
  149.     lea    ax,WORD PTR [di-1]    ; Set DX:AX to point at last null
  150.     mov    dx,es
  151.     pop    di
  152.     pop    ds
  153.     mov    si,cx
  154.     mov    bp,bx
  155.     ret
  156. _strmov    ENDP
  157.  
  158.     ;
  159.     ; Fill a area of memory with a walue
  160.     ; Args: to,length,fillchar
  161.     ;
  162.  
  163.     PUBLIC    _bfill
  164. _bfill    PROC
  165.     mov    bx,sp            ; Get args through BX
  166.     mov    al,BYTE PTR ss:[bx+10]    ; Fill
  167. bfill_10:
  168.     mov    dx,di            ; Save di
  169.     les    di,DWORD PTR ss:[bx+4]    ; Memory pointer
  170.     mov    cx,WORD PTR ss:[bx+8]    ; Length
  171. ;    cld
  172.     q_stos
  173.     mov    di,dx
  174.     ret
  175. _bfill    ENDP
  176.  
  177.     ;
  178.     ; Fill a area with null
  179.     ; Args: to,length
  180.  
  181.     PUBLIC    _bzero
  182. _bzero    PROC
  183.     mov    bx,sp            ; Get args through BX
  184.     mov    al,0            ; Fill with null
  185.     jmp    short bfill_10
  186. _bzero    ENDP
  187.  
  188. endif    ; ZTC
  189.  
  190.     ;
  191.     ; Move a memory area
  192.     ; Args: to,from,length
  193.     ;
  194.  
  195.     PUBLIC    _bmove
  196. _bmove    PROC
  197.     mov    bx,bp
  198.     mov    dx,di
  199.     mov    ax,si
  200.     mov    bp,sp
  201.     push    ds
  202.     lds    si,DWORD PTR [bp+8]    ; from
  203.     les    di,DWORD PTR [bp+4]    ; to
  204.     mov    cx,WORD PTR [bp+12]    ; Length of memory-area
  205. ;    cld                ; Work uppward
  206.     rep    movsb            ; Not q_movs because overlap ?
  207.     pop    ds
  208.     mov    si,ax
  209.     mov    di,dx
  210.     mov    bp,bx
  211.     ret
  212. _bmove    ENDP
  213.  
  214.     ;
  215.     ; Move a alligned, not overlapped, by (long) divided memory area
  216.     ; Args: to,from,length
  217.     ;
  218.  
  219.     PUBLIC    _bmove_allign
  220. _bmove_allign    PROC
  221.     mov    bx,bp
  222.     mov    dx,di
  223.     mov    ax,si
  224.     mov    bp,sp
  225.     push    ds
  226.     lds    si,DWORD PTR [bp+8]    ; from
  227.     les    di,DWORD PTR [bp+4]    ; to
  228.     mov    cx,WORD PTR [bp+12]    ; Length of memory-area
  229. ;    cld                ; Work uppward
  230.     inc    cx            ; fix if not divisible with word
  231.     shr    cx,1
  232.     rep    movsw            ; Move 2 bytes at a time
  233.     pop    ds
  234.     mov    si,ax
  235.     mov    di,dx
  236.     mov    bp,bx
  237.     ret
  238. _bmove_allign    ENDP
  239.  
  240.     ;
  241.     ; Move a string from higher to lower
  242.     ; Arg from+1,to+1,length
  243.     ;
  244.  
  245.     PUBLIC    _bmove_upp
  246. _bmove_upp    PROC
  247.     mov    bx,bp
  248.     mov    dx,di
  249.     mov    ax,si
  250.     mov    bp,sp
  251.     push    ds
  252.     lds    si,DWORD PTR [bp+8]    ; from
  253.     les    di,DWORD PTR [bp+4]    ; to
  254.     mov    cx,WORD PTR [bp+12]    ; Length of memory-area
  255.     dec    di            ; Don't move last arg
  256.     dec    si
  257.     std                ; Work downward
  258.     rep    movsb            ; Not q_movs because overlap ?
  259.     cld                ; C compilator want cld
  260.     pop    ds
  261.     mov    si,ax
  262.     mov    di,dx
  263.     mov    bp,bx
  264.     ret
  265. _bmove_upp ENDP
  266.  
  267.     ;
  268.     ; Append fillchars to string
  269.     ; Args: dest,len,fill
  270.     ;
  271.  
  272.     PUBLIC    _strappend
  273. _strappend    PROC
  274.     mov    bx,bp
  275.     mov    dx,di
  276.     mov    bp,sp
  277.     les    di,DWORD PTR [bp+4]    ; Memory pointer
  278.     mov    cx,WORD PTR [bp+8]    ; Length
  279.     sub    al,al            ; Find end of string
  280. ;    cld
  281.     repne    scasb
  282.     jnz    sa_99            ; String to long, shorten it
  283.     mov    al,BYTE PTR [bp+10]    ; Fillchar
  284.     dec    di            ; Point at end null
  285.     inc    cx            ; rep made one dec for null-char
  286.     q_stos                ; Store al in string
  287. sa_99:    mov    BYTE PTR es:[di],0    ; End of string
  288.     mov    di,dx
  289.     mov    bp,bx
  290.     ret
  291. _strappend    ENDP
  292.  
  293.     ;
  294.     ; Find if string contains any char in another string
  295.     ; Arg: str,set
  296.     ; Ret: Pointer to first found char in str
  297.     ;
  298.  
  299.     PUBLIC    _strcont
  300. _strcont    PROC
  301.     mov    bx,bp            ; Save bp and di in regs
  302.     mov    dx,di
  303.     mov    bp,sp
  304.     push    ds
  305.     push    si
  306.     lds    si,DWORD PTR [bp+4]    ; str
  307.     les    di,DWORD PTR [bp+8]    ; Set
  308.     mov    cx,di            ; Save for loop
  309.     xor    ah,ah            ; For endtest
  310.     jmp    sc_60
  311.  
  312. sc_10:    scasb
  313.     jz    sc_fo            ; Found char
  314. sc_20:    cmp    ah,es:[di]        ; Test if null
  315.     jnz    sc_10            ; Not end of set yet
  316.     inc    si            ; Next char in str
  317.     mov    di,cx            ; es:di = Set
  318. sc_60:    mov    al,ds:[si]        ; Test if this char exist
  319.     and    al,al
  320.     jnz    sc_20            ; Not end of string
  321.     sub    si,si            ; Return Null
  322.     mov    ds,si
  323. sc_fo:    mov    ax,si            ; Char found here
  324.     mov    di,dx            ; Restore
  325.     mov    dx,ds            ; Seg of found char
  326.     pop    si
  327.     pop    ds
  328.     mov    bp,bx
  329.     ret
  330. _strcont    ENDP
  331.  
  332.     ;
  333.     ; Found end of string
  334.     ; Arg: str
  335.     ; ret: Pointer to end null
  336.     ;
  337.  
  338.     PUBLIC    _strend
  339. _strend    PROC
  340.     mov    bx,sp
  341.     mov    dx,di            ; Save
  342.     les    di,DWORD PTR ss:[bx+4]    ; str
  343.     mov    cx,-1
  344.     sub    al,al            ; Find end of string
  345. ;    cld
  346.     repne    scasb
  347.     lea    ax,WORD PTR [di-1]    ; Endpos i DX:AX
  348.     mov    di,dx            ; Restore
  349.     mov    dx,es
  350.     ret
  351. _strend    ENDP
  352.  
  353.     ;
  354.     ; Make a string with len fill-chars and endnull
  355.     ; Args: dest,len,fill
  356.     ; Ret:  dest+len
  357.     ;
  358.  
  359.     PUBLIC    _strfill
  360. _strfill    PROC
  361.     mov    bx,bp            ; Save sp
  362.     mov    bp,sp
  363.     push    di
  364.     les    di,DWORD PTR [bp+4]    ; Memory pointer
  365.     mov    cx,WORD PTR [bp+8]    ; Length
  366.     mov    al,BYTE PTR [bp+10]    ; Fill
  367. ;    cld
  368.     q_stos
  369.     mov    BYTE PTR es:[di],0    ; End NULL
  370.     mov    ax,di            ; End i DX:AX
  371.     mov    dx,es
  372.     pop    di
  373.     mov    bp,bx
  374.     ret
  375. _strfill    ENDP
  376.  
  377.     ;
  378.     ; Find a char in or end of a string
  379.     ; Arg: str,char
  380.     ; Ret: pointer to found char or NullS
  381.     ;
  382.  
  383.     PUBLIC    _strcend
  384. _strcend    PROC
  385.     mov    bx,bp            ; Save bp and di
  386.     mov    dx,di
  387.     mov    bp,sp
  388.     les    di,DWORD PTR [bp+4]    ; str
  389.     mov    ah,BYTE PTR [bp+8]    ; search
  390.     xor    al,al            ; for scasb to find end
  391.  
  392. @@:    cmp    ah,es:[di]
  393.     jz    @F            ; Found char
  394.     scasb
  395.     jnz    @B            ; Not end
  396.     dec     di            ; Not found, point at end of string
  397. @@:    mov    ax,di
  398.     mov    di,dx            ; Restore
  399.     mov    dx,es            ; Seg adr
  400.     mov    bp,bx            ; Restore
  401.     ret
  402. _strcend    ENDP
  403.  
  404.     ;
  405.     ; Test if string has a given suffix
  406.     ;
  407.  
  408. PUBLIC  _is_prefix
  409. _is_prefix PROC
  410.     mov    dx,di            ; Save di
  411.     mov    bx,sp            ; Arguments through bx
  412.     push    ds
  413.     push    si
  414.     les    di,DWORD PTR ss:[bx+8]    ; s2
  415.     lds    si,DWORD PTR ss:[bx+4]    ; s1
  416.     mov    ax,1            ; Ok and zero-test
  417. ;    cld                ; Work uppward
  418. @@:    cmp    ah,es:[di]
  419.     jz    suf_ok            ; End of string; found suffix
  420.     cmpsb                ; Compare strings
  421.     jz    @B            ; Same, possible prefix
  422.     xor    ax,ax            ; Not suffix
  423. suf_ok:    pop    si
  424.     pop    ds
  425.     mov    di,dx
  426.     ret
  427. _is_prefix ENDP
  428.  
  429.     ;
  430.     ; Find a substring in string
  431.     ; Arg: str,search
  432.     ;
  433.  
  434.     PUBLIC    _strstr
  435. _strstr    PROC
  436.     mov    bx,bp
  437.     mov    bp,sp
  438.     push    ds
  439.     push    di
  440.     push    si
  441.     lds    si,DWORD PTR [bp+4]    ; str
  442.     les    di,DWORD PTR [bp+8]    ; search
  443.     mov    cx,di
  444.     inc    cx            ; CX = search+1
  445.     mov    ah,es:[di]        ; AH = First char in search
  446.     jmp    sf_10
  447.  
  448. sf_00:    mov    si,dx            ; si = Current str-pos
  449. sf_10:    mov    al,ds:[si]        ; Test if this char exist
  450.     and    al,al
  451.     jz    sf_90            ; End of string, didn't find search
  452.     inc    si
  453.     cmp    al,ah
  454.     jnz    sf_10            ; Didn't find first char, continue
  455.     mov    dx,si            ; Save str-pos in DX
  456.     mov    di,cx
  457. sf_20:    cmp    BYTE PTR es:[di],0
  458.     jz    sf_fo            ; Found substring
  459.     cmpsb
  460.     jz    sf_20            ; Char ok
  461.     jmp    sf_00            ; Next str-pos
  462.  
  463. sf_90:    sub    dx,dx            ; Return Null
  464.     mov    ds,dx
  465.     inc    dx            ; Because of following dec
  466. sf_fo:    mov    ax,dx            ; Char found here
  467.     dec    ax            ; Pointed one after
  468.     mov    dx,ds
  469.     pop    si
  470.     pop    di            ; End
  471.     pop    ds
  472.     mov    bp,bx
  473.     ret
  474. _strstr    ENDP
  475.  
  476.     ;
  477.     ; Find a substring in string, return index
  478.     ; Arg: str,search
  479.     ;
  480.  
  481.     PUBLIC    _strinstr
  482. _strinstr    PROC
  483.     push    bp
  484.     mov    bp,sp
  485.     push    di
  486.     les    di,DWORD PTR [bp+10]    ; search
  487.     push    es
  488.     push    di
  489.     les    di,DWORD PTR [bp+6]    ; str
  490.     push    es
  491.     push    di
  492.     call    _strstr
  493.     mov    cx,ax
  494.     or    cx,dx
  495.     jz    si_99
  496.     sub    ax,di            ; Pos from start
  497.     inc    ax            ; And first pos = 1
  498. si_99:    add    sp,8
  499.     pop    di
  500.     pop    bp
  501.     ret
  502. _strinstr    ENDP
  503.  
  504.     ;
  505.     ; Make a string of len length from another string
  506.     ; Arg: dst,src,length
  507.     ; ret: end of dst
  508.     ;
  509.  
  510.     PUBLIC    _strmake
  511. _strmake    PROC
  512.     mov    bx,bp
  513.     mov    bp,sp
  514.     push    ds
  515.     push    di
  516.     push    si
  517.     les    di,DWORD PTR [bp+4]    ; dst
  518.     lds    si,DWORD PTR [bp+8]    ; src
  519.     mov    cx,WORD PTR [bp+12]    ; Length of memory-area
  520.     xor    al,al            ; For test of end-null
  521.     jcxz    sm_90            ; Nothing to move, put zero at end.
  522. ;    cld                ; Work uppward
  523.  
  524. @@:    cmp    al,ds:[si]        ; Next char to move
  525.     movsb                ; move arg
  526.     jz    sm_99            ; last char, we are ready
  527.     loop    @B            ; Continue moving
  528. sm_90:    mov    BYTE PTR es:[di],al    ; Set end pos
  529.     inc    di            ; Fix that di points at end null
  530. sm_99:    dec    di            ; di points now at end null
  531.     mov    ax,di            ; Ret value in DX:AX
  532.     mov    dx,es
  533.     pop    si
  534.     pop    di
  535.     pop    ds
  536.     mov    bp,bx
  537.     ret
  538. _strmake    ENDP
  539.  
  540.     ;
  541.     ; Find length of string with maxlength
  542.     ; arg: str,maxlength
  543.     ; ret: length
  544.     ;
  545.  
  546.     PUBLIC    _strnlen
  547. _strnlen    PROC
  548.     mov    bx,bp
  549.     mov    bp,sp
  550.     push    di
  551.     les    di,DWORD PTR [bp+4]    ; Str
  552.     mov    cx,WORD PTR [bp+8]    ; length
  553.     mov    dx,di            ; Save str to calc length
  554.     jcxz    sn_10            ; Length = 0
  555.     xor    al,al            ; Find end of string
  556. ;    cld
  557.     repne    scasb            ; Find strend or length
  558.     jnz    sn_10
  559.     dec    di            ; DI points at last null
  560. sn_10:    mov    ax,di
  561.     sub    ax,dx            ; Ax = length
  562.     pop    di
  563.     mov    bp,bx
  564.     ret
  565. _strnlen    ENDP
  566.  
  567.     ;
  568.     ; Move a string with max len chars
  569.     ; arg: dst,src,len
  570.     ; ret: pos to first null or dst+len
  571.  
  572.     PUBLIC    _strnmov
  573. _strnmov    PROC
  574.     mov    bx,bp
  575.     mov    bp,sp
  576.     push    ds
  577.     push    di
  578.     push    si
  579.     les    di,DWORD PTR [bp+4]    ; dst
  580.     lds    si,DWORD PTR [bp+8]    ; src
  581.     mov    cx,WORD PTR [bp+12]    ; length
  582.     jcxz    snm_99            ; Nothing to do
  583.     xor    al,al            ; For test of end-null
  584. ;    cld
  585.  
  586. @@:    cmp    al,ds:[si]        ; Next char to move
  587.     movsb                ; move arg
  588.     jz    snm_20            ; last char, fill with null
  589.     loop    @B            ; Continue moving
  590.     inc    di            ; Point two after last
  591. snm_20:    dec    di            ; Point at first null (or last+1)
  592. snm_99:    mov    ax,di            ; Pointer at last char
  593.     mov    dx,es            ; To-segment
  594.     pop    si
  595.     pop    di
  596.     pop    ds
  597.     mov    bp,bx            ; Restore
  598.     ret
  599. _strnmov    ENDP
  600.  
  601. else    ; M_I386
  602.  
  603. include macros.asm
  604.  
  605. q_stos    MACRO                ; as rep stosb but quicker, Uses edx
  606.     mov    ah,al            ;(2) Set up a 32 bit pattern.
  607.     mov    edx,eax            ;(2)
  608.     shl    edx,16            ;(3)
  609.     or    eax,edx            ;(2) EAX has the 32 bit pattern.
  610.  
  611.     mov    edx,ecx            ;(2) Save the count of bytes.
  612.     shr    ecx,2            ;(2) Number of dwords.
  613.     rep    stosd            ;(5 + 5n)
  614.     mov    cl,3            ;(2)
  615.     and    ecx,edx            ;(2) Fill in the remaining odd bytes.
  616.     rep    stosb            ; Move last bytes if any
  617.     ENDM
  618.  
  619. fix_es    MACRO    fix_cld            ; Load ES if neaded
  620.   ife ESeqDS
  621.     mov    ax,ds
  622.     mov    es,ax
  623.   endif
  624.   ifnb <fix_cld>
  625.     cld
  626.   endif
  627.     ENDM
  628.  
  629.     ;
  630.     ; Move a memory area
  631.     ; Args: to,from,length
  632.     ; Acts as one byte was moved a-time from dst to source.
  633.     ;
  634.  
  635.     begcode bmove
  636.     public    _bmove
  637. _bmove    proc near
  638.     fix_es    1
  639.     mov    edx,edi
  640.     mov    eax,esi
  641.     mov    edi,P-SIZEPTR[esp]    ;p1
  642.     mov    esi,P[esp]        ;p2
  643.     mov    ecx,P+SIZEPTR[esp]
  644.     rep    movsb            ; Not q_movs because overlap ?
  645.     mov    esi,eax
  646.     mov    edi,edx
  647.     ret
  648. _bmove    ENDP
  649.     endcode bmove
  650.  
  651.     ;
  652.     ; Move a alligned, not overlapped, by (long) divided memory area
  653.     ; Args: to,from,length
  654.     ;
  655.  
  656.     begcode    bmove_allign
  657.     public    _bmove_allign
  658. _bmove_allign    proc near
  659.     fix_es    1
  660.     mov    edx,edi
  661.     mov    eax,esi
  662.     mov    edi,P-SIZEPTR[esp]    ;to
  663.     mov    esi,P[esp]        ;from
  664.     mov    ecx,P+SIZEPTR[esp]    ;length
  665.     add    cx,3            ;fix if not divisible with long
  666.     shr    cx,2
  667.     rep    movsd
  668.     mov    esi,eax
  669.     mov    edi,edx
  670.     ret
  671. _bmove_allign    ENDP
  672.     endcode bmove_allign
  673.  
  674.     ;
  675.     ; Move a string from higher to lower
  676.     ; Arg from+1,to+1,length
  677.     ;
  678.  
  679.     begcode    bmove_upp
  680.     public    _bmove_upp
  681. _bmove_upp    proc near
  682.     fix_es
  683.     std                ; Work downward
  684.     mov    edx,edi
  685.     mov    eax,esi
  686.     mov    edi,P-SIZEPTR[esp]    ;p1
  687.     mov    esi,P[esp]        ;p2
  688.     mov    ecx,P+SIZEPTR[esp]
  689.     dec    edi            ; Don't move last arg
  690.     dec    esi
  691.     rep    movsb            ; One byte a time because overlap !
  692.     cld                ; C compilator wants cld
  693.     mov    esi,eax
  694.     mov    edi,edx
  695.     ret
  696. _bmove_upp ENDP
  697.     endcode bmove_upp
  698.  
  699.     ;
  700.     ; Append fillchars to string
  701.     ; Args: dest,len,fill
  702.     ;
  703.  
  704.     begcode    strappend
  705.     public    _strappend
  706. _strappend    proc near
  707.     push    ebp
  708.     mov    ebp,esp
  709.     fix_es  1
  710.     push    edi
  711.     mov    edi,P[ebp]        ; Memory pointer
  712.     mov    ecx,P+SIZEPTR[ebp]    ; Length
  713.     clr    eax            ; Find end of string
  714.     repne    scasb
  715.     jnz    sa_99            ; String to long, shorten it
  716.     movzx    eax,byte ptr P+(2*SIZEPTR)[ebp]    ; Fillchar
  717.     dec    edi            ; Point at end null
  718.     inc    ecx            ; rep made one dec for null-char
  719.     q_stos                ; Store al in string
  720. sa_99:    mov    BYTE PTR [edi],0    ; End of string
  721.     pop    edi
  722.     pop    ebp
  723.     ret
  724. _strappend    ENDP
  725.     endcode strappend
  726.  
  727.     ;
  728.     ; Find if string contains any char in another string
  729.     ; Arg: str,set
  730.     ; Ret: Pointer to first found char in str
  731.     ;
  732.  
  733.     begcode strcont
  734.     PUBLIC    _strcont
  735. _strcont proc near
  736.     push    ebp
  737.     mov    ebp,esp
  738.     fix_es    1
  739.     mov    edx,edi
  740.     push    esi
  741.     mov    esi,P[ebp]        ; str
  742.     mov    ecx,P+SIZEPTR[ebp]    ; Set
  743.     clr    ah            ; For endtest
  744.     jmps    sc_60
  745.  
  746. sc_10:    scasb
  747.     jz    sc_fo            ; Found char
  748. sc_20:    cmp    ah,[edi]        ; Test if null
  749.     jnz    sc_10            ; Not end of set yet
  750.     inc    esi            ; Next char in str
  751. sc_60:    mov    edi,ecx            ; edi = Set
  752.     mov    al,[esi]        ; Test if this char exist
  753.     and    al,al
  754.     jnz    sc_20            ; Not end of string
  755.     clr    esi            ; Return Null
  756. sc_fo:    mov    eax,esi            ; Char found here
  757.     mov    edi,edx            ; Restore
  758.     pop    esi
  759.     pop    ebp
  760.     ret
  761. _strcont    ENDP
  762.     endcode strcont
  763.  
  764.     ;
  765.     ; Found end of string
  766.     ; Arg: str
  767.     ; ret: Pointer to end null
  768.     ;
  769.  
  770.     begcode strend
  771.     public    _strend
  772. _strend    proc near
  773.     fix_es    1
  774.     mov    edx,edi            ; Save
  775.     mov    edi,P-SIZEPTR[esp]    ; str
  776.     clr    eax            ; Find end of string
  777.     mov    ecx,eax
  778.     dec    ecx            ; ECX = -1
  779.     repne    scasb
  780.     mov    eax,edi
  781.     dec    eax
  782.     mov    edi,edx            ; Restore
  783.     ret
  784. _strend    endp
  785.     endcode strend
  786.  
  787.     ;
  788.     ; Make a string with len fill-chars and endnull
  789.     ; Args: dest,len,fill
  790.     ; Ret:  dest+len
  791.     ;
  792.  
  793.     begcode    strfill
  794.     public    _strfill
  795. _strfill proc near
  796.     push    ebp
  797.     mov    ebp,esp
  798.     fix_es  1
  799.     push    edi
  800.     mov    edi,P[ebp]        ; Memory pointer
  801.     mov    ecx,P+SIZEPTR[ebp]    ; Length
  802.     movzx    eax,byte ptr P+(2*SIZEPTR)[ebp]    ; Fill
  803.     q_stos
  804.     mov    BYTE PTR [edi],0    ; End NULL
  805.     mov    eax,edi            ; End i DX:AX
  806.     pop    edi
  807.     pop    ebp
  808.     ret
  809. _strfill endp
  810.     endcode strfill
  811.  
  812.     ;
  813.     ; Find a char in or end of a string
  814.     ; Arg: str,char
  815.     ; Ret: pointer to found char or NullS
  816.     ;
  817.  
  818.     begcode strcend
  819.     public    _strcend
  820. _strcend proc near
  821.     push    ebp
  822.     mov    ebp,esp
  823.     fix_es  1
  824.     mov    edx,edi
  825.     mov    edi,P[ebp]        ; str
  826.     mov    ah,P+SIZEPTR[ebp]    ; search
  827.     clr    al            ; for scasb to find end
  828.  
  829. @@:    cmp    ah,[edi]
  830.     jz    @F            ; Found char
  831.     scasb
  832.     jnz    @B            ; Not end
  833.     dec     edi            ; Not found, point at end of string
  834. @@:    mov    eax,edi
  835.     mov    edi,edx            ; Restore
  836.     pop    ebp
  837.     ret
  838. _strcend    ENDP
  839.     endcode strcend
  840.  
  841.     ;
  842.     ; Test if string has a given suffix
  843.     ;
  844.  
  845.     begcode is_prefix
  846.     public    _is_prefix
  847. _is_prefix proc near
  848.     fix_es    1
  849.     mov    edx,edi            ; Save edi
  850.     mov    eax,esi            ; Save esi
  851.     mov    esi,P[esp]        ; get suffix
  852.     mov    edi,P-SIZEPTR[esp]    ; s1
  853.     push    eax            ; push esi
  854.     mov    eax,1            ; Ok and zero-test
  855. @@:    cmp    ah,[esi]
  856.     jz    suf_ok            ; End of string; found suffix
  857.     cmpsb                ; Compare strings
  858.     jz    @B            ; Same, possible prefix
  859.     xor    eax,eax            ; Not suffix
  860. suf_ok:    pop    esi
  861.     mov    edi,edx
  862.     ret
  863. _is_prefix endp
  864.     endcode    _is_prefix
  865.  
  866.     ;
  867.     ; Find a substring in string
  868.     ; Arg: str,search
  869.     ;
  870.  
  871.     begcode strstr
  872.     public    _strstr
  873. _strstr proc near
  874.     push    ebp
  875.     mov    ebp,esp
  876.     fix_es    1
  877.     push    EDI
  878.     push    ESI
  879.     mov    esi,P[ebp]        ; str
  880.     mov    edi,P+SIZEPTR[ebp]    ; search
  881.     mov    ecx,edi
  882.     inc    ecx            ; ECX = search+1
  883.     mov    ah,[edi]        ; AH = First char in search
  884.     jmps    sf_10
  885.  
  886. sf_00:    mov    esi,edx            ; si = Current str-pos
  887. sf_10:    mov    al,[esi]        ; Test if this char exist
  888.     and    al,al
  889.     jz    sf_90            ; End of string, didn't find search
  890.     inc    esi
  891.     cmp    al,ah
  892.     jnz    sf_10            ; Didn't find first char, continue
  893.     mov    edx,esi            ; Save str-pos in EDX
  894.     mov    edi,ecx
  895. sf_20:    cmp    BYTE PTR [edi],0
  896.     jz    sf_fo            ; Found substring
  897.     cmpsb
  898.     jz    sf_20            ; Char ok
  899.     jmps    sf_00            ; Next str-pos
  900.  
  901. sf_90:    mov    edx,1            ; Return Null
  902. sf_fo:    mov    eax,edx            ; Char found here
  903.     dec    eax            ; Pointed one after
  904.     pop    ESI
  905.     pop    EDI
  906.     pop    ebp
  907.     ret
  908. _strstr endp
  909.     endcode strstr
  910.  
  911.     ;
  912.     ; Find a substring in string, return index
  913.     ; Arg: str,search
  914.     ;
  915.  
  916.     begcode    strinstr
  917.     public    _strinstr
  918. _strinstr proc near
  919.     push    ebp
  920.     mov    ebp,esp
  921.     push    P+SIZEPTR[ebp]        ; search
  922.     push    P[ebp]            ; str
  923.     call    _strstr
  924.     add    esp,SIZEPTR*2
  925.     or    eax,eax
  926.     jz    si_99            ; Not found, return NULL
  927.     sub    eax,P[ebp]        ; Pos from start
  928.     inc    eax            ; And first pos = 1
  929. si_99:    pop    ebp
  930.     ret
  931. _strinstr    endp
  932.     endcode strinstr
  933.  
  934.     ;
  935.     ; Make a string of len length from another string
  936.     ; Arg: dst,src,length
  937.     ; ret: end of dst
  938.     ;
  939.  
  940.     begcode strmake
  941.     public    _strmake
  942. _strmake proc near
  943.     push    ebp
  944.     mov    ebp,esp
  945.     fix_es    1
  946.     push    EDI
  947.     push    ESI
  948.     mov    edi,P[ebp]        ; dst
  949.     mov    esi,P+SIZEPTR[ebp]    ; src
  950.     mov    ecx,P+SIZEPTR*2[ebp]    ; Length of memory-area
  951.     clr    al            ; For test of end-null
  952.     jcxz    sm_90            ; Nothing to move, put zero at end.
  953.  
  954. @@:    cmp    al,[esi]        ; Next char to move
  955.     movsb                ; move arg
  956.     jz    sm_99            ; last char, we are ready
  957.     loop    @B            ; Continue moving
  958. sm_90:    mov    BYTE PTR [edi],al    ; Set end pos
  959.     inc    edi            ; Fix that di points at end null
  960. sm_99:    dec    edi            ; di points now at end null
  961.     mov    eax,edi            ; Ret value in DX:AX
  962.     pop    ESI
  963.     pop    EDI
  964.     pop    ebp
  965.     ret
  966. _strmake    ENDP
  967.     endcode strmake
  968.  
  969.     ;
  970.     ; Find length of string with maxlength
  971.     ; arg: str,maxlength
  972.     ; ret: length
  973.     ;
  974.  
  975.     begcode    strnlen
  976.     public    _strnlen
  977. _strnlen proc near
  978.     push    ebp
  979.     mov    ebp,esp
  980.     fix_es    1
  981.     push    edi
  982.     mov    edi,P[ebp]        ; Str
  983.     mov    ecx,P+SIZEPTR[ebp]    ; length
  984.     mov    edx,edi            ; Save str to calc length
  985.     jcxz    sn_10            ; Length = 0
  986.     clr    al            ; Find end of string
  987.     repne    scasb            ; Find strend or length
  988.     jnz    sn_10
  989.     dec    edi            ; DI points at last null
  990. sn_10:    mov    eax,edi
  991.     sub    eax,edx            ; Ax = length
  992.     pop    edi
  993.     pop    ebp
  994.     ret
  995. _strnlen    ENDP
  996.     endcode strnlen
  997.  
  998.     ;
  999.     ; Move a string with max len chars
  1000.     ; arg: dst,src,len
  1001.     ; ret: pos to first null or dst+len
  1002.  
  1003.     begcode    strnmov
  1004.     public    _strnmov
  1005. _strnmov PROC near
  1006.     push    ebp
  1007.     mov    ebp,esp
  1008.     fix_es    1
  1009.     push    EDI
  1010.     push    ESI
  1011.     mov    edi,P[ebp]        ; dst
  1012.     mov    esi,P+SIZEPTR[ebp]    ; src
  1013.     mov    ecx,P+(SIZEPTR*2)[ebp]    ; length
  1014.     jcxz    snm_99            ; Nothing to do
  1015.     clr    al            ; For test of end-null
  1016.  
  1017. @@:    cmp    al,[esi]        ; Next char to move
  1018.     movsb                ; move arg
  1019.     jz    snm_20            ; last char, fill with null
  1020.     loop    @B            ; Continue moving
  1021.     inc    edi            ; Point two after last
  1022. snm_20:    dec    edi            ; Point at first null (or last+1)
  1023. snm_99:    mov    eax,edi            ; Pointer at last char
  1024.     pop    ESI
  1025.     pop    EDI
  1026.     pop    ebp
  1027.     ret
  1028. _strnmov    ENDP
  1029.     endcode strnmov
  1030.  
  1031. ;
  1032. ; Zortech has this one in standard library
  1033. ;
  1034.  
  1035.     begcode strmov
  1036.     public    _strmov
  1037. _strmov proc    near
  1038.     mov    ecx,esi            ; Save old esi and edi
  1039.     mov    edx,edi
  1040.     mov    esi,P[esp]        ; get source pointer (s2)
  1041.     mov    edi,P-SIZEPTR[esp]    ; EDI -> s1
  1042.     fix_es    1
  1043. @@:    mov    al,[esi]
  1044.     movsb                ; move arg
  1045.     and    al,al
  1046.     jnz    @B            ; Not last
  1047.     mov    eax,edi
  1048.     dec    eax
  1049.     mov    esi,ecx            ; Restore args
  1050.     mov    edi,edx
  1051.     ret
  1052. _strmov endp
  1053.     endcode strmov
  1054.  
  1055. endif ; M_I386
  1056.  
  1057.     END
  1058.