Initial revision
This commit is contained in:
112
lib/i86/string/Makefile
Executable file
112
lib/i86/string/Makefile
Executable 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
5
lib/i86/string/README
Executable 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
50
lib/i86/string/_memmove.s
Executable 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
37
lib/i86/string/_strncat.s
Executable 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
36
lib/i86/string/_strncmp.s
Executable 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
21
lib/i86/string/_strncpy.s
Executable 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
26
lib/i86/string/_strnlen.s
Executable 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
28
lib/i86/string/bcmp.s
Executable 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
19
lib/i86/string/bcopy.s
Executable 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
21
lib/i86/string/bzero.s
Executable 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
12
lib/i86/string/index.s
Executable 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
28
lib/i86/string/memchr.s
Executable 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
44
lib/i86/string/memcmp.s
Executable 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
23
lib/i86/string/memcpy.s
Executable 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
11
lib/i86/string/memmove.s
Executable 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
31
lib/i86/string/memset.s
Executable 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
12
lib/i86/string/rindex.s
Executable 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
12
lib/i86/string/strcat.s
Executable 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
38
lib/i86/string/strchr.s
Executable 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
12
lib/i86/string/strcmp.s
Executable 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
21
lib/i86/string/strcpy.s
Executable 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
12
lib/i86/string/strlen.s
Executable 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
13
lib/i86/string/strncat.s
Executable 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
13
lib/i86/string/strncmp.s
Executable 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
23
lib/i86/string/strncpy.s
Executable 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
13
lib/i86/string/strnlen.s
Executable 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
33
lib/i86/string/strrchr.s
Executable 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
|
||||
Reference in New Issue
Block a user