Commit 4508fbb5 authored by monty@tik.mysql.fi's avatar monty@tik.mysql.fi
Browse files

Use portable comments in assembler files

parent cb3499b7
Loading
Loading
Loading
Loading
+20 −4
Original line number Diff line number Diff line
@@ -566,7 +566,8 @@ a commercial memory leakage detector.
@item
Works on many different platforms.  @xref{Which OS}.
@item
Uses GNU Automake, Autoconf (Ver 2.52 or newer), and Libtool for portability.
Uses GNU Automake (1.4), Autoconf (Ver 2.52 or newer), and Libtool for
portability.
@item
APIs for C, C++, Eiffel, Java, Perl, PHP, Python and Tcl.  @xref{Clients}.
@item
@@ -7015,11 +7016,10 @@ The initial download of the source tree may take a while, depending on the
speed of your connection; be patient.
@item
You will need GNU @code{autoconf 2.13}, @code{automake 1.4},
You will need GNU @code{autoconf 2.52}, @code{automake 1.4},
@code{libtool}, and @code{m4} to run the next set of commands.
If you are using the 3.23 tree the new versions of @code{autoconf}
(2.52) and @code{automake} (1.5) will not work.
@code{automake} (1.5) doesn't yet work.
If you get some strange error during this stage, check that you really
have @code{libtool} installed!
@@ -13707,6 +13707,13 @@ tell @code{mysql} to read its input from the file:
shell> mysql < batch-file
@end example
If you are running @code{mysql} under windows and have some special
characters in the file that causes problems, you can do:
@example
dos> mysql -e "source batch-file"
@end example
If you need to specify connection parameters on the command line, the
command might look like this:
@@ -13718,6 +13725,9 @@ Enter password: ********
When you use @code{mysql} this way, you are creating a script file, then
executing the script.
If you want the script to continue even if you have errors, you should
use the @code{--force} command line option.
Why use a script?  Here are a few reasons:
@itemize @bullet
@@ -13791,6 +13801,12 @@ If you want to get the interactive output format in batch mode, use
@code{mysql -t}.  To echo to the output the commands that are executed, use
@code{mysql -vvv}.
You can also use scripts in the @code{mysql} command line prompt by
using the @code{source} command:
@example
mysql> source filename
@end example
@node Twin, Apache, Batch mode, Tutorial
@section Queries from Twin Project
+14 −15
Original line number Diff line number Diff line
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program 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 General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
# Copyright (C) 2000 MySQL AB
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# Optimized longlong2str function for Intel 80x86  (gcc/gas syntax) 
# Some set sequences are optimized for pentuimpro II 
+188 −189
Original line number Diff line number Diff line
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
   
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
   
   This program 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 General Public License for more details.
   
   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/* Optimized string functions Intel 80x86  (gcc/gas syntax) */
# Copyright (C) 2000 MySQL AB
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

# Optimized string functions Intel 80x86  (gcc/gas syntax)

	.file	"strings.s"
	.version "1.00"

.text

	/*  Move a alligned, not overlapped, by (long) divided memory area */
	/*  Args: to,from,length */
#	Move a alligned, not overlapped, by (long) divided memory area
#	Args: to,from,length

.globl bmove_allign
	.type	 bmove_allign,@function
bmove_allign:	
	movl	%edi,%edx
	movl	%esi,%eax
	movl	4(%esp),%edi		/* to */
	movl	8(%esp),%esi		/* from */
	movl	12(%esp),%ecx		/* length */
	addw	$3,%cx			/* fix if not divisible with long */
	movl	4(%esp),%edi		# to
	movl	8(%esp),%esi		# from
	movl	12(%esp),%ecx		# length
	addw	$3,%cx			# fix if not divisible with long
	shrw	$2,%cx
	rep
	movsl
@@ -42,198 +41,198 @@ bmove_allign:
.end:
	.size	 bmove_allign,.end-bmove_allign

	/* Move a string from higher to lower */
	/* Arg from+1,to+1,length */
	# Move a string from higher to lower
	# Arg from+1,to+1,length

.globl bmove_upp
	.type bmove_upp,@function
bmove_upp:	
	std				/*  Work downward */
	std				#  Work downward
	movl	%edi,%edx
	movl	%esi,%eax
	movl	4(%esp),%edi		/* p1 */
	movl	8(%esp),%esi		/* p2 */
	movl	12(%esp),%ecx		/* length */
	decl	%edi			/*  Don't move last arg */
	movl	4(%esp),%edi		# p1
	movl	8(%esp),%esi		# p2
	movl	12(%esp),%ecx		# length
	decl	%edi			#  Don't move last arg
	decl	%esi
	rep
	movsb				/*  One byte a time because overlap */
	cld				/*  C library wants cld */
	movsb				#  One byte a time because overlap
	cld				#  C library wants cld
	movl	%eax,%esi
	movl	%edx,%edi
	ret
.bmove_upp_end:	
	.size bmove_upp,.bmove_upp_end-bmove_upp

	/* Append fillchars to string */
	/* Args: dest,len,fill */
	# Append fillchars to string
	# Args: dest,len,fill

.globl strappend
	.type strappend,@function
strappend:	
	pushl	%edi
	movl	8(%esp),%edi		/*  Memory pointer */
	movl	12(%esp),%ecx		/*  Length */
	clrl	%eax			/*  Find end of string */
	movl	8(%esp),%edi		#  Memory pointer
	movl	12(%esp),%ecx		#  Length
	clrl	%eax			#  Find end of string
	repne
	scasb
	jnz	sa_99			/*  String to long, shorten it */
	movzb	16(%esp),%eax		/*  Fillchar */
	decl	%edi			/*  Point at end null */
	incl	%ecx			/*  rep made one dec for null-char */

	movb	%al,%ah			/* (2) Set up a 32 bit pattern. */
	movw	%ax,%dx			/* (2) */
	shll	$16,%eax		/* (3) */
	movw	%dx,%ax			/* (2) %eax has the 32 bit pattern. */

	movl	%ecx,%edx		/* (2) Save the count of bytes. */
	shrl	$2,%ecx			/* (2) Number of dwords. */
	jnz	sa_99			#  String to long, shorten it
	movzb	16(%esp),%eax		#  Fillchar
	decl	%edi			#  Point at end null
	incl	%ecx			#  rep made one dec for null-char

	movb	%al,%ah			# (2) Set up a 32 bit pattern.
	movw	%ax,%dx			# (2)
	shll	$16,%eax		# (3)
	movw	%dx,%ax			# (2) %eax has the 32 bit pattern.

	movl	%ecx,%edx		# (2) Save the count of bytes.
	shrl	$2,%ecx			# (2) Number of dwords.
	rep
	stosl				/* (5 + 5n) */
	movb	$3,%cl			/* (2) */
	and	%edx,%ecx		/* (2) Fill in the odd bytes*/
	stosl				# (5 + 5n)
	movb	$3,%cl			# (2)
	and	%edx,%ecx		# (2) Fill in the odd bytes
	rep
	stosb				/*  Move last bytes if any */
	stosb				#  Move last bytes if any

sa_99:	movb	$0,(%edi)		/*  End of string */
sa_99:	movb	$0,(%edi)		#  End of string
	popl	%edi
	ret
.strappend_end:	
	.size strappend,.strappend_end-strappend

	/* Find if string contains any char in another string */
	/* Arg: str,set */
	/* Ret: Pointer to first found char in str */
	# Find if string contains any char in another string
	# Arg: str,set
	# Ret: Pointer to first found char in str

.globl strcont
	.type strcont,@function
strcont:	
	movl	%edi,%edx
	pushl	%esi
	movl	8(%esp),%esi		/*  str */
	movl	12(%esp),%ecx		/*  set */
	clrb	%ah			/*  For endtest */
	movl	8(%esp),%esi		#  str
	movl	12(%esp),%ecx		#  set
	clrb	%ah			#  For endtest
	jmp	sc_60

sc_10:	scasb
	jz	sc_fo			/*  Found char */
sc_20:	cmp	(%edi),%ah		/*  Test if null */
	jnz	sc_10			/*  Not end of set yet */
	incl	%esi			/*  Next char in str */
sc_60:	movl	%ecx,%edi		/*  %edi = Set */
	movb	(%esi),%al		/*  Test if this char exist */
	jz	sc_fo			#  Found char
sc_20:	cmp	(%edi),%ah		#  Test if null
	jnz	sc_10			#  Not end of set yet
	incl	%esi			#  Next char in str
sc_60:	movl	%ecx,%edi		#  %edi = Set
	movb	(%esi),%al		#  Test if this char exist
	andb	%al,%al
	jnz	sc_20			/*  Not end of string */
	clrl	%esi			/*  Return Null */
sc_fo:	movl	%esi,%eax		/*  Char found here */
	movl	%edx,%edi		/*  Restore */
	jnz	sc_20			#  Not end of string
	clrl	%esi			#  Return Null
sc_fo:	movl	%esi,%eax		#  Char found here
	movl	%edx,%edi		#  Restore
	popl	%esi
	ret
.strcont_end:	
	.size strcont,.strcont_end-strcont

	/* Find end of string */
	/* Arg: str */
	/* ret: Pointer to end null */
	# Find end of string
	# Arg: str
	# ret: Pointer to end null

.globl strend
	.type strend,@function
strend:	
	movl	%edi,%edx		/*  Save */
	movl	4(%esp),%edi		/*  str */
	clrl	%eax			/*  Find end of string */
	movl	%edi,%edx		#  Save
	movl	4(%esp),%edi		#  str
	clrl	%eax			#  Find end of string
	movl	%eax,%ecx
	decl	%ecx			/*  ECX = -1 */
	decl	%ecx			#  ECX = -1
	repne
	scasb
	movl	%edi,%eax
	decl	%eax			/*  End of string */
	movl	%edx,%edi		/*  Restore */
	decl	%eax			#  End of string
	movl	%edx,%edi		#  Restore
	ret
.strend_end:	
	.size strend,.strend_end-strend

	/* Make a string with len fill-chars and endnull */
	/* Args: dest,len,fill */
	/* Ret:  dest+len */
	# Make a string with len fill-chars and endnull
	# Args: dest,len,fill
	# Ret:  dest+len

.globl strfill
	.type strfill,@function
strfill:
	pushl	%edi
	movl	8(%esp),%edi		/*  Memory pointer */
	movl	12(%esp),%ecx		/*  Length */
	movzb	16(%esp),%eax		/*  Fill */
	movl	8(%esp),%edi		#  Memory pointer
	movl	12(%esp),%ecx		#  Length
	movzb	16(%esp),%eax		#  Fill

	movb	%al,%ah			/* (2) Set up a 32 bit pattern */
	movw	%ax,%dx			/* (2) */
	shll	$16,%eax		/* (3) */
	movw	%dx,%ax			/* (2) %eax has the 32 bit pattern. */
	movb	%al,%ah			# (2) Set up a 32 bit pattern
	movw	%ax,%dx			# (2)
	shll	$16,%eax		# (3)
	movw	%dx,%ax			# (2) %eax has the 32 bit pattern.

	movl	%ecx,%edx		/* (2) Save the count of bytes. */
	shrl	$2,%ecx			/* (2) Number of dwords. */
	movl	%ecx,%edx		# (2) Save the count of bytes.
	shrl	$2,%ecx			# (2) Number of dwords.
	rep
	stosl				/* (5 + 5n) */
	movb	$3,%cl			/* (2) */
	and	%edx,%ecx		/* (2) Fill in the odd bytes */
	stosl				# (5 + 5n)
	movb	$3,%cl			# (2)
	and	%edx,%ecx		# (2) Fill in the odd bytes
	rep
	stosb				/*  Move last bytes if any */
	stosb				#  Move last bytes if any

	movb	%cl,(%edi)		/*  End NULL */
	movl	%edi,%eax		/*  End i %eax */
	movb	%cl,(%edi)		#  End NULL
	movl	%edi,%eax		#  End i %eax
	popl	%edi
	ret
.strfill_end:	
	.size strfill,.strfill_end-strfill


	/* Find a char in or end of a string */
	/* Arg: str,char */
	/* Ret: pointer to found char or NullS */
	# Find a char in or end of a string
	# Arg: str,char
	# Ret: pointer to found char or NullS

.globl strcend
	.type strcend,@function
strcend:
	movl	%edi,%edx
	movl	4(%esp),%edi		/* str */
	movb	8(%esp),%ah		/* search */
	clrb	%al			/* for scasb to find end */
	movl	4(%esp),%edi		# str
	movb	8(%esp),%ah		# search
	clrb	%al			# for scasb to find end

se_10:	cmpb	(%edi),%ah
	jz	se_20			/* Found char */
	jz	se_20			# Found char
	scasb
	jnz	se_10			/* Not end */
	dec 	%edi			/* Not found, point at end of string */
	jnz	se_10			# Not end
	dec 	%edi			# Not found, point at end of string
se_20:	movl	%edi,%eax
	movl	%edx,%edi		/* Restore */
	movl	%edx,%edi		# Restore
	ret
.strcend_end:	
	.size strcend,.strcend_end-strcend

	/* Test if string has a given suffix */
	# Test if string has a given suffix

.globl is_prefix
	.type is_prefix,@function
is_prefix:	
	movl	%edi,%edx		/* Save %edi */
	pushl	%esi			/* and %esi */
	movl	12(%esp),%esi		/* get suffix */
	movl	8(%esp),%edi		/* s1 */
	movl	$1,%eax			/* Ok and zero-test */
	movl	%edi,%edx		# Save %edi
	pushl	%esi			# and %esi
	movl	12(%esp),%esi		# get suffix
	movl	8(%esp),%edi		# s1
	movl	$1,%eax			# Ok and zero-test
ip_10:	cmpb	(%esi),%ah
	jz	suf_ok			/* End of string/ found suffix */
	cmpsb				/* Compare strings */
	jz	ip_10			/* Same, possible prefix */
	xor	%eax,%eax		/* Not suffix */
	jz	suf_ok			# End of string/ found suffix
	cmpsb				# Compare strings
	jz	ip_10			# Same, possible prefix
	xor	%eax,%eax		# Not suffix
suf_ok:	popl	%esi
	movl	%edx,%edi
	ret
.is_prefix_end:	
	.size is_prefix,.is_prefix_end-is_prefix

	/* Find a substring in string */
	/* Arg: str,search */
	# Find a substring in string
	# Arg: str,search

.globl strstr
	.type strstr,@function
@@ -241,31 +240,31 @@ suf_ok: popl %esi
strstr:	
	pushl	%edi
	pushl	%esi
	movl	12(%esp),%esi		/*  str */
	movl	16(%esp),%edi		/*  search */
	movl	12(%esp),%esi		#  str
	movl	16(%esp),%edi		#  search
	movl	%edi,%ecx
	incl	%ecx			/*  %ecx = search+1 */
	movb	(%edi),%ah		/*  %ah = First char in search */
	incl	%ecx			#  %ecx = search+1
	movb	(%edi),%ah		#  %ah = First char in search
	jmp	sf_10

sf_00:	movl	%edx,%esi		/*  si = Current str-pos */
sf_10:	movb	(%esi),%al		/*  Test if this char exist */
sf_00:	movl	%edx,%esi		#  si = Current str-pos
sf_10:	movb	(%esi),%al		#  Test if this char exist
	andb	%al,%al
	jz	sf_90			/*  End of string, didn't find search */
	jz	sf_90			#  End of string, didn't find search
	incl	%esi
	cmpb	%al,%ah
	jnz	sf_10			/*  Didn't find first char, continue */
	movl	%esi,%edx		/*  Save str-pos in %edx */
	jnz	sf_10			#  Didn't find first char, continue
	movl	%esi,%edx		#  Save str-pos in %edx
	movl	%ecx,%edi
sf_20:	cmpb	$0,(%edi)
	jz	sf_fo			/*  Found substring */
	jz	sf_fo			#  Found substring
	cmpsb
	jz	sf_20			/*  Char ok */
	jmp	sf_00			/*  Next str-pos */
	jz	sf_20			#  Char ok
	jmp	sf_00			#  Next str-pos

sf_90:	movl	$1,%edx			/*  Return Null */
sf_fo:	movl	%edx,%eax		/*  Char found here */
	decl	%eax			/*  Pointed one after */
sf_90:	movl	$1,%edx			#  Return Null
sf_fo:	movl	%edx,%eax		#  Char found here
	decl	%eax			#  Pointed one after
	popl	%esi
	popl	%edi
	ret
@@ -273,8 +272,8 @@ sf_fo: movl %edx,%eax /* Char found here */
	.size strstr,.strstr_end-strstr


	/* Find a substring in string, return index */
	/* Arg: str,search */
	# Find a substring in string, return index
	# Arg: str,search

.globl strinstr
	.type strinstr,@function
@@ -282,22 +281,22 @@ sf_fo: movl %edx,%eax /* Char found here */
strinstr:
	pushl	%ebp
	movl	%esp,%ebp
	pushl	12(%ebp)		/*  search */
	pushl	8(%ebp)			/*  str */
	pushl	12(%ebp)		#  search
	pushl	8(%ebp)			#  str
	call	strstr
	add	$8,%esp
	or	%eax,%eax
	jz	si_99			/*  Not found, return NULL */
	sub	8(%ebp),%eax		/*  Pos from start */
	inc	%eax			/*  And first pos = 1 */
	jz	si_99			#  Not found, return NULL
	sub	8(%ebp),%eax		#  Pos from start
	inc	%eax			#  And first pos = 1
si_99:	popl	%ebp
	ret
.strinstr_end:	
	.size strinstr,.strinstr_end-strinstr

	/* Make a string of len length from another string */
	/* Arg: dst,src,length */
	/* ret: end of dst */
	# Make a string of len length from another string
	# Arg: dst,src,length
	# ret: end of dst

.globl strmake
	.type strmake,@function
@@ -305,48 +304,48 @@ si_99: popl %ebp
strmake:	
	pushl	%edi
	pushl	%esi
	movl	12(%esp),%edi		/*  dst */
	movl	16(%esp),%esi		/*  src */
	movl	20(%esp),%ecx		/*  Length of memory-area */
	clrb	%al			/*  For test of end-null */
	jecxz	sm_90			/*  Nothing to move, put zero at end. */

sm_10:	cmpb	(%esi),%al		/*  Next char to move */
	movsb				/*  move arg */
	jz	sm_99			/*  last char, we are ready */
	loop	sm_10			/*  Continue moving */
sm_90:	movb	%al,(%edi)		/*  Set end pos */
	incl	%edi			/*  Fix that di points at end null */
sm_99:	decl	%edi			/*  di points now at end null */
	movl	%edi,%eax		/*  Ret value.p $ */
	movl	12(%esp),%edi		#  dst
	movl	16(%esp),%esi		#  src
	movl	20(%esp),%ecx		#  Length of memory-area
	clrb	%al			#  For test of end-null
	jecxz	sm_90			#  Nothing to move, put zero at end.

sm_10:	cmpb	(%esi),%al		#  Next char to move
	movsb				#  move arg
	jz	sm_99			#  last char, we are ready
	loop	sm_10			#  Continue moving
sm_90:	movb	%al,(%edi)		#  Set end pos
	incl	%edi			#  Fix that di points at end null
sm_99:	decl	%edi			#  di points now at end null
	movl	%edi,%eax		#  Ret value.p $
	popl	%esi
	popl	%edi
	ret
.strmake_end:	
	.size strmake,.strmake_end-strmake

	/* Move a string with max len chars */
	/* arg: dst,src,len */
	/* ret: pos to first null or dst+len */
	# Move a string with max len chars
	# arg: dst,src,len
	# ret: pos to first null or dst+len

.globl strnmov
	.type strnmov,@function
strnmov:	
	pushl	%edi
	pushl	%esi
	movl	12(%esp),%edi		/*  dst */
	movl	16(%esp),%esi		/*  src */
	movl	20(%esp),%ecx		/*  Length of memory-area */
	jecxz	snm_99			/*  Nothing to do */
	clrb	%al			/*  For test of end-null */

snm_10:	cmpb	(%esi),%al		/*  Next char to move */
	movsb				/*  move arg */
	jz	snm_20			/*  last char, fill with null */
	loop	snm_10			/*  Continue moving */
	incl	%edi			/*  Point two after last */
snm_20:	decl	%edi			/*  Point at first null (or last+1) */
snm_99:	movl	%edi,%eax		/*  Pointer at last char */
	movl	12(%esp),%edi		#  dst
	movl	16(%esp),%esi		#  src
	movl	20(%esp),%ecx		#  Length of memory-area
	jecxz	snm_99			#  Nothing to do
	clrb	%al			#  For test of end-null

snm_10:	cmpb	(%esi),%al		#  Next char to move
	movsb				#  move arg
	jz	snm_20			#  last char, fill with null
	loop	snm_10			#  Continue moving
	incl	%edi			#  Point two after last
snm_20:	decl	%edi			#  Point at first null (or last+1)
snm_99:	movl	%edi,%eax		#  Pointer at last char
	popl	%esi
	popl	%edi
	ret
@@ -357,17 +356,17 @@ snm_99: movl %edi,%eax /* Pointer at last char */
.globl strmov
	.type strmov,@function
strmov:	
	movl	%esi,%ecx		/*  Save old %esi and %edi */
	movl	%esi,%ecx		#  Save old %esi and %edi
	movl	%edi,%edx
	movl	8(%esp),%esi		/*  get source pointer (s2) */
	movl	4(%esp),%edi		/*  %edi -> s1 */
	movl	8(%esp),%esi		#  get source pointer (s2)
	movl	4(%esp),%edi		#  %edi -> s1
smo_10:	movb	(%esi),%al
	movsb				/*  move arg */
	movsb				#  move arg
	andb	%al,%al
	jnz	smo_10			/*  Not last */
	jnz	smo_10			#  Not last
	movl	%edi,%eax
	dec	%eax
	movl	%ecx,%esi		/*  Restore */
	movl	%ecx,%esi		#  Restore
	movl	%edx,%edi
	ret
.strmov_end:	
@@ -376,29 +375,29 @@ smo_10: movb (%esi),%al
.globl strxmov
	.type	 strxmov,@function
strxmov:
	movl	%ebx,%edx		/*  Save %ebx, %esi and %edi */
	movl	%ebx,%edx		#  Save %ebx, %esi and %edi
	mov	%esi,%ecx
	push	%edi
	leal	8(%esp),%ebx		/*  Get destination */
	leal	8(%esp),%ebx		#  Get destination
	movl	(%ebx),%edi
	xorb	%al,%al
	jmp	next_str		/*  Handle source ebx+4 */
	jmp	next_str		#  Handle source ebx+4

start_str:
	movsb
	cmpb	-1(%edi),%al
	jne	start_str
	decl	%edi			/*  Don't copy last null */
	decl	%edi			#  Don't copy last null

next_str:
	addl	$4,%ebx
	movl	(%ebx),%esi
	orl	%esi,%esi
	jne	start_str
	movb	%al,0(%edi)		/*  Force last to ASCII 0 */
	movb	%al,0(%edi)		#  Force last to ASCII 0

	movl	%edi,%eax		/*  Return ptr to ASCII 0 */
	pop	%edi			/*  Restore registers */
	movl	%edi,%eax		#  Return ptr to ASCII 0
	pop	%edi			#  Restore registers
	movl	%ecx,%esi
	movl	%edx,%ebx
	ret