mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-30 04:26:45 +03:00 
			
		
		
		
	 6523aca729
			
		
	
	6523aca729
	
	
	
		
			
			Corrected spelling in copyright text Makefile.am: Don't update the files from BitKeeper Many files: Removed "MySQL Finland AB & TCX DataKonsult AB" from copyright header Adjusted year(s) in copyright header Many files: Added GPL copyright text Removed files: Docs/Support/colspec-fix.pl Docs/Support/docbook-fixup.pl Docs/Support/docbook-prefix.pl Docs/Support/docbook-split Docs/Support/make-docbook Docs/Support/make-makefile Docs/Support/test-make-manual Docs/Support/test-make-manual-de Docs/Support/xwf
		
			
				
	
	
		
			1061 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			1061 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
| ; Copyright (C) 2000, 2003 MySQL AB
 | |
| ; 
 | |
| ; This library is free software; you can redistribute it and/or
 | |
| ; modify it under the terms of the GNU Library General Public
 | |
| ; License as published by the Free Software Foundation; version 2
 | |
| ; of the License.
 | |
| ; 
 | |
| ; This library is distributed in the hope that it will be useful,
 | |
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
| ; Library General Public License for more details.
 | |
| ; 
 | |
| ; You should have received a copy of the GNU Library General Public
 | |
| ; License along with this library; if not, write to the Free
 | |
| ; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 | |
| ; MA 02111-1307, USA
 | |
| 
 | |
| ; Note that if you don't have a macro assembler (like MASM) to compile
 | |
| ; this file, you can instead compile all *.c files in the string
 | |
| ; directory.
 | |
| 
 | |
| 	TITLE   Stringfunctions that we use often at MSDOS / Intel 8086
 | |
| 
 | |
| ifndef M_I386
 | |
| 	.8087
 | |
| 	DOSSEG
 | |
| 	.MODEL LARGE
 | |
| 	.CODE
 | |
| 
 | |
| 	;
 | |
| 	; Some macros
 | |
| 	;
 | |
| 
 | |
| q_movs	MACRO				; as rep movsb but quicker
 | |
| 	shr	cx,1
 | |
| 	rep	movsw			; Move 2 bytes at a time
 | |
| 	adc	cx,cx
 | |
| 	rep	movsb			; Move last byte if any
 | |
| 	ENDM
 | |
| 
 | |
| q_stos	MACRO				; as rep stosb but quicker
 | |
| 	mov	ah,al			; For word store
 | |
| 	shr	cx,1
 | |
| 	rep	stosw			; Move 2 bytes at a time
 | |
| 	adc	cx,cx
 | |
| 	rep	stosb			; Move last byte if any
 | |
|  	ENDM
 | |
| 
 | |
| ifndef  ZTC				; If not using ZORTECH compiler
 | |
| 	;
 | |
| 	; Compare memory
 | |
| 	; Args: s1,s2,length
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_bcmp
 | |
| _bcmp	PROC
 | |
| 	mov	bx,bp			; Save bp
 | |
| 	mov	dx,di			; Save di
 | |
| 	mov	bp,sp
 | |
| 	push	ds
 | |
| 	push	si
 | |
| 	les	di,DWORD PTR [bp+8]	; s2
 | |
| 	lds	si,DWORD PTR [bp+4]	; s1
 | |
| 	mov	cx,WORD PTR [bp+12]	; Length of memory-area
 | |
| 	jcxz	@F			; Length = 0, return same
 | |
| ;	cld				; Work uppward
 | |
| 	repe	cmpsb			; Compare strings
 | |
| 	jz	@F			; Match found
 | |
| 	inc	cx			; return matchpoint +1
 | |
| @@:	mov	ax,cx			; Return 0 if match, else pos from end
 | |
| 	pop	si
 | |
| 	pop	ds
 | |
| 	mov	di,dx
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _bcmp	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Find a char in a string
 | |
| 	; Arg: str,char
 | |
| 	; Ret: pointer to found char or NullS
 | |
| 	;
 | |
| 
 | |
| ifdef better_stringfunctions		; Breaks window linkage (broken linking)
 | |
| 
 | |
| 	PUBLIC	_strchr
 | |
| _strchr	PROC
 | |
| 	mov	bx,bp			; Save bp and di
 | |
| 	mov	dx,di
 | |
| 	mov	bp,sp
 | |
| 	les	di,DWORD PTR [bp+4]	; str
 | |
| 	mov	ah,BYTE PTR [bp+8]	; search
 | |
| 	xor	al,al			; for scasb to find end
 | |
| 
 | |
| @@:	cmp	ah,es:[di]
 | |
| 	jz	@F			; Found char
 | |
| 	scasb
 | |
| 	jnz	@B			; Not end
 | |
| 	xor	di,di			; Not found
 | |
| 	mov	es,di
 | |
| @@:	mov	ax,di
 | |
| 	mov	di,dx			; Restore
 | |
| 	mov	dx,es			; Seg adr
 | |
| 	mov	bp,bx			; Restore
 | |
| 	ret
 | |
| _strchr	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Find length of string
 | |
| 	; arg: str
 | |
| 	; ret: length
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strlen
 | |
| _strlen	PROC
 | |
| 	mov	bx,sp
 | |
| 	mov	dx,di
 | |
| 	les	di,DWORD PTR ss:[bx+4]	; Str
 | |
| 	xor	al,al			; Find end of string
 | |
| 	mov	cx,-1
 | |
| ;	cld
 | |
| 	repne	scasb			; Find strend or length
 | |
| 	inc	cx			; Calc strlength
 | |
| 	not	cx
 | |
| 	mov	ax,cx
 | |
| 	mov	di,dx			; Restore register
 | |
| 	ret
 | |
| _strlen	ENDP
 | |
| 
 | |
| endif
 | |
| 
 | |
| 	;
 | |
| 	; Move a string
 | |
| 	; arg: dst,src
 | |
| 	; ret: end-null of to
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strmov
 | |
| _strmov	PROC
 | |
| 	mov	bx,bp
 | |
| 	mov	cx,si
 | |
| 	mov	bp,sp
 | |
| 	push	ds
 | |
| 	push	di
 | |
| 	les	di,DWORD PTR [bp+4]	; dst
 | |
| 	lds	si,DWORD PTR [bp+8]	; src
 | |
| ;	cld
 | |
| @@:	mov	al,ds:[si]
 | |
| 	movsb				; move arg
 | |
| 	and	al,al
 | |
| 	jnz	@B			; Not last
 | |
| 	lea	ax,WORD PTR [di-1]	; Set DX:AX to point at last null
 | |
| 	mov	dx,es
 | |
| 	pop	di
 | |
| 	pop	ds
 | |
| 	mov	si,cx
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _strmov	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Fill a area of memory with a walue
 | |
| 	; Args: to,length,fillchar
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_bfill
 | |
| _bfill	PROC
 | |
| 	mov	bx,sp			; Get args through BX
 | |
| 	mov	al,BYTE PTR ss:[bx+10]	; Fill
 | |
| bfill_10:
 | |
| 	mov	dx,di			; Save di
 | |
| 	les	di,DWORD PTR ss:[bx+4]	; Memory pointer
 | |
| 	mov	cx,WORD PTR ss:[bx+8]	; Length
 | |
| ;	cld
 | |
| 	q_stos
 | |
| 	mov	di,dx
 | |
| 	ret
 | |
| _bfill	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Fill a area with null
 | |
| 	; Args: to,length
 | |
| 
 | |
| 	PUBLIC	_bzero
 | |
| _bzero	PROC
 | |
| 	mov	bx,sp			; Get args through BX
 | |
| 	mov	al,0			; Fill with null
 | |
| 	jmp	short bfill_10
 | |
| _bzero	ENDP
 | |
| 
 | |
| endif	; ZTC
 | |
| 
 | |
| 	;
 | |
| 	; Move a memory area
 | |
| 	; Args: to,from,length
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_bmove
 | |
| _bmove	PROC
 | |
| 	mov	bx,bp
 | |
| 	mov	dx,di
 | |
| 	mov	ax,si
 | |
| 	mov	bp,sp
 | |
| 	push	ds
 | |
| 	lds	si,DWORD PTR [bp+8]	; from
 | |
| 	les	di,DWORD PTR [bp+4]	; to
 | |
| 	mov	cx,WORD PTR [bp+12]	; Length of memory-area
 | |
| ;	cld				; Work uppward
 | |
| 	rep	movsb			; Not q_movs because overlap ?
 | |
| 	pop	ds
 | |
| 	mov	si,ax
 | |
| 	mov	di,dx
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _bmove	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Move a alligned, not overlapped, by (long) divided memory area
 | |
| 	; Args: to,from,length
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_bmove_align
 | |
| _bmove_align	PROC
 | |
| 	mov	bx,bp
 | |
| 	mov	dx,di
 | |
| 	mov	ax,si
 | |
| 	mov	bp,sp
 | |
| 	push	ds
 | |
| 	lds	si,DWORD PTR [bp+8]	; from
 | |
| 	les	di,DWORD PTR [bp+4]	; to
 | |
| 	mov	cx,WORD PTR [bp+12]	; Length of memory-area
 | |
| ;	cld				; Work uppward
 | |
| 	inc	cx			; fix if not divisible with word
 | |
| 	shr	cx,1
 | |
| 	rep	movsw			; Move 2 bytes at a time
 | |
| 	pop	ds
 | |
| 	mov	si,ax
 | |
| 	mov	di,dx
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _bmove_align	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Move a string from higher to lower
 | |
| 	; Arg from+1,to+1,length
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_bmove_upp
 | |
| _bmove_upp	PROC
 | |
| 	mov	bx,bp
 | |
| 	mov	dx,di
 | |
| 	mov	ax,si
 | |
| 	mov	bp,sp
 | |
| 	push	ds
 | |
| 	lds	si,DWORD PTR [bp+8]	; from
 | |
| 	les	di,DWORD PTR [bp+4]	; to
 | |
| 	mov	cx,WORD PTR [bp+12]	; Length of memory-area
 | |
| 	dec	di			; Don't move last arg
 | |
| 	dec	si
 | |
| 	std				; Work downward
 | |
| 	rep	movsb			; Not q_movs because overlap ?
 | |
| 	cld				; C compilator want cld
 | |
| 	pop	ds
 | |
| 	mov	si,ax
 | |
| 	mov	di,dx
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _bmove_upp ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Append fillchars to string
 | |
| 	; Args: dest,len,fill
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strappend
 | |
| _strappend	PROC
 | |
| 	mov	bx,bp
 | |
| 	mov	dx,di
 | |
| 	mov	bp,sp
 | |
| 	les	di,DWORD PTR [bp+4]	; Memory pointer
 | |
| 	mov	cx,WORD PTR [bp+8]	; Length
 | |
| 	sub	al,al			; Find end of string
 | |
| ;	cld
 | |
| 	repne	scasb
 | |
| 	jnz	sa_99			; String to long, shorten it
 | |
| 	mov	al,BYTE PTR [bp+10]	; Fillchar
 | |
| 	dec	di			; Point at end null
 | |
| 	inc	cx			; rep made one dec for null-char
 | |
| 	q_stos				; Store al in string
 | |
| sa_99:	mov	BYTE PTR es:[di],0	; End of string
 | |
| 	mov	di,dx
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _strappend	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Find if string contains any char in another string
 | |
| 	; Arg: str,set
 | |
| 	; Ret: Pointer to first found char in str
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strcont
 | |
| _strcont	PROC
 | |
| 	mov	bx,bp			; Save bp and di in regs
 | |
| 	mov	dx,di
 | |
| 	mov	bp,sp
 | |
| 	push	ds
 | |
| 	push	si
 | |
| 	lds	si,DWORD PTR [bp+4]	; str
 | |
| 	les	di,DWORD PTR [bp+8]	; Set
 | |
| 	mov	cx,di			; Save for loop
 | |
| 	xor	ah,ah			; For endtest
 | |
| 	jmp	sc_60
 | |
| 
 | |
| sc_10:	scasb
 | |
| 	jz	sc_fo			; Found char
 | |
| sc_20:	cmp	ah,es:[di]		; Test if null
 | |
| 	jnz	sc_10			; Not end of set yet
 | |
| 	inc	si			; Next char in str
 | |
| 	mov	di,cx			; es:di = Set
 | |
| sc_60:	mov	al,ds:[si]		; Test if this char exist
 | |
| 	and	al,al
 | |
| 	jnz	sc_20			; Not end of string
 | |
| 	sub	si,si			; Return Null
 | |
| 	mov	ds,si
 | |
| sc_fo:	mov	ax,si			; Char found here
 | |
| 	mov	di,dx			; Restore
 | |
| 	mov	dx,ds			; Seg of found char
 | |
| 	pop	si
 | |
| 	pop	ds
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _strcont	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Found end of string
 | |
| 	; Arg: str
 | |
| 	; ret: Pointer to end null
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strend
 | |
| _strend	PROC
 | |
| 	mov	bx,sp
 | |
| 	mov	dx,di			; Save
 | |
| 	les	di,DWORD PTR ss:[bx+4]	; str
 | |
| 	mov	cx,-1
 | |
| 	sub	al,al			; Find end of string
 | |
| ;	cld
 | |
| 	repne	scasb
 | |
| 	lea	ax,WORD PTR [di-1]	; Endpos i DX:AX
 | |
| 	mov	di,dx			; Restore
 | |
| 	mov	dx,es
 | |
| 	ret
 | |
| _strend	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Make a string with len fill-chars and endnull
 | |
| 	; Args: dest,len,fill
 | |
| 	; Ret:  dest+len
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strfill
 | |
| _strfill	PROC
 | |
| 	mov	bx,bp			; Save sp
 | |
| 	mov	bp,sp
 | |
| 	push	di
 | |
| 	les	di,DWORD PTR [bp+4]	; Memory pointer
 | |
| 	mov	cx,WORD PTR [bp+8]	; Length
 | |
| 	mov	al,BYTE PTR [bp+10]	; Fill
 | |
| ;	cld
 | |
| 	q_stos
 | |
| 	mov	BYTE PTR es:[di],0	; End NULL
 | |
| 	mov	ax,di			; End i DX:AX
 | |
| 	mov	dx,es
 | |
| 	pop	di
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _strfill	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Find a char in or end of a string
 | |
| 	; Arg: str,char
 | |
| 	; Ret: pointer to found char or NullS
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strcend
 | |
| _strcend	PROC
 | |
| 	mov	bx,bp			; Save bp and di
 | |
| 	mov	dx,di
 | |
| 	mov	bp,sp
 | |
| 	les	di,DWORD PTR [bp+4]	; str
 | |
| 	mov	ah,BYTE PTR [bp+8]	; search
 | |
| 	xor	al,al			; for scasb to find end
 | |
| 
 | |
| @@:	cmp	ah,es:[di]
 | |
| 	jz	@F			; Found char
 | |
| 	scasb
 | |
| 	jnz	@B			; Not end
 | |
| 	dec 	di			; Not found, point at end of string
 | |
| @@:	mov	ax,di
 | |
| 	mov	di,dx			; Restore
 | |
| 	mov	dx,es			; Seg adr
 | |
| 	mov	bp,bx			; Restore
 | |
| 	ret
 | |
| _strcend	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Test if string has a given suffix
 | |
| 	;
 | |
| 
 | |
| PUBLIC  _is_prefix
 | |
| _is_prefix PROC
 | |
| 	mov	dx,di			; Save di
 | |
| 	mov	bx,sp			; Arguments through bx
 | |
| 	push	ds
 | |
| 	push	si
 | |
| 	les	di,DWORD PTR ss:[bx+8]	; s2
 | |
| 	lds	si,DWORD PTR ss:[bx+4]	; s1
 | |
| 	mov	ax,1			; Ok and zero-test
 | |
| ;	cld				; Work uppward
 | |
| @@:	cmp	ah,es:[di]
 | |
| 	jz	suf_ok			; End of string; found suffix
 | |
| 	cmpsb				; Compare strings
 | |
| 	jz	@B			; Same, possible prefix
 | |
| 	xor	ax,ax			; Not suffix
 | |
| suf_ok:	pop	si
 | |
| 	pop	ds
 | |
| 	mov	di,dx
 | |
| 	ret
 | |
| _is_prefix ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Find a substring in string
 | |
| 	; Arg: str,search
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strstr
 | |
| _strstr	PROC
 | |
| 	mov	bx,bp
 | |
| 	mov	bp,sp
 | |
| 	push	ds
 | |
| 	push	di
 | |
| 	push	si
 | |
| 	lds	si,DWORD PTR [bp+4]	; str
 | |
| 	les	di,DWORD PTR [bp+8]	; search
 | |
| 	mov	cx,di
 | |
| 	inc	cx			; CX = search+1
 | |
| 	mov	ah,es:[di]		; AH = First char in search
 | |
| 	jmp	sf_10
 | |
| 
 | |
| sf_00:	mov	si,dx			; si = Current str-pos
 | |
| sf_10:	mov	al,ds:[si]		; Test if this char exist
 | |
| 	and	al,al
 | |
| 	jz	sf_90			; End of string, didn't find search
 | |
| 	inc	si
 | |
| 	cmp	al,ah
 | |
| 	jnz	sf_10			; Didn't find first char, continue
 | |
| 	mov	dx,si			; Save str-pos in DX
 | |
| 	mov	di,cx
 | |
| sf_20:	cmp	BYTE PTR es:[di],0
 | |
| 	jz	sf_fo			; Found substring
 | |
| 	cmpsb
 | |
| 	jz	sf_20			; Char ok
 | |
| 	jmp	sf_00			; Next str-pos
 | |
| 
 | |
| sf_90:	sub	dx,dx			; Return Null
 | |
| 	mov	ds,dx
 | |
| 	inc	dx			; Because of following dec
 | |
| sf_fo:	mov	ax,dx			; Char found here
 | |
| 	dec	ax			; Pointed one after
 | |
| 	mov	dx,ds
 | |
| 	pop	si
 | |
| 	pop	di			; End
 | |
| 	pop	ds
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _strstr	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Find a substring in string, return index
 | |
| 	; Arg: str,search
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strinstr
 | |
| _strinstr	PROC
 | |
| 	push	bp
 | |
| 	mov	bp,sp
 | |
| 	push	di
 | |
| 	les	di,DWORD PTR [bp+10]	; search
 | |
| 	push	es
 | |
| 	push	di
 | |
| 	les	di,DWORD PTR [bp+6]	; str
 | |
| 	push	es
 | |
| 	push	di
 | |
| 	call	_strstr
 | |
| 	mov	cx,ax
 | |
| 	or	cx,dx
 | |
| 	jz	si_99
 | |
| 	sub	ax,di			; Pos from start
 | |
| 	inc	ax			; And first pos = 1
 | |
| si_99:	add	sp,8
 | |
| 	pop	di
 | |
| 	pop	bp
 | |
| 	ret
 | |
| _strinstr	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Make a string of len length from another string
 | |
| 	; Arg: dst,src,length
 | |
| 	; ret: end of dst
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strmake
 | |
| _strmake	PROC
 | |
| 	mov	bx,bp
 | |
| 	mov	bp,sp
 | |
| 	push	ds
 | |
| 	push	di
 | |
| 	push	si
 | |
| 	les	di,DWORD PTR [bp+4]	; dst
 | |
| 	lds	si,DWORD PTR [bp+8]	; src
 | |
| 	mov	cx,WORD PTR [bp+12]	; Length of memory-area
 | |
| 	xor	al,al			; For test of end-null
 | |
| 	jcxz	sm_90			; Nothing to move, put zero at end.
 | |
| ;	cld				; Work uppward
 | |
| 
 | |
| @@:	cmp	al,ds:[si]		; Next char to move
 | |
| 	movsb				; move arg
 | |
| 	jz	sm_99			; last char, we are ready
 | |
| 	loop	@B			; Continue moving
 | |
| sm_90:	mov	BYTE PTR es:[di],al	; Set end pos
 | |
| 	inc	di			; Fix that di points at end null
 | |
| sm_99:	dec	di			; di points now at end null
 | |
| 	mov	ax,di			; Ret value in DX:AX
 | |
| 	mov	dx,es
 | |
| 	pop	si
 | |
| 	pop	di
 | |
| 	pop	ds
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _strmake	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Find length of string with maxlength
 | |
| 	; arg: str,maxlength
 | |
| 	; ret: length
 | |
| 	;
 | |
| 
 | |
| 	PUBLIC	_strnlen
 | |
| _strnlen	PROC
 | |
| 	mov	bx,bp
 | |
| 	mov	bp,sp
 | |
| 	push	di
 | |
| 	les	di,DWORD PTR [bp+4]	; Str
 | |
| 	mov	cx,WORD PTR [bp+8]	; length
 | |
| 	mov	dx,di			; Save str to calc length
 | |
| 	jcxz	sn_10			; Length = 0
 | |
| 	xor	al,al			; Find end of string
 | |
| ;	cld
 | |
| 	repne	scasb			; Find strend or length
 | |
| 	jnz	sn_10
 | |
| 	dec	di			; DI points at last null
 | |
| sn_10:	mov	ax,di
 | |
| 	sub	ax,dx			; Ax = length
 | |
| 	pop	di
 | |
| 	mov	bp,bx
 | |
| 	ret
 | |
| _strnlen	ENDP
 | |
| 
 | |
| 	;
 | |
| 	; Move a string with max len chars
 | |
| 	; arg: dst,src,len
 | |
| 	; ret: pos to first null or dst+len
 | |
| 
 | |
| 	PUBLIC	_strnmov
 | |
| _strnmov	PROC
 | |
| 	mov	bx,bp
 | |
| 	mov	bp,sp
 | |
| 	push	ds
 | |
| 	push	di
 | |
| 	push	si
 | |
| 	les	di,DWORD PTR [bp+4]	; dst
 | |
| 	lds	si,DWORD PTR [bp+8]	; src
 | |
| 	mov	cx,WORD PTR [bp+12]	; length
 | |
| 	jcxz	snm_99			; Nothing to do
 | |
| 	xor	al,al			; For test of end-null
 | |
| ;	cld
 | |
| 
 | |
| @@:	cmp	al,ds:[si]		; Next char to move
 | |
| 	movsb				; move arg
 | |
| 	jz	snm_20			; last char, fill with null
 | |
| 	loop	@B			; Continue moving
 | |
| 	inc	di			; Point two after last
 | |
| snm_20:	dec	di			; Point at first null (or last+1)
 | |
| snm_99:	mov	ax,di			; Pointer at last char
 | |
| 	mov	dx,es			; To-segment
 | |
| 	pop	si
 | |
| 	pop	di
 | |
| 	pop	ds
 | |
| 	mov	bp,bx			; Restore
 | |
| 	ret
 | |
| _strnmov	ENDP
 | |
| 
 | |
| else	; M_I386
 | |
| 
 | |
| include macros.asm
 | |
| 
 | |
| q_stos	MACRO				; as rep stosb but quicker, Uses edx
 | |
| 	mov	ah,al			;(2) Set up a 32 bit pattern.
 | |
| 	mov	edx,eax			;(2)
 | |
| 	shl	edx,16			;(3)
 | |
| 	or	eax,edx			;(2) EAX has the 32 bit pattern.
 | |
| 
 | |
| 	mov	edx,ecx			;(2) Save the count of bytes.
 | |
| 	shr	ecx,2			;(2) Number of dwords.
 | |
| 	rep	stosd			;(5 + 5n)
 | |
| 	mov	cl,3			;(2)
 | |
| 	and	ecx,edx			;(2) Fill in the remaining odd bytes.
 | |
| 	rep	stosb			; Move last bytes if any
 | |
| 	ENDM
 | |
| 
 | |
| fix_es	MACRO	fix_cld			; Load ES if neaded
 | |
|   ife ESeqDS
 | |
| 	mov	ax,ds
 | |
| 	mov	es,ax
 | |
|   endif
 | |
|   ifnb <fix_cld>
 | |
| 	cld
 | |
|   endif
 | |
| 	ENDM
 | |
| 
 | |
| 	;
 | |
| 	; Move a memory area
 | |
| 	; Args: to,from,length
 | |
| 	; Acts as one byte was moved a-time from dst to source.
 | |
| 	;
 | |
| 
 | |
| 	begcode bmove
 | |
| 	public	_bmove
 | |
| _bmove	proc near
 | |
| 	fix_es	1
 | |
| 	mov	edx,edi
 | |
| 	mov	eax,esi
 | |
| 	mov	edi,P-SIZEPTR[esp]	;p1
 | |
| 	mov	esi,P[esp]		;p2
 | |
| 	mov	ecx,P+SIZEPTR[esp]
 | |
| 	rep	movsb			; Not q_movs because overlap ?
 | |
| 	mov	esi,eax
 | |
| 	mov	edi,edx
 | |
| 	ret
 | |
| _bmove	ENDP
 | |
| 	endcode bmove
 | |
| 
 | |
| 	;
 | |
| 	; Move a alligned, not overlapped, by (long) divided memory area
 | |
| 	; Args: to,from,length
 | |
| 	;
 | |
| 
 | |
| 	begcode	bmove_align
 | |
| 	public	_bmove_align
 | |
| _bmove_align	proc near
 | |
| 	fix_es	1
 | |
| 	mov	edx,edi
 | |
| 	mov	eax,esi
 | |
| 	mov	edi,P-SIZEPTR[esp]	;to
 | |
| 	mov	esi,P[esp]		;from
 | |
| 	mov	ecx,P+SIZEPTR[esp]	;length
 | |
| 	add	cx,3			;fix if not divisible with long
 | |
| 	shr	cx,2
 | |
| 	rep	movsd
 | |
| 	mov	esi,eax
 | |
| 	mov	edi,edx
 | |
| 	ret
 | |
| _bmove_align	ENDP
 | |
| 	endcode bmove_align
 | |
| 
 | |
| 	;
 | |
| 	; Move a string from higher to lower
 | |
| 	; Arg from+1,to+1,length
 | |
| 	;
 | |
| 
 | |
| 	begcode	bmove_upp
 | |
| 	public	_bmove_upp
 | |
| _bmove_upp	proc near
 | |
| 	fix_es
 | |
| 	std				; Work downward
 | |
| 	mov	edx,edi
 | |
| 	mov	eax,esi
 | |
| 	mov	edi,P-SIZEPTR[esp]	;p1
 | |
| 	mov	esi,P[esp]		;p2
 | |
| 	mov	ecx,P+SIZEPTR[esp]
 | |
| 	dec	edi			; Don't move last arg
 | |
| 	dec	esi
 | |
| 	rep	movsb			; One byte a time because overlap !
 | |
| 	cld				; C compilator wants cld
 | |
| 	mov	esi,eax
 | |
| 	mov	edi,edx
 | |
| 	ret
 | |
| _bmove_upp ENDP
 | |
| 	endcode bmove_upp
 | |
| 
 | |
| 	;
 | |
| 	; Append fillchars to string
 | |
| 	; Args: dest,len,fill
 | |
| 	;
 | |
| 
 | |
| 	begcode	strappend
 | |
| 	public	_strappend
 | |
| _strappend	proc near
 | |
| 	push	ebp
 | |
| 	mov	ebp,esp
 | |
| 	fix_es  1
 | |
| 	push	edi
 | |
| 	mov	edi,P[ebp]		; Memory pointer
 | |
| 	mov	ecx,P+SIZEPTR[ebp]	; Length
 | |
| 	clr	eax			; Find end of string
 | |
| 	repne	scasb
 | |
| 	jnz	sa_99			; String to long, shorten it
 | |
| 	movzx	eax,byte ptr P+(2*SIZEPTR)[ebp]	; Fillchar
 | |
| 	dec	edi			; Point at end null
 | |
| 	inc	ecx			; rep made one dec for null-char
 | |
| 	q_stos				; Store al in string
 | |
| sa_99:	mov	BYTE PTR [edi],0	; End of string
 | |
| 	pop	edi
 | |
| 	pop	ebp
 | |
| 	ret
 | |
| _strappend	ENDP
 | |
| 	endcode strappend
 | |
| 
 | |
| 	;
 | |
| 	; Find if string contains any char in another string
 | |
| 	; Arg: str,set
 | |
| 	; Ret: Pointer to first found char in str
 | |
| 	;
 | |
| 
 | |
| 	begcode strcont
 | |
| 	PUBLIC	_strcont
 | |
| _strcont proc near
 | |
| 	push	ebp
 | |
| 	mov	ebp,esp
 | |
| 	fix_es	1
 | |
| 	mov	edx,edi
 | |
| 	push	esi
 | |
| 	mov	esi,P[ebp]		; str
 | |
| 	mov	ecx,P+SIZEPTR[ebp]	; Set
 | |
| 	clr	ah			; For endtest
 | |
| 	jmps	sc_60
 | |
| 
 | |
| sc_10:	scasb
 | |
| 	jz	sc_fo			; Found char
 | |
| sc_20:	cmp	ah,[edi]		; Test if null
 | |
| 	jnz	sc_10			; Not end of set yet
 | |
| 	inc	esi			; Next char in str
 | |
| sc_60:	mov	edi,ecx			; edi = Set
 | |
| 	mov	al,[esi]		; Test if this char exist
 | |
| 	and	al,al
 | |
| 	jnz	sc_20			; Not end of string
 | |
| 	clr	esi			; Return Null
 | |
| sc_fo:	mov	eax,esi			; Char found here
 | |
| 	mov	edi,edx			; Restore
 | |
| 	pop	esi
 | |
| 	pop	ebp
 | |
| 	ret
 | |
| _strcont	ENDP
 | |
| 	endcode strcont
 | |
| 
 | |
| 	;
 | |
| 	; Found end of string
 | |
| 	; Arg: str
 | |
| 	; ret: Pointer to end null
 | |
| 	;
 | |
| 
 | |
| 	begcode strend
 | |
| 	public	_strend
 | |
| _strend	proc near
 | |
| 	fix_es	1
 | |
| 	mov	edx,edi			; Save
 | |
| 	mov	edi,P-SIZEPTR[esp]	; str
 | |
| 	clr	eax			; Find end of string
 | |
| 	mov	ecx,eax
 | |
| 	dec	ecx			; ECX = -1
 | |
| 	repne	scasb
 | |
| 	mov	eax,edi
 | |
| 	dec	eax
 | |
| 	mov	edi,edx			; Restore
 | |
| 	ret
 | |
| _strend	endp
 | |
| 	endcode strend
 | |
| 
 | |
| 	;
 | |
| 	; Make a string with len fill-chars and endnull
 | |
| 	; Args: dest,len,fill
 | |
| 	; Ret:  dest+len
 | |
| 	;
 | |
| 
 | |
| 	begcode	strfill
 | |
| 	public	_strfill
 | |
| _strfill proc near
 | |
| 	push	ebp
 | |
| 	mov	ebp,esp
 | |
| 	fix_es  1
 | |
| 	push	edi
 | |
| 	mov	edi,P[ebp]		; Memory pointer
 | |
| 	mov	ecx,P+SIZEPTR[ebp]	; Length
 | |
| 	movzx	eax,byte ptr P+(2*SIZEPTR)[ebp]	; Fill
 | |
| 	q_stos
 | |
| 	mov	BYTE PTR [edi],0	; End NULL
 | |
| 	mov	eax,edi			; End i DX:AX
 | |
| 	pop	edi
 | |
| 	pop	ebp
 | |
| 	ret
 | |
| _strfill endp
 | |
| 	endcode strfill
 | |
| 
 | |
| 	;
 | |
| 	; Find a char in or end of a string
 | |
| 	; Arg: str,char
 | |
| 	; Ret: pointer to found char or NullS
 | |
| 	;
 | |
| 
 | |
| 	begcode strcend
 | |
| 	public	_strcend
 | |
| _strcend proc near
 | |
| 	push	ebp
 | |
| 	mov	ebp,esp
 | |
| 	fix_es  1
 | |
| 	mov	edx,edi
 | |
| 	mov	edi,P[ebp]		; str
 | |
| 	mov	ah,P+SIZEPTR[ebp]	; search
 | |
| 	clr	al			; for scasb to find end
 | |
| 
 | |
| @@:	cmp	ah,[edi]
 | |
| 	jz	@F			; Found char
 | |
| 	scasb
 | |
| 	jnz	@B			; Not end
 | |
| 	dec 	edi			; Not found, point at end of string
 | |
| @@:	mov	eax,edi
 | |
| 	mov	edi,edx			; Restore
 | |
| 	pop	ebp
 | |
| 	ret
 | |
| _strcend	ENDP
 | |
| 	endcode strcend
 | |
| 
 | |
| 	;
 | |
| 	; Test if string has a given suffix
 | |
| 	;
 | |
| 
 | |
| 	begcode is_prefix
 | |
| 	public	_is_prefix
 | |
| _is_prefix proc near
 | |
| 	fix_es	1
 | |
| 	mov	edx,edi			; Save edi
 | |
| 	mov	eax,esi			; Save esi
 | |
| 	mov	esi,P[esp]		; get suffix
 | |
| 	mov	edi,P-SIZEPTR[esp]	; s1
 | |
| 	push	eax			; push esi
 | |
| 	mov	eax,1			; Ok and zero-test
 | |
| @@:	cmp	ah,[esi]
 | |
| 	jz	suf_ok			; End of string; found suffix
 | |
| 	cmpsb				; Compare strings
 | |
| 	jz	@B			; Same, possible prefix
 | |
| 	xor	eax,eax			; Not suffix
 | |
| suf_ok:	pop	esi
 | |
| 	mov	edi,edx
 | |
| 	ret
 | |
| _is_prefix endp
 | |
| 	endcode	_is_prefix
 | |
| 
 | |
| 	;
 | |
| 	; Find a substring in string
 | |
| 	; Arg: str,search
 | |
| 	;
 | |
| 
 | |
| 	begcode strstr
 | |
| 	public	_strstr
 | |
| _strstr proc near
 | |
| 	push	ebp
 | |
| 	mov	ebp,esp
 | |
| 	fix_es	1
 | |
| 	push	EDI
 | |
| 	push	ESI
 | |
| 	mov	esi,P[ebp]		; str
 | |
| 	mov	edi,P+SIZEPTR[ebp]	; search
 | |
| 	mov	ecx,edi
 | |
| 	inc	ecx			; ECX = search+1
 | |
| 	mov	ah,[edi]		; AH = First char in search
 | |
| 	jmps	sf_10
 | |
| 
 | |
| sf_00:	mov	esi,edx			; si = Current str-pos
 | |
| sf_10:	mov	al,[esi]		; Test if this char exist
 | |
| 	and	al,al
 | |
| 	jz	sf_90			; End of string, didn't find search
 | |
| 	inc	esi
 | |
| 	cmp	al,ah
 | |
| 	jnz	sf_10			; Didn't find first char, continue
 | |
| 	mov	edx,esi			; Save str-pos in EDX
 | |
| 	mov	edi,ecx
 | |
| sf_20:	cmp	BYTE PTR [edi],0
 | |
| 	jz	sf_fo			; Found substring
 | |
| 	cmpsb
 | |
| 	jz	sf_20			; Char ok
 | |
| 	jmps	sf_00			; Next str-pos
 | |
| 
 | |
| sf_90:	mov	edx,1			; Return Null
 | |
| sf_fo:	mov	eax,edx			; Char found here
 | |
| 	dec	eax			; Pointed one after
 | |
| 	pop	ESI
 | |
| 	pop	EDI
 | |
| 	pop	ebp
 | |
| 	ret
 | |
| _strstr endp
 | |
| 	endcode strstr
 | |
| 
 | |
| 	;
 | |
| 	; Find a substring in string, return index
 | |
| 	; Arg: str,search
 | |
| 	;
 | |
| 
 | |
| 	begcode	strinstr
 | |
| 	public	_strinstr
 | |
| _strinstr proc near
 | |
| 	push	ebp
 | |
| 	mov	ebp,esp
 | |
| 	push	P+SIZEPTR[ebp]		; search
 | |
| 	push	P[ebp]			; str
 | |
| 	call	_strstr
 | |
| 	add	esp,SIZEPTR*2
 | |
| 	or	eax,eax
 | |
| 	jz	si_99			; Not found, return NULL
 | |
| 	sub	eax,P[ebp]		; Pos from start
 | |
| 	inc	eax			; And first pos = 1
 | |
| si_99:	pop	ebp
 | |
| 	ret
 | |
| _strinstr	endp
 | |
| 	endcode strinstr
 | |
| 
 | |
| 	;
 | |
| 	; Make a string of len length from another string
 | |
| 	; Arg: dst,src,length
 | |
| 	; ret: end of dst
 | |
| 	;
 | |
| 
 | |
| 	begcode strmake
 | |
| 	public	_strmake
 | |
| _strmake proc near
 | |
| 	push	ebp
 | |
| 	mov	ebp,esp
 | |
| 	fix_es	1
 | |
| 	push	EDI
 | |
| 	push	ESI
 | |
| 	mov	edi,P[ebp]		; dst
 | |
| 	mov	esi,P+SIZEPTR[ebp]	; src
 | |
| 	mov	ecx,P+SIZEPTR*2[ebp]	; Length of memory-area
 | |
| 	clr	al			; For test of end-null
 | |
| 	jcxz	sm_90			; Nothing to move, put zero at end.
 | |
| 
 | |
| @@:	cmp	al,[esi]		; Next char to move
 | |
| 	movsb				; move arg
 | |
| 	jz	sm_99			; last char, we are ready
 | |
| 	loop	@B			; Continue moving
 | |
| sm_90:	mov	BYTE PTR [edi],al	; Set end pos
 | |
| 	inc	edi			; Fix that di points at end null
 | |
| sm_99:	dec	edi			; di points now at end null
 | |
| 	mov	eax,edi			; Ret value in DX:AX
 | |
| 	pop	ESI
 | |
| 	pop	EDI
 | |
| 	pop	ebp
 | |
| 	ret
 | |
| _strmake	ENDP
 | |
| 	endcode strmake
 | |
| 
 | |
| 	;
 | |
| 	; Find length of string with maxlength
 | |
| 	; arg: str,maxlength
 | |
| 	; ret: length
 | |
| 	;
 | |
| 
 | |
| 	begcode	strnlen
 | |
| 	public	_strnlen
 | |
| _strnlen proc near
 | |
| 	push	ebp
 | |
| 	mov	ebp,esp
 | |
| 	fix_es	1
 | |
| 	push	edi
 | |
| 	mov	edi,P[ebp]		; Str
 | |
| 	mov	ecx,P+SIZEPTR[ebp]	; length
 | |
| 	mov	edx,edi			; Save str to calc length
 | |
| 	jcxz	sn_10			; Length = 0
 | |
| 	clr	al			; Find end of string
 | |
| 	repne	scasb			; Find strend or length
 | |
| 	jnz	sn_10
 | |
| 	dec	edi			; DI points at last null
 | |
| sn_10:	mov	eax,edi
 | |
| 	sub	eax,edx			; Ax = length
 | |
| 	pop	edi
 | |
| 	pop	ebp
 | |
| 	ret
 | |
| _strnlen	ENDP
 | |
| 	endcode strnlen
 | |
| 
 | |
| 	;
 | |
| 	; Move a string with max len chars
 | |
| 	; arg: dst,src,len
 | |
| 	; ret: pos to first null or dst+len
 | |
| 
 | |
| 	begcode	strnmov
 | |
| 	public	_strnmov
 | |
| _strnmov PROC near
 | |
| 	push	ebp
 | |
| 	mov	ebp,esp
 | |
| 	fix_es	1
 | |
| 	push	EDI
 | |
| 	push	ESI
 | |
| 	mov	edi,P[ebp]		; dst
 | |
| 	mov	esi,P+SIZEPTR[ebp]	; src
 | |
| 	mov	ecx,P+(SIZEPTR*2)[ebp]	; length
 | |
| 	jcxz	snm_99			; Nothing to do
 | |
| 	clr	al			; For test of end-null
 | |
| 
 | |
| @@:	cmp	al,[esi]		; Next char to move
 | |
| 	movsb				; move arg
 | |
| 	jz	snm_20			; last char, fill with null
 | |
| 	loop	@B			; Continue moving
 | |
| 	inc	edi			; Point two after last
 | |
| snm_20:	dec	edi			; Point at first null (or last+1)
 | |
| snm_99:	mov	eax,edi			; Pointer at last char
 | |
| 	pop	ESI
 | |
| 	pop	EDI
 | |
| 	pop	ebp
 | |
| 	ret
 | |
| _strnmov	ENDP
 | |
| 	endcode strnmov
 | |
| 
 | |
| ;
 | |
| ; Zortech has this one in standard library
 | |
| ;
 | |
| 
 | |
| 	begcode strmov
 | |
| 	public	_strmov
 | |
| _strmov proc	near
 | |
| 	mov	ecx,esi			; Save old esi and edi
 | |
| 	mov	edx,edi
 | |
| 	mov	esi,P[esp]		; get source pointer (s2)
 | |
| 	mov	edi,P-SIZEPTR[esp]	; EDI -> s1
 | |
| 	fix_es	1
 | |
| @@:	mov	al,[esi]
 | |
| 	movsb				; move arg
 | |
| 	and	al,al
 | |
| 	jnz	@B			; Not last
 | |
| 	mov	eax,edi
 | |
| 	dec	eax
 | |
| 	mov	esi,ecx			; Restore args
 | |
| 	mov	edi,edx
 | |
| 	ret
 | |
| _strmov endp
 | |
| 	endcode strmov
 | |
| 
 | |
| endif ; M_I386
 | |
| 
 | |
| 	END
 |