kvisc/ka/crt/str.k

223 lines
2.7 KiB
Plaintext

; The OS/K Team licenses this file to you under the MIT license.
; See the LICENSE file in the project root for more information.
;
; int strnlen(char *, int)
;
strnlen:
mov ecx, ax1
scasb ax0, zero
sub eax, ax1, ecx
ret
;
; int strlen(char *)
;
strlen:
mov ecx, STRLEN_MAX
mov edx, ecx
scasb ax0, zero
sub eax, edx, ecx
ret
;
; void strcpy(char *, const char *)
;
strcpy:
.l:
mov ecx, b[ax1]
mov b[ax0], ecx
jrcxz .r
inc ax0
inc ax1
jmp .l
.r:
ret
;
; void strncpy(char *, const char *, int)
;
strncpy:
mov ecx, ax2
jrcxz .r
.l:
mov b[ax0], b[ax1]
inc ax0
inc ax1
loop .l
.r:
ret
;
; void strnzcpy(char *, const char *, int)
;
strnzcpy:
mov ecx, ax2
jrcxz .r
.l:
mov eax, b[ax1]
mov b[ax0], eax
jraxz .r
inc ax0
inc ax1
loop .l
.z:
nul b[ax0]
.r:
ret
;
; int strcmp(const char *str1, const char *str2)
;
; Returns:
; 0 if the contents of both strings are equal
; >0 if the first character that does not match has a greater value in str1 than in str2
; <0 if the first character that does not match has a lower value in str1 than in str2
;
strcmp:
nul esi
.l:
movzx eax, b[ax0+esi]
movzx edx, b[ax1+esi]
bne eax, edx, .r
; both zero?
add ecx, eax, edx
jrcxz .r
inc esi
jmp .l
.r:
sub eax, edx
ret
;
; int strncmp(const char *str1, const char *str2, int maxn)
;
strncmp:
mov ecx, ax2
jrcxz .r
.l:
movzx eax, b[ax0]
movzx edx, b[ax1]
bne eax, edx, .r
inc ax0
inc ax1
loop .l
.r:
sub eax, edx
ret
;
; char *strchrnul(const char *str, int ch)
;
strchrnul:
mov ecx, STRLEN_MAX
scasb ax0, ax1
mov eax, ax0
ret
;
; char *strchr(const char *str, int ch)
;
strchr:
mov ecx, STRLEN_MAX
scasb ax0, ax1
bnz b[ax0], .r
nul eax
ret
.r:
mov eax, ax0
ret
;
; void strrev(char *buf, const char *str)
;
; buf and src must NOT overlap
;
strrev:
bzr b[ax1], .z
; save str's location
mov esi, ax1
; go to str's end, just before
; the null terminator
mov ecx, STRLEN_MAX
scasb ax1, zero
dec ax1
.l:
; copy, going backward though str
; and forward through buf
mov b[ax0], b[ax1]
beq ax1, esi, .r
inc ax0
dec ax1
jmp .l
.r:
nul b[ax0+1]
ret
.z:
nul b[ax0]
ret
;
; void strrev2(char *str)
;
; Inverses str
;
strrev2:
bzr b[ax0], .r
mov ax1, ax0
; go to str's end, just before
; the null terminator
mov ecx, STRLEN_MAX
scasb ax1, zero
dec ax1
; increase ax0 while decreasing ax1, performing exchanges
.l:
blteu ax1, ax0, .r
xchg b[ax0], b[ax1]
inc ax0
dec ax1
jmp .l
.r:
ret