Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1407 → Rev 1408

/drivers/ddk/string/_memmove.S
0,0 → 1,67
# _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.
 
.intel_syntax
 
.globl __memmove, __memcpy
 
.text
 
.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?
upbyte:
rep movsb # Copy bytes
done:
mov eax, [ebp+8] # 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.
 
downwards:
std # Set direction bit: downwards
lea esi, [esi+ecx-1]
lea edi, [edi+ecx-1]
rep movsb # Copy bytes
cld
jmp done
/drivers/ddk/string/_strncat.S
0,0 → 1,43
# _strncat() Author: Kees J. Bot
# 1 Jan 1994
# char *_strncat(char *s1, const char *s2, size_t edx)
# Append string s2 to s1.
#
 
.intel_syntax
 
.global __strncat
 
.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
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
ret
/drivers/ddk/string/_strncmp.S
0,0 → 1,44
# strncmp() Author: Kees J. Bot 1 Jan 1994
 
# int strncmp(const char *s1, const char *s2, size_t ecx)
# Compare two strings.
#
 
.intel_syntax
 
.globl __strncmp
 
.text
.align 16
__strncmp:
push ebp
mov ebp, esp
 
push esi
push edi
 
test ecx, ecx # Max length is zero?
je done
 
mov esi, [ebp+8] # esi = string s1
mov edi, [ebp+12] # edi = string s2
cld
compare:
cmpsb # Compare two bytes
jne done
 
cmpb [esi-1], 0 # End of string?
je done
 
dec 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
ret
/drivers/ddk/string/_strncpy.S
0,0 → 1,27
# _strncpy() Author: Kees J. Bot
# 1 Jan 1994
 
# char *_strncpy(char *s1, const char *s2, size_t ecx)
# Copy string s2 to s1.
#
 
.intel_syntax
 
.text
.globl __strncpy
.align 16
 
__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
ret
/drivers/ddk/string/_strnlen.S
0,0 → 1,30
# _strnlen() Author: Kees J. Bot 1 Jan 1994
 
# size_t _strnlen(const char *s, size_t ecx)
# Return the length of a string.
 
.intel_syntax
 
.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
jne no0
inc ecx # Don't count zero byte
no0:
mov eax, edx
sub eax, ecx # Compute bytes scanned
pop edi
pop ebp
ret
/drivers/ddk/string/memcmp.S
0,0 → 1,59
# memcmp() Author: Kees J. Bot
# 2 Jan 1994
 
# int memcmp(const void *s1, const void *s2, size_t n)
# Compare two chunks of memory.
#
 
.intel_syntax
 
.globl _memcmp
 
.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
ret
/drivers/ddk/string/memcpy.S
0,0 → 1,26
# 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.
 
.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
/drivers/ddk/string/memset.S
0,0 → 1,47
# 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.
#
 
.intel_syntax
 
.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
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
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
sword:
movb ah, al # One byte to two bytes
shr ecx, 1
rep stosw # Store words
adc ecx, ecx # One more byte?
sbyte:
rep stosb # Store bytes
done:
mov eax, [8+ebp] # Return some value you have no need for
pop edi
pop ebp
ret
/drivers/ddk/string/strcat.S
0,0 → 1,15
# strcat() Author: Kees J. Bot
# 1 Jan 1994
# char *strcat(char *s1, const char *s2)
# Append string s2 to s1.
#
 
.intel_syntax
 
.global _strcat
 
.text
.align 16
_strcat:
mov edx, -1 # Unlimited length
jmp __strncat # Common code
/drivers/ddk/string/strchr.S
0,0 → 1,46
# strchr() Author: Kees J. Bot 1 Jan 1994
 
# char *strchr(const char *s, int c)
# Look for a character in a string.
 
.intel_syntax
 
.globl _strchr
 
.text
.align 16
_strchr:
push ebp
mov ebp, esp
push edi
cld
mov edi, [ebp+8] # edi = string
mov edx, 16 # 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
repne scasb
 
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
ret
found:
pop eax # Get rid of those flags
lea eax, [edi-1] # Address of byte found
pop edi
pop ebp
ret
/drivers/ddk/string/strcpy.S
0,0 → 1,24
# strcpy() Author: Kees J. Bot
# 1 Jan 1994
# char *strcpy(char *s1, const char *s2)
# Copy string s2 to s1.
#
 
.intel_syntax
 
.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
ret
/drivers/ddk/string/strlen.S
0,0 → 1,15
# strlen() Author: Kees J. Bot 1 Jan 1994
 
# size_t strlen(const char *s)
# Return the length of a string.
 
.intel_syntax
 
.globl _strlen
 
.text
 
.align 16
_strlen:
mov ecx, -1 # Unlimited length
jmp __strnlen # Common code
/drivers/ddk/string/strncmp.S
0,0 → 1,15
# strncmp() Author: Kees J. Bot 1 Jan 1994
 
# int strncmp(const char *s1, const char *s2, size_t n)
# Compare two strings.
#
 
.intel_syntax
 
.globl _strncmp
 
.text
.align 16
_strncmp:
mov ecx, [esp+12] # Maximum length
jmp __strncmp # Common code
/drivers/ddk/string/strncpy.S
0,0 → 1,28
# strncpy() Author: Kees J. Bot
# 1 Jan 1994
# char *strncpy(char *s1, const char *s2, size_t n)
# Copy string s2 to s1.
#
 
.intel_syntax
 
.text
 
.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
ret