Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1626 → Rev 1627

/drivers/ddk/string/_memmove.S
1,67 → 1,60
# _memmove() Author: Kees J. Bot 2 Jan 1994
/* _memmove() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
# void *_memmove(void *s1, const void *s2, size_t n)
# Copy a chunk of memory. Handle overlap.
/* void *_memmove(void *s1, const void *s2, size_t n) */
/* Copy a chunk of memory. Handle overlap. */
/* */
 
.intel_syntax
#include "asm.h"
 
.globl __memmove, __memcpy
ENTRY(_memmove)
push %ebp
movl %esp, %ebp
push %esi
push %edi
movl 8(%ebp), %edi /* String s1 */
movl 12(%ebp), %esi /* String s2 */
movl 16(%ebp), %ecx /* Length */
movl %edi, %eax
subl %esi, %eax
cmpl %ecx, %eax
jb downwards /* if (s2 - s1) < n then copy downwards */
LABEL(_memcpy)
cld /* Clear direction bit: upwards */
cmpl $16, %ecx
jb upbyte /* Don't bother being smart with short arrays */
movl %esi, %eax
orl %edi, %eax
testb $1, %al
jne upbyte /* Bit 0 set, use byte copy */
testb $2, %al
jne upword /* Bit 1 set, use word copy */
uplword:
shrdl $2, %ecx, %eax /* Save low 2 bits of ecx in eax */
shrl $2, %ecx
 
.text
rep movsl /* Copy longwords. */
shldl $2, %eax, %ecx /* Restore excess count */
upword:
shrl $1, %ecx
 
.align 16
__memmove:
push ebp
mov ebp, esp
 
push esi
push edi
 
mov edi, [ebp+8] # String s1
mov esi, [ebp+12] # String s2
mov ecx, [ebp+16] # Length
 
mov eax, edi
sub eax, esi
cmp eax, ecx
jb downwards # if (s2 - s1) < n then copy downwards
__memcpy:
cld # Clear direction bit: upwards
cmp ecx, 16
jb upbyte # Don't bother being smart with short arrays
 
mov eax, esi
or eax, edi
testb al, 1
jnz upbyte # Bit 0 set, use byte copy
 
testb al, 2
 
jnz upword # Bit 1 set, use word copy
uplword:
shrd eax, ecx, 2 # Save low 2 bits of ecx in eax
shr ecx, 2
rep movsd # Copy longwords.
shld ecx, eax, 2 # Restore excess count
upword:
shr ecx, 1
rep movsw # Copy words
adc ecx, ecx # One more byte?
rep movsw /* Copy words */
adcl %ecx, %ecx /* One more byte? */
upbyte:
rep movsb # Copy bytes
rep movsb /* Copy bytes */
done:
mov eax, [ebp+8] # Absolutely noone cares about this value
pop edi
pop esi
pop ebp
movl 8(%ebp), %eax /* Absolutely noone cares about this value */
pop %edi
pop %esi
pop %ebp
ret
 
# Handle bad overlap by copying downwards, don't bother to do word copies.
/* Handle bad overlap by copying downwards, don't bother to do word copies. */
downwards:
std /* Set direction bit: downwards */
leal -1(%esi,%ecx,1), %esi
leal -1(%edi,%ecx,1), %edi
 
downwards:
std # Set direction bit: downwards
lea esi, [esi+ecx-1]
lea edi, [edi+ecx-1]
rep movsb # Copy bytes
rep movsb /* Copy bytes */
cld
jmp done
/drivers/ddk/string/_strncat.S
1,43 → 1,40
# _strncat() Author: Kees J. Bot
# 1 Jan 1994
# char *_strncat(char *s1, const char *s2, size_t edx)
# Append string s2 to s1.
#
/* _strncat() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
.intel_syntax
/* char *_strncat(char *s1, const char *s2, size_t edx) */
/* Append string s2 to s1. */
/* */
#include "asm.h"
 
.global __strncat
ENTRY(_strncat)
push %ebp
movl %esp, %ebp
push %esi
push %edi
movl 8(%ebp), %edi /* String s1 */
movl $-1, %ecx
xorb %al, %al /* Null byte */
cld
 
.text
.align 16
__strncat:
push ebp
mov ebp, esp
push esi
push edi
mov edi, [ebp+8] # String s1
mov ecx, -1
xorb al, al # Null byte
cld
repne
scasb # Look for the zero byte in s1
dec edi # Back one up (and clear 'Z' flag)
push edi # Save end of s1
mov edi, [12+ebp] # edi = string s2
mov ecx, edx # Maximum count
repne
scasb # Look for the end of s2
repne scasb /* Look for the zero byte in s1 */
decl %edi /* Back one up (and clear 'Z' flag) */
push %edi /* Save end of s1 */
movl 12(%ebp), %edi /* edi = string s2 */
movl %edx, %ecx /* Maximum count */
 
repne scasb /* Look for the end of s2 */
jne no0
inc ecx # Exclude null byte
no0: sub edx, ecx # Number of bytes in s2
mov ecx, edx
mov esi, [12+ebp] # esi = string s2
pop edi # edi = end of string s1
rep
movsb # Copy bytes
stosb # Add a terminating null
mov eax, [8+ebp] # Return s1
pop edi
pop esi
pop ebp
incl %ecx /* Exclude null byte */
no0:
subl %ecx, %edx /* Number of bytes in s2 */
movl %edx, %ecx
movl 12(%ebp), %esi /* esi = string s2 */
pop %edi /* edi = end of string s1 */
 
rep movsb /* Copy bytes */
stosb /* Add a terminating null */
movl 8(%ebp), %eax /* Return s1 */
pop %edi
pop %esi
pop %ebp
ret
/drivers/ddk/string/_strncmp.S
1,44 → 1,34
# strncmp() Author: Kees J. Bot 1 Jan 1994
/* strncmp() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
# int strncmp(const char *s1, const char *s2, size_t ecx)
# Compare two strings.
#
/* int strncmp(const char *s1, const char *s2, size_t ecx) */
/* Compare two strings. */
/* */
#include "asm.h"
 
.intel_syntax
 
.globl __strncmp
 
.text
.align 16
__strncmp:
push ebp
mov ebp, esp
 
push esi
push edi
 
test ecx, ecx # Max length is zero?
ENTRY(_strncmp)
push %ebp
movl %esp, %ebp
push %esi
push %edi
testl %ecx, %ecx /* Max length is zero? */
je done
 
mov esi, [ebp+8] # esi = string s1
mov edi, [ebp+12] # edi = string s2
movl 8(%ebp), %esi /* esi = string s1 */
movl 12(%ebp), %edi /* edi = string s2 */
cld
compare:
cmpsb # Compare two bytes
cmpsb /* Compare two bytes */
jne done
 
cmpb [esi-1], 0 # End of string?
cmpb $0, -1(%esi) /* End of string? */
je done
 
dec ecx # Length limit reached?
decl %ecx /* Length limit reached? */
jne compare
done:
seta al # al = (s1 > s2)
setb ah # ah = (s1 < s2)
subb al, ah
movsx eax, al # eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
 
pop edi
pop esi
pop ebp
seta %al /* al = (s1 > s2) */
setb %ah /* ah = (s1 < s2) */
subb %ah, %al
movsbl %al, %eax /* eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 */
pop %edi
pop %esi
pop %ebp
ret
/drivers/ddk/string/_strncpy.S
1,27 → 1,22
# _strncpy() Author: Kees J. Bot
# 1 Jan 1994
/* _strncpy() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
# char *_strncpy(char *s1, const char *s2, size_t ecx)
# Copy string s2 to s1.
#
/* char *_strncpy(char *s1, const char *s2, size_t ecx) */
/* Copy string s2 to s1. */
/* */
#include "asm.h"
 
.intel_syntax
ENTRY(_strncpy)
movl 12(%ebp), %edi /* edi = string s2 */
xorb %al, %al /* Look for a zero byte */
movl %ecx, %edx /* Save maximum count */
cld
 
.text
.globl __strncpy
.align 16
repne scasb /* Look for end of s2 */
subl %ecx, %edx /* Number of bytes in s2 including null */
xchgl %edx, %ecx
movl 12(%ebp), %esi /* esi = string s2 */
movl 8(%ebp), %edi /* edi = string s1 */
 
__strncpy:
mov edi, [ebp+12] # edi = string s2
xorb al, al # Look for a zero byte
mov edx, ecx # Save maximum count
cld
repne
scasb # Look for end of s2
sub edx, ecx # Number of bytes in s2 including null
xchg ecx, edx
mov esi, [ebp+12] # esi = string s2
mov edi, [ebp+8] # edi = string s1
rep
movsb # Copy bytes
rep movsb /* Copy bytes */
ret
/drivers/ddk/string/_strnlen.S
1,30 → 1,27
# _strnlen() Author: Kees J. Bot 1 Jan 1994
/* _strnlen() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
# size_t _strnlen(const char *s, size_t ecx)
# Return the length of a string.
/* size_t _strnlen(const char *s, size_t ecx) */
/* Return the length of a string. */
/* */
#include "asm.h"
 
.intel_syntax
ENTRY(_strnlen)
push %ebp
movl %esp, %ebp
push %edi
movl 8(%ebp), %edi /* edi = string */
xorb %al, %al /* Look for a zero byte */
movl %ecx, %edx /* Save maximum count */
cmpb $1, %cl /* 'Z' bit must be clear if ecx = 0 */
cld
 
.globl __strnlen
 
.text
.align 16
__strnlen:
push ebp
mov ebp, esp
push edi
mov edi, [ebp+8] # edi = string
xorb al, al # Look for a zero byte
mov edx, ecx # Save maximum count
cmpb cl, 1 # 'Z' bit must be clear if ecx = 0
cld
repne
scasb # Look for zero
repne scasb /* Look for zero */
jne no0
inc ecx # Don't count zero byte
incl %ecx /* Don't count zero byte */
no0:
mov eax, edx
sub eax, ecx # Compute bytes scanned
pop edi
pop ebp
movl %edx, %eax
subl %ecx, %eax /* Compute bytes scanned */
pop %edi
pop %ebp
ret
/drivers/ddk/string/asm.h
0,0 → 1,61
/*-
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)asm.h 5.5 (Berkeley) 5/7/91
*/
 
#ifndef _I386_ASM_H_
#define _I386_ASM_H_
 
#define _C_LABEL(x) _ ## x
#define _ASM_LABEL(x) x
 
/* allow overriding entrypoint alignment */
#if !defined(_ALIGN_TEXT)
# define _ALIGN_TEXT .align 16
#endif
 
#define _ENTRY(x) \
.text; _ALIGN_TEXT; .globl x; x:
 
#define _LABEL(x) \
.globl x; x:
 
#define ENTRY(y) _ENTRY(_C_LABEL(y))
#define NENTRY(y) _ENTRY(_C_LABEL(y))
#define ASENTRY(y) _ENTRY(_ASM_LABEL(y))
#define LABEL(y) _LABEL(_C_LABEL(y))
#define END(y) .size y, . - y
 
#define IMPORT(sym) \
.extern _C_LABEL(sym)
 
#endif /* !_I386_ASM_H_ */
/drivers/ddk/string/bcmp.S
0,0 → 1,27
/* bcmp() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
/* int bcmp(const void *s1, const void *s2, size_t n) */
/* Compare two chunks of memory. */
/* This is a BSD routine that escaped from the kernel. Don't use. */
/* (Alas it is not without some use, it reports the number of bytes */
/* after the bytes that are equal. So it can't be simply replaced.) */
/* */
#include "asm.h"
 
ENTRY(bcmp)
push %ebp
movl %esp, %ebp
push 16(%ebp)
push 12(%ebp)
push 8(%ebp)
call _C_LABEL(memcmp) /* Let memcmp do the work */
testl %eax, %eax
je equal
subl 8(%ebp), %edx /* Memcmp was nice enough to leave "esi" in edx */
decl %edx /* Number of bytes that are equal */
movl 16(%ebp), %eax
subl %edx, %eax /* Number of bytes that are unequal */
equal:
leave
ret
/drivers/ddk/string/bcopy.S
0,0 → 1,14
/* bcopy() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
/* void bcopy(const void *s1, void *s2, size_t n) */
/* Copy a chunk of memory. Handle overlap. */
/* This is a BSD routine that escaped from the kernel. Don't use. */
/* */
#include "asm.h"
 
ENTRY(bcopy)
movl 4(%esp), %eax /* Exchange string arguments */
xchgl 8(%esp), %eax
movl %eax, 4(%esp)
jmp _C_LABEL(_memmove) /* Call the proper routine */
/drivers/ddk/string/bzero.S
0,0 → 1,18
/* bzero() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
/* void bzero(void *s, size_t n) */
/* Set a chunk of memory to zero. */
/* This is a BSD routine that escaped from the kernel. Don't use. */
/* */
#include "asm.h"
 
ENTRY(bzero)
push %ebp
movl %esp, %ebp
push 12(%ebp) /* Size */
push $0 /* Zero */
push 8(%ebp) /* String */
call _C_LABEL(memset) /* Call the proper routine */
leave
ret
/drivers/ddk/string/index.S
0,0 → 1,11
/* index() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
/* char *index(const char *s, int c) */
/* Look for a character in a string. Has suffered from a hostile */
/* takeover by strchr(). */
/* */
#include "asm.h"
 
ENTRY(index)
jmp _C_LABEL(strchr)
/drivers/ddk/string/memchr.S
0,0 → 1,29
/* memchr() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
/* void *memchr(const void *s, int c, size_t n) */
/* Look for a character in a chunk of memory. */
/* */
#include "asm.h"
 
ENTRY(memchr)
push %ebp
movl %esp, %ebp
push %edi
movl 8(%ebp), %edi /* edi = string */
movb 12(%ebp), %al /* The character to look for */
movl 16(%ebp), %ecx /* Length */
cmpb $1, %cl /* 'Z' bit must be clear if ecx = 0 */
cld
 
repne scasb
jne failure
leal -1(%edi), %eax /* Found */
pop %edi
pop %ebp
ret
failure:
xorl %eax, %eax
pop %edi
pop %ebp
ret
/drivers/ddk/string/memcmp.S
1,59 → 1,57
# memcmp() Author: Kees J. Bot
# 2 Jan 1994
/* memcmp() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
# int memcmp(const void *s1, const void *s2, size_t n)
# Compare two chunks of memory.
#
/* int memcmp(const void *s1, const void *s2, size_t n) */
/* Compare two chunks of memory. */
/* */
#include "asm.h"
 
.intel_syntax
ENTRY(memcmp)
cld
push %ebp
movl %esp, %ebp
push %esi
push %edi
movl 8(%ebp), %esi /* String s1 */
movl 12(%ebp), %edi /* String s2 */
movl 16(%ebp), %ecx /* Length */
cmpl $16, %ecx
jb cbyte /* Don't bother being smart with short arrays */
movl %esi, %eax
orl %edi, %eax
testb $1, %al
jne cbyte /* Bit 0 set, use byte compare */
testb $2, %al
jne cword /* Bit 1 set, use word compare */
clword:
shrdl $2, %ecx, %eax /* Save low two bits of ecx in eax */
shrl $2, %ecx
 
.globl _memcmp
repe cmpsl /* Compare longwords */
subl $4, %esi
subl $4, %edi
incl %ecx /* Recompare the last longword */
shldl $2, %eax, %ecx /* And any excess bytes */
jmp last
cword:
shrdl $1, %ecx, %eax /* Save low bit of ecx in eax */
shrl $1, %ecx
 
.text
.align 16
_memcmp:
cld
push ebp
mov ebp, esp
push esi
push edi
mov esi, [8+ebp] # String s1
mov edi, [12+ebp] # String s2
mov ecx, [16+ebp] # Length
cmp ecx, 16
jb cbyte # Don't bother being smart with short arrays
mov eax, esi
or eax, edi
testb al, 1
jnz cbyte # Bit 0 set, use byte compare
testb al, 2
jnz cword # Bit 1 set, use word compare
clword: shrd eax, ecx, 2 # Save low two bits of ecx in eax
shr ecx, 2
repe
cmpsd # Compare longwords
sub esi, 4
sub edi, 4
inc ecx # Recompare the last longword
shld ecx, eax, 2 # And any excess bytes
jmp last
cword: shrd eax, ecx, 1 # Save low bit of ecx in eax
shr ecx, 1
repe
cmpsw # Compare words
sub esi, 2
sub edi, 2
inc ecx # Recompare the last word
shld ecx, eax, 1 # And one more byte?
cbyte: test ecx, ecx # Set 'Z' flag if ecx = 0
last: repe
cmpsb # Look for the first differing byte
seta al # al = (s1 > s2)
setb ah # ah = (s1 < s2)
subb al, ah
movsxb eax, al # eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1
mov edx, esi # For bcmp() to play with
pop edi
pop esi
pop ebp
repe cmpsw /* Compare words */
subl $2, %esi
subl $2, %edi
incl %ecx /* Recompare the last word */
shldl $1, %eax, %ecx /* And one more byte? */
cbyte:
testl %ecx, %ecx /* Set 'Z' flag if ecx = 0 */
last:
repe cmpsb /* Look for the first differing byte */
seta %al /* al = (s1 > s2) */
setb %ah /* ah = (s1 < s2) */
subb %ah, %al
movsbl %al, %eax /* eax = (s1 > s2) - (s1 < s2), i.e. -1, 0, 1 */
movl %esi, %edx /* For bcmp() to play with */
pop %edi
pop %esi
pop %ebp
ret
/drivers/ddk/string/memcpy.S
1,26 → 1,22
# memcpy() Author: Kees J. Bot 2 Jan 1994
/* memcpy() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
# void *memcpy(void *s1, const void *s2, size_t n)
# Copy a chunk of memory.
# This routine need not handle overlap, so it does not handle overlap.
# One could simply call __memmove, the cost of the overlap check is
# negligible, but you are dealing with a programmer who believes that
# if anything can go wrong, it should go wrong.
/* void *memcpy(void *s1, const void *s2, size_t n) */
/* Copy a chunk of memory. */
/* This routine need not handle overlap, so it does not handle overlap. */
/* One could simply call __memmove, the cost of the overlap check is */
/* negligible, but you are dealing with a programmer who believes that if */
/* anything can go wrong, it should go wrong. */
/* */
#include "asm.h"
 
.intel_syntax
 
.globl _memcpy
 
.text
 
.align 16
_memcpy:
push ebp
mov ebp, esp
push esi
push edi
mov edi, [ebp+8] # String s1
mov esi, [ebp+12] # String s2
mov ecx, [ebp+16] # Length
# No overlap check here
jmp __memcpy # Call the part of __memmove that copies up
ENTRY(memcpy)
push %ebp
movl %esp, %ebp
push %esi
push %edi
movl 8(%ebp), %edi /* String s1 */
movl 12(%ebp), %esi /* String s2 */
movl 16(%ebp), %ecx /* Length */
/* No overlap check here */
jmp _C_LABEL(_memcpy) /* Call the part of __memmove that copies up */
/drivers/ddk/string/memmove.S
0,0 → 1,10
/* memmove() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
/* void *memmove(void *s1, const void *s2, size_t n) */
/* Copy a chunk of memory. Handle overlap. */
/* */
#include "asm.h"
 
ENTRY(memmove)
jmp _C_LABEL(_memmove) /* Call common code */
/drivers/ddk/string/memset.S
1,47 → 1,45
# memset() Author: Kees J. Bot
# 2 Jan 1994
# void *memset(void *s, int c, size_t n)
# Set a chunk of memory to the same byte value.
#
/* memset() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
.intel_syntax
/* void *memset(void *s, int c, size_t n) */
/* Set a chunk of memory to the same byte value. */
/* */
#include "asm.h"
 
.global _memset
 
.text
.align 16
_memset:
push ebp
mov ebp, esp
push edi
mov edi, [8+ebp] # The string
movzx eax, byte ptr [12+ebp] # The fill byte
mov ecx, [16+ebp] # Length
ENTRY(memset)
push %ebp
movl %esp, %ebp
push %edi
movl 8(%ebp), %edi /* The string */
movzbl 12(%ebp), %eax /* The fill byte */
movl 16(%ebp), %ecx /* Length */
cld
cmp ecx, 16
jb sbyte # Don't bother being smart with short arrays
test edi, 1
jnz sbyte # Bit 0 set, use byte store
test edi, 2
jnz sword # Bit 1 set, use word store
cmpl $16, %ecx
jb sbyte /* Don't bother being smart with short arrays */
testl $1, %edi
jne sbyte /* Bit 0 set, use byte store */
testl $2, %edi
jne sword /* Bit 1 set, use word store */
slword:
movb ah, al
mov edx, eax
sal edx, 16
or eax, edx # One byte to four bytes
shrd edx, ecx, 2 # Save low two bits of ecx in edx
shr ecx, 2
rep stosd # Store longwords.
shld ecx, edx, 2 # Restore low two bits
movb %al, %ah
movl %eax, %edx
sall $16, %edx
orl %edx, %eax /* One byte to four bytes */
shrdl $2, %ecx, %edx /* Save low two bits of ecx in edx */
shrl $2, %ecx
 
rep stosl /* Store longwords. */
shldl $2, %edx, %ecx /* Restore low two bits */
sword:
movb ah, al # One byte to two bytes
shr ecx, 1
rep stosw # Store words
adc ecx, ecx # One more byte?
movb %al, %ah /* One byte to two bytes */
shrl $1, %ecx
 
rep stosw /* Store words */
adcl %ecx, %ecx /* One more byte? */
sbyte:
rep stosb # Store bytes
rep stosb /* Store bytes */
done:
mov eax, [8+ebp] # Return some value you have no need for
pop edi
pop ebp
movl 8(%ebp), %eax /* Return some value you have no need for */
pop %edi
pop %ebp
ret
/drivers/ddk/string/rindex.S
0,0 → 1,11
/* rindex() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
/* char *rindex(const char *s, int c) */
/* Look for the last occurrence a character in a string. Has suffered */
/* from a hostile takeover by strrchr(). */
/* */
#include "asm.h"
 
ENTRY(rindex)
jmp _C_LABEL(strrchr)
/drivers/ddk/string/strcat.S
1,15 → 1,11
# strcat() Author: Kees J. Bot
# 1 Jan 1994
# char *strcat(char *s1, const char *s2)
# Append string s2 to s1.
#
/* strcat() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
.intel_syntax
/* char *strcat(char *s1, const char *s2) */
/* Append string s2 to s1. */
/* */
#include "asm.h"
 
.global _strcat
 
.text
.align 16
_strcat:
mov edx, -1 # Unlimited length
jmp __strncat # Common code
ENTRY(strcat)
movl $-1, %edx /* Unlimited length */
jmp _C_LABEL(_strncat) /* Common code */
/drivers/ddk/string/strchr.S
1,46 → 1,41
# strchr() Author: Kees J. Bot 1 Jan 1994
/* strchr() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
# char *strchr(const char *s, int c)
# Look for a character in a string.
/* char *strchr(const char *s, int c) */
/* Look for a character in a string. */
/* */
#include "asm.h"
 
.intel_syntax
 
.globl _strchr
 
.text
.align 16
_strchr:
push ebp
mov ebp, esp
push edi
ENTRY(strchr)
push %ebp
movl %esp, %ebp
push %edi
cld
mov edi, [ebp+8] # edi = string
mov edx, 16 # Look at small chunks of the string
movl 8(%ebp), %edi /* edi = string */
movl $16, %edx /* Look at small chunks of the string */
next:
shl edx, 1 # Chunks become bigger each time
mov ecx, edx
xorb al, al # Look for the zero at the end
shll $1, %edx /* Chunks become bigger each time */
movl %edx, %ecx
xorb %al, %al /* Look for the zero at the end */
 
repne scasb
pushf /* Remember the flags */
subl %edx, %ecx
negl %ecx /* Some or all of the chunk */
subl %ecx, %edi /* Step back */
movb 12(%ebp), %al /* The character to look for */
 
pushf # Remember the flags
sub ecx, edx
neg ecx # Some or all of the chunk
sub edi, ecx # Step back
movb al, [ebp+12] # The character to look for
repne scasb
je found
 
popf # Did we find the end of string earlier?
 
jne next # No, try again
 
xor eax, eax # Return NULL
pop edi
pop ebp
popf /* Did we find the end of string earlier? */
jne next /* No, try again */
xorl %eax, %eax /* Return NULL */
pop %edi
pop %ebp
ret
found:
pop eax # Get rid of those flags
lea eax, [edi-1] # Address of byte found
pop edi
pop ebp
pop %eax /* Get rid of those flags */
leal -1(%edi), %eax /* Address of byte found */
pop %edi
pop %ebp
ret
/drivers/ddk/string/strcmp.S
0,0 → 1,11
/* strcmp() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
/* int strcmp(const char *s1, const char *s2) */
/* Compare two strings. */
/* */
#include "asm.h"
 
ENTRY(strcmp)
movl $-1, %ecx /* Unlimited length */
jmp _C_LABEL(_strncmp) /* Common code */
/drivers/ddk/string/strcpy.S
1,24 → 1,20
# strcpy() Author: Kees J. Bot
# 1 Jan 1994
# char *strcpy(char *s1, const char *s2)
# Copy string s2 to s1.
#
/* strcpy() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
.intel_syntax
/* char *strcpy(char *s1, const char *s2) */
/* Copy string s2 to s1. */
/* */
#include "asm.h"
 
.global _strcpy
 
.text
.align 16
_strcpy:
push ebp
mov ebp, esp
push esi
push edi
mov ecx, -1 # Unlimited length
call _strncpy # Common code
mov eax, [8+ebp] # Return s1
pop edi
pop esi
pop ebp
ENTRY(strcpy)
push %ebp
movl %esp, %ebp
push %esi
push %edi
movl $-1, %ecx /* Unlimited length */
call _C_LABEL(_strncpy) /* Common code */
movl 8(%ebp), %eax /* Return s1 */
pop %edi
pop %esi
pop %ebp
ret
/drivers/ddk/string/strlen.S
1,15 → 1,11
# strlen() Author: Kees J. Bot 1 Jan 1994
/* strlen() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
# size_t strlen(const char *s)
# Return the length of a string.
/* size_t strlen(const char *s) */
/* Return the length of a string. */
/* */
#include "asm.h"
 
.intel_syntax
 
.globl _strlen
 
.text
 
.align 16
_strlen:
mov ecx, -1 # Unlimited length
jmp __strnlen # Common code
ENTRY(strlen)
movl $-1, %ecx /* Unlimited length */
jmp _C_LABEL(_strnlen) /* Common code */
/drivers/ddk/string/strncat.S
0,0 → 1,11
/* strncat() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
/* size_t strncat(char *s1, const char *s2, size_t n) */
/* Append string s2 to s1. */
/* */
#include "asm.h"
 
ENTRY(strncat)
movl 12(%esp), %edx /* Maximum length */
jmp _C_LABEL(_strncat) /* Common code */
/drivers/ddk/string/strncmp.S
1,22 → 1,11
# strncmp() Author: Kees J. Bot 1 Jan 1994
/* strncmp() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
# int strncmp(const char *s1, const char *s2, size_t n)
# Compare two strings.
#
/* int strncmp(const char *s1, const char *s2, size_t n) */
/* Compare two strings. */
/* */
#include "asm.h"
 
.intel_syntax
 
.globl _strncmp
.globl _strcmp
 
.text
.align 16
_strncmp:
mov ecx, [esp+12] # Maximum length
jmp __strncmp # Common code
 
 
.align 16
_strcmp:
mov ecx, -1 # Maximum length
jmp __strncmp # Common code
ENTRY(strncmp)
movl 12(%esp), %ecx /* Maximum length */
jmp _C_LABEL(_strncmp) /* Common code */
/drivers/ddk/string/strncpy.S
1,28 → 1,23
# strncpy() Author: Kees J. Bot
# 1 Jan 1994
# char *strncpy(char *s1, const char *s2, size_t n)
# Copy string s2 to s1.
#
/* strncpy() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
.intel_syntax
/* char *strncpy(char *s1, const char *s2, size_t n) */
/* Copy string s2 to s1. */
/* */
#include "asm.h"
 
.text
ENTRY(strncpy)
push %ebp
movl %esp, %ebp
push %esi
push %edi
movl 16(%ebp), %ecx /* Maximum length */
call _C_LABEL(_strncpy) /* Common code */
movl %edx, %ecx /* Number of bytes not copied */
 
.globl _strncpy
 
.align 16
_strncpy:
push ebp
mov ebp, esp
push esi
push edi
mov ecx, [ebp+16] # Maximum length
call __strncpy # Common code
mov ecx, edx # Number of bytes not copied
rep
stosb # strncpy always copies n bytes by null padding
mov eax, [ebp+8] # Return s1
pop edi
pop esi
pop ebp
rep stosb /* strncpy always copies n bytes by null padding */
movl 8(%ebp), %eax /* Return s1 */
pop %edi
pop %esi
pop %ebp
ret
/drivers/ddk/string/strnlen.S
0,0 → 1,11
/* strnlen() Author: Kees J. Bot */
/* 1 Jan 1994 */
 
/* size_t strnlen(const char *s, size_t n) */
/* Return the length of a string. */
/* */
#include "asm.h"
 
ENTRY(strnlen)
movl 8(%esp), %ecx /* Maximum length */
jmp _C_LABEL(_strnlen) /* Common code */
/drivers/ddk/string/strrchr.S
0,0 → 1,35
/* strrchr() Author: Kees J. Bot */
/* 2 Jan 1994 */
 
/* char *strrchr(const char *s, int c) */
/* Look for the last occurrence a character in a string. */
/* */
#include "asm.h"
 
ENTRY(strrchr)
push %ebp
movl %esp, %ebp
push %edi
movl 8(%ebp), %edi /* edi = string */
movl $-1, %ecx
xorb %al, %al
cld
 
repne scasb /* Look for the end of the string */
notl %ecx /* -1 - ecx = Length of the string + null */
decl %edi /* Put edi back on the zero byte */
movb 12(%ebp), %al /* The character to look for */
std /* Downwards search */
 
repne scasb
cld /* Direction bit back to default */
jne failure
leal 1(%edi), %eax /* Found it */
pop %edi
pop %ebp
ret
failure:
xorl %eax, %eax /* Not there */
pop %edi
pop %ebp
ret