Initial revision

This commit is contained in:
Ben Gras
2005-04-21 14:53:53 +00:00
commit 9865aeaa79
2264 changed files with 411685 additions and 0 deletions

112
lib/i86/string/Makefile Executable file
View File

@@ -0,0 +1,112 @@
# Makefile for lib/i86/string.
CC1 = $(CC) -Was-ncc -c
LIBRARY = ../../libc.a
all: $(LIBRARY)
OBJECTS = \
$(LIBRARY)(_memmove.o) \
$(LIBRARY)(_strncat.o) \
$(LIBRARY)(_strncmp.o) \
$(LIBRARY)(_strncpy.o) \
$(LIBRARY)(_strnlen.o) \
$(LIBRARY)(bcmp.o) \
$(LIBRARY)(bcopy.o) \
$(LIBRARY)(bzero.o) \
$(LIBRARY)(index.o) \
$(LIBRARY)(memchr.o) \
$(LIBRARY)(memcmp.o) \
$(LIBRARY)(memcpy.o) \
$(LIBRARY)(memmove.o) \
$(LIBRARY)(memset.o) \
$(LIBRARY)(rindex.o) \
$(LIBRARY)(strcat.o) \
$(LIBRARY)(strchr.o) \
$(LIBRARY)(strcmp.o) \
$(LIBRARY)(strcpy.o) \
$(LIBRARY)(strlen.o) \
$(LIBRARY)(strncat.o) \
$(LIBRARY)(strncmp.o) \
$(LIBRARY)(strncpy.o) \
$(LIBRARY)(strnlen.o) \
$(LIBRARY)(strrchr.o) \
$(LIBRARY): $(OBJECTS)
aal cr $@ *.o
rm *.o
$(LIBRARY)(_memmove.o): _memmove.s
$(CC1) _memmove.s
$(LIBRARY)(_strncat.o): _strncat.s
$(CC1) _strncat.s
$(LIBRARY)(_strncmp.o): _strncmp.s
$(CC1) _strncmp.s
$(LIBRARY)(_strncpy.o): _strncpy.s
$(CC1) _strncpy.s
$(LIBRARY)(_strnlen.o): _strnlen.s
$(CC1) _strnlen.s
$(LIBRARY)(bcmp.o): bcmp.s
$(CC1) bcmp.s
$(LIBRARY)(bcopy.o): bcopy.s
$(CC1) bcopy.s
$(LIBRARY)(bzero.o): bzero.s
$(CC1) bzero.s
$(LIBRARY)(index.o): index.s
$(CC1) index.s
$(LIBRARY)(memchr.o): memchr.s
$(CC1) memchr.s
$(LIBRARY)(memcmp.o): memcmp.s
$(CC1) memcmp.s
$(LIBRARY)(memcpy.o): memcpy.s
$(CC1) memcpy.s
$(LIBRARY)(memmove.o): memmove.s
$(CC1) memmove.s
$(LIBRARY)(memset.o): memset.s
$(CC1) memset.s
$(LIBRARY)(rindex.o): rindex.s
$(CC1) rindex.s
$(LIBRARY)(strcat.o): strcat.s
$(CC1) strcat.s
$(LIBRARY)(strchr.o): strchr.s
$(CC1) strchr.s
$(LIBRARY)(strcmp.o): strcmp.s
$(CC1) strcmp.s
$(LIBRARY)(strcpy.o): strcpy.s
$(CC1) strcpy.s
$(LIBRARY)(strlen.o): strlen.s
$(CC1) strlen.s
$(LIBRARY)(strncat.o): strncat.s
$(CC1) strncat.s
$(LIBRARY)(strncmp.o): strncmp.s
$(CC1) strncmp.s
$(LIBRARY)(strncpy.o): strncpy.s
$(CC1) strncpy.s
$(LIBRARY)(strnlen.o): strnlen.s
$(CC1) strnlen.s
$(LIBRARY)(strrchr.o): strrchr.s
$(CC1) strrchr.s

5
lib/i86/string/README Executable file
View File

@@ -0,0 +1,5 @@
Notes on i8086 string assembly routines. Author: Kees J. Bot
27 Jan 1994
These routines are simply translations of the 386 code, so all comments
to that code apply here.

50
lib/i86/string/_memmove.s Executable file
View File

@@ -0,0 +1,50 @@
! _memmove() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! void *_memmove(void *s1, const void *s2, size_t n)
! Copy a chunk of memory. Handle overlap.
!
.sect .text
.define __memmove, __memcpy
__memmove:
push bp
mov bp, sp
push si
push di
mov di, 4(bp) ! String s1
mov si, 6(bp) ! String s2
mov cx, 8(bp) ! Length
mov ax, di
sub ax, si
cmp ax, cx
jb downwards ! if (s2 - s1) < n then copy downwards
__memcpy:
cld ! Clear direction bit: upwards
cmp cx, #16
jb upbyte ! Don't bother being smart with short arrays
mov ax, si
or ax, di
testb al, #1
jnz upbyte ! Bit 0 set, use byte copy
upword: shr cx, #1
rep movs ! Copy words
adc cx, cx ! One more byte?
upbyte:
rep movsb ! Copy bytes
done: mov ax, 4(bp) ! Absolutely noone cares about this value
pop di
pop si
pop bp
ret
! Handle bad overlap by copying downwards, don't bother to do word copies.
downwards:
std ! Set direction bit: downwards
add si, cx
dec si
add di, cx
dec di
rep movsb ! Copy bytes
cld
jmp done

37
lib/i86/string/_strncat.s Executable file
View File

@@ -0,0 +1,37 @@
! _strncat() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! char *_strncat(char *s1, const char *s2, size_t dx)
! Append string s2 to s1.
!
.sect .text
.define __strncat
__strncat:
push bp
mov bp, sp
push si
push di
mov di, 4(bp) ! String s1
mov cx, #-1
xorb al, al ! Null byte
cld
repne scasb ! Look for the zero byte in s1
dec di ! Back one up (and clear 'Z' flag)
push di ! Save end of s1
mov di, 6(bp) ! di = string s2
mov cx, dx ! Maximum count
repne scasb ! Look for the end of s2
jne no0
inc cx ! Exclude null byte
no0: sub dx, cx ! Number of bytes in s2
mov cx, dx
mov si, 6(bp) ! si = string s2
pop di ! di = end of string s1
rep movsb ! Copy bytes
stosb ! Add a terminating null
mov ax, 4(bp) ! Return s1
pop di
pop si
pop bp
ret

36
lib/i86/string/_strncmp.s Executable file
View File

@@ -0,0 +1,36 @@
! strncmp() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! int strncmp(const char *s1, const char *s2, size_t cx)
! Compare two strings.
!
.sect .text
.define __strncmp
__strncmp:
push bp
mov bp, sp
push si
push di
xor ax, ax ! Prepare return value
test cx, cx ! Max length is zero?
je equal
mov si, 4(bp) ! si = string s1
mov di, 6(bp) ! di = string s2
cld
compare:
cmpsb ! Compare two bytes
jne unequal
cmpb -1(si), #0 ! End of string?
je equal
dec cx ! Length limit reached?
jne compare
jmp equal
unequal:
ja after
sub ax, #2 ! if (s1 < s2) ax -= 2;
after: inc ax ! ax++, now it's -1 or 1
equal: pop di
pop si
pop bp
ret

21
lib/i86/string/_strncpy.s Executable file
View File

@@ -0,0 +1,21 @@
! _strncpy() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! char *_strncpy(char *s1, const char *s2, size_t cx)
! Copy string s2 to s1.
!
.sect .text
.define __strncpy
__strncpy:
mov di, 6(bp) ! di = string s2
xorb al, al ! Look for a zero byte
mov dx, cx ! Save maximum count
cld
repne scasb ! Look for end of s2
sub dx, cx ! Number of bytes in s2 including null
xchg cx, dx
mov si, 6(bp) ! si = string s2
mov di, 4(bp) ! di = string s1
rep movsb ! Copy bytes
ret

26
lib/i86/string/_strnlen.s Executable file
View File

@@ -0,0 +1,26 @@
! _strnlen() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! size_t _strnlen(const char *s, size_t cx)
! Return the length of a string.
!
.sect .text
.define __strnlen
__strnlen:
push bp
mov bp, sp
push di
mov di, 4(bp) ! di = string
xorb al, al ! Look for a zero byte
mov dx, cx ! Save maximum count
cmpb cl, #1 ! 'Z' bit must be clear if cx = 0
cld
repne scasb ! Look for zero
jne no0
inc cx ! Don't count zero byte
no0: mov ax, dx
sub ax, cx ! Compute bytes scanned
pop di
pop bp
ret

28
lib/i86/string/bcmp.s Executable file
View File

@@ -0,0 +1,28 @@
! bcmp() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! 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.)
!
.sect .text
.define _bcmp
_bcmp:
push bp
mov bp, sp
push 8(bp)
push 6(bp)
push 4(bp)
call _memcmp ! Let memcmp do the work
mov sp, bp
test ax, ax
jz equal
sub dx, 4(bp) ! Memcmp was nice enough to leave "si" in dx
dec dx ! Number of bytes that are equal
mov ax, 8(bp)
sub ax, dx ! Number of bytes that are unequal
equal: pop bp
ret

19
lib/i86/string/bcopy.s Executable file
View File

@@ -0,0 +1,19 @@
! bcopy() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! 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.
!
.sect .text
.define _bcopy
.extern __memmove
_bcopy:
pop cx
pop ax
pop dx ! Pop return address and arguments
push ax
push dx ! Arguments reversed
push cx
jmp __memmove ! Call the proper routine

21
lib/i86/string/bzero.s Executable file
View File

@@ -0,0 +1,21 @@
! bzero() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! 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.
!
.sect .text
.define _bzero
_bzero:
push bp
mov bp, sp
push 6(bp) ! Size
xor ax, ax
push ax ! Zero
push 4(bp) ! String
call _memset ! Call the proper routine
mov sp, bp
pop bp
ret

12
lib/i86/string/index.s Executable file
View File

@@ -0,0 +1,12 @@
! index() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! char *index(const char *s, int c)
! Look for a character in a string. Has suffered from a hostile
! takeover by strchr().
!
.sect .text
.define _index
_index:
jmp _strchr

28
lib/i86/string/memchr.s Executable file
View File

@@ -0,0 +1,28 @@
! memchr() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! void *memchr(const void *s, int c, size_t n)
! Look for a character in a chunk of memory.
!
.sect .text
.define _memchr
_memchr:
push bp
mov bp, sp
push di
mov di, 4(bp) ! di = string
movb al, 6(bp) ! The character to look for
mov cx, 8(bp) ! Length
cmpb cl, #1 ! 'Z' bit must be clear if cx = 0
cld
repne scasb
jne failure
lea ax, -1(di) ! Found
pop di
pop bp
ret
failure:xor ax, ax
pop di
pop bp
ret

44
lib/i86/string/memcmp.s Executable file
View File

@@ -0,0 +1,44 @@
! memcmp() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! int memcmp(const void *s1, const void *s2, size_t n)
! Compare two chunks of memory.
!
.sect .text
.define _memcmp
_memcmp:
cld
push bp
mov bp, sp
push si
push di
xor ax, ax ! Prepare return value
mov si, 4(bp) ! String s1
mov di, 6(bp) ! String s2
mov cx, 8(bp) ! Length
cmp cx, #16
jb cbyte ! Don't bother being smart with short arrays
mov dx, si
or dx, di
andb dl, #1
jnz cbyte ! Bit 0 set, use byte compare
cword: sar cx, #1
adcb dl, dl ! Save carry
repe cmps ! Compare words
mov cx, #2 ! Recompare the last word
sub si, cx
sub di, cx
addb cl, dl ! One more byte?
cbyte: test cx, cx ! Set 'Z' flag if cx = 0
last:
repe cmpsb ! Look for the first differing byte
je equal
ja after
sub ax, #2 ! if (s1 < s2) ax -= 2;
after: inc ax ! ax++, now it's -1 or 1
equal: mov dx, si ! For bcmp() to play with
pop di
pop si
pop bp
ret

23
lib/i86/string/memcpy.s Executable file
View File

@@ -0,0 +1,23 @@
! memcpy() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! 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.
!
.sect .text
.define _memcpy
_memcpy:
push bp
mov bp, sp
push si
push di
mov di, 4(bp) ! String s1
mov si, 6(bp) ! String s2
mov cx, 8(bp) ! Length
! No overlap check here
jmp __memcpy ! Call the part of __memmove that copies up

11
lib/i86/string/memmove.s Executable file
View File

@@ -0,0 +1,11 @@
! memmove() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! void *memmove(void *s1, const void *s2, size_t n)
! Copy a chunk of memory. Handle overlap.
!
.sect .text
.define _memmove
_memmove:
jmp __memmove ! Call common code

31
lib/i86/string/memset.s Executable file
View File

@@ -0,0 +1,31 @@
! memset() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! void *memset(void *s, int c, size_t n)
! Set a chunk of memory to the same byte value.
!
.sect .text
.define _memset
_memset:
push bp
mov bp, sp
push di
mov di, 4(bp) ! The string
movb al, 6(bp) ! The fill byte
mov cx, 8(bp) ! Length
cld
cmp cx, #16
jb sbyte ! Don't bother being smart with short arrays
test di, #1
jnz sbyte ! Bit 0 set, use byte store
sword: movb ah, al ! One byte to two bytes
sar cx, #1
rep stos ! Store words
adc cx, cx ! One more byte?
sbyte:
rep stosb ! Store bytes
done: mov ax, 4(bp) ! Return some value you have no need for
pop di
pop bp
ret

12
lib/i86/string/rindex.s Executable file
View File

@@ -0,0 +1,12 @@
! rindex() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! 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().
!
.sect .text
.define _rindex
_rindex:
jmp _strrchr

12
lib/i86/string/strcat.s Executable file
View File

@@ -0,0 +1,12 @@
! strcat() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! char *strcat(char *s1, const char *s2)
! Append string s2 to s1.
!
.sect .text
.define _strcat
_strcat:
mov dx, #-1 ! Unlimited length
jmp __strncat ! Common code

38
lib/i86/string/strchr.s Executable file
View File

@@ -0,0 +1,38 @@
! strchr() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! char *strchr(const char *s, int c)
! Look for a character in a string.
!
.sect .text
.define _strchr
_strchr:
push bp
mov bp, sp
push di
cld
mov di, 4(bp) ! di = string
mov dx, #16 ! Look at small chunks of the string
next: shl dx, #1 ! Chunks become bigger each time
mov cx, dx
xorb al, al ! Look for the zero at the end
repne scasb
pushf ! Remember the flags
sub cx, dx
neg cx ! Some or all of the chunk
sub di, cx ! Step back
movb al, 6(bp) ! The character to look for
repne scasb
je found
popf ! Did we find the end of string earlier?
jne next ! No, try again
xor ax, ax ! Return NULL
pop di
pop bp
ret
found: pop ax ! Get rid of those flags
lea ax, -1(di) ! Address of byte found
pop di
pop bp
ret

12
lib/i86/string/strcmp.s Executable file
View File

@@ -0,0 +1,12 @@
! strcmp() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! int strcmp(const char *s1, const char *s2)
! Compare two strings.
!
.sect .text
.define _strcmp
_strcmp:
mov cx, #-1 ! Unlimited length
jmp __strncmp ! Common code

21
lib/i86/string/strcpy.s Executable file
View File

@@ -0,0 +1,21 @@
! strcpy() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! char *strcpy(char *s1, const char *s2)
! Copy string s2 to s1.
!
.sect .text
.define _strcpy
_strcpy:
push bp
mov bp, sp
push si
push di
mov cx, #-1 ! Unlimited length
call __strncpy ! Common code
mov ax, 4(bp) ! Return s1
pop di
pop si
pop bp
ret

12
lib/i86/string/strlen.s Executable file
View File

@@ -0,0 +1,12 @@
! strlen() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! size_t strlen(const char *s)
! Return the length of a string.
!
.sect .text
.define _strlen
_strlen:
mov cx, #-1 ! Unlimited length
jmp __strnlen ! Common code

13
lib/i86/string/strncat.s Executable file
View File

@@ -0,0 +1,13 @@
! strncat() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! size_t strncat(char *s1, const char *s2, size_t n)
! Append string s2 to s1.
!
.sect .text
.define _strncat
_strncat:
mov bx, sp
mov dx, 6(bx) ! Maximum length
jmp __strncat ! Common code

13
lib/i86/string/strncmp.s Executable file
View File

@@ -0,0 +1,13 @@
! strncmp() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! int strncmp(const char *s1, const char *s2, size_t n)
! Compare two strings.
!
.sect .text
.define _strncmp
_strncmp:
mov bx, sp
mov cx, 6(bx) ! Maximum length
jmp __strncmp ! Common code

23
lib/i86/string/strncpy.s Executable file
View File

@@ -0,0 +1,23 @@
! strncpy() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! char *strncpy(char *s1, const char *s2, size_t n)
! Copy string s2 to s1.
!
.sect .text
.define _strncpy
_strncpy:
push bp
mov bp, sp
push si
push di
mov cx, 8(bp) ! Maximum length
call __strncpy ! Common code
mov cx, dx ! Number of bytes not copied
rep stosb ! strncpy always copies n bytes by null padding
mov ax, 4(bp) ! Return s1
pop di
pop si
pop bp
ret

13
lib/i86/string/strnlen.s Executable file
View File

@@ -0,0 +1,13 @@
! strnlen() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! size_t strnlen(const char *s, size_t n)
! Return the length of a string.
!
.sect .text
.define _strnlen
_strnlen:
mov bx, sp
mov cx, 4(bx) ! Maximum length
jmp __strnlen ! Common code

33
lib/i86/string/strrchr.s Executable file
View File

@@ -0,0 +1,33 @@
! strrchr() Author: Kees J. Bot
! 27 Jan 1994
.sect .text; .sect .rom; .sect .data; .sect .bss
! char *strrchr(const char *s, int c)
! Look for the last occurrence a character in a string.
!
.sect .text
.define _strrchr
_strrchr:
push bp
mov bp, sp
push di
mov di, 4(bp) ! di = string
mov cx, #-1
xorb al, al
cld
repne scasb ! Look for the end of the string
not cx ! -1 - cx = Length of the string + null
dec di ! Put di back on the zero byte
movb al, 6(bp) ! The character to look for
std ! Downwards search
repne scasb
cld ! Direction bit back to default
jne failure
lea ax, 1(di) ! Found it
pop di
pop bp
ret
failure:xor ax, ax ! Not there
pop di
pop bp
ret