Files
klibc/src/string.asm

146 lines
2.8 KiB
NASM

%include "src/constants.asm"
section .text
global strlen
global strcpy
global strcat
global strclr
global strcmp
;----- strlen(*str[]) -----;
; Gets the length of given string
; Return value: Length of given string
; Used registers:
; rax* Byte to check in str[] >> (ret) length of given string
; rdi* (arg) Pointer to str[]
; rcx* Counter for scasb
strlen:
xor al, al
mov rcx, -1
cld
repne scasb
mov rax, rcx
not rax
dec rax
ret
;----- strcpy(*dest[], *src[], maxLength) -----;
; Copies one string (src) into the other (dest), overwriting dest
; NOTE: maxLength must never exceed size of dest[].
; Return value: Pointer to dest[]
; Used registers:
; rax* (ret) Pointer to dest[]
; rdi* (arg) Pointer to dest[]
; rsi* (arg) Pointer to src[]
; rdx (arg) Size of dest[]
; rcx* Counter for movsb
; r8* Backup for rdi
strcpy:
mov r8, rdi
mov rdi, rsi
call strlen
inc rax
cmp rax, rdx
cmova rcx, rdx
cmovbe rcx, rax
cmp rcx, rdx
jb .copy
dec rcx
.copy:
mov rdi, r8
cld
rep movsb
mov byte [rdi], EOS
mov rax, r8
ret
;----- strcat(*dest[], *src[], maxLength) -----;
; Concatenate src[] into dest[]
; Return value: Pointer to dest[]
; Used registers:
; rax* (ret) Pointer to dest[]
; rdi* (arg) Pointer to dest[]
; rsi* (arg) Pointer to src[]
; rdx (arg) Size of dest[]
; rcx* Counter for movsb
; r8* Backup for rdi (point to start of dest)
; r9* Backup for rsi
; r10* Backup for rdi (point to end of dest)
strcat:
mov r8, rdi
mov r9, rsi
call strlen
sub rdx, rax
dec rdi
mov r10, rdi
mov rdi, rsi
call strlen
cmp rax, rdx
jb .copy
dec rdx
.copy:
mov rcx, rdx
mov rsi, r9
mov rdi, r10
cld
rep movsb
mov byte [rdi], EOS
mov rax, r8
ret
;----- strclr(*str[], maxLength) -----;
; Clears a string by placing [maxLength] EOS into string.
; Thus DANGEROUS function: MAKE SURE maxLength IS SIZE OF str[] - greater values WILL cause issues and eventually crashes
; Return value: N/A
; Used registers:
; rdi* (arg) Pointer to str[]
; rsi (arg) Length of str[]
; rcx* Counter for STOSB
; rax* Character storage (AL) for STOSB
strclr:
mov rcx, rsi
xor al, al
cld
rep stosb
ret
;----- strcmp(*str1[], *str2[]) -----;
; Compares str2 against str1
; Return values:
; 0 Two strings are the same, OR str1 or str2 is empty
; Length of str1 str2 is longer than str1, but no difference was found in between str1 and str2 -up to the point str1 ended-
; Anything else Position (index+1) where str1 and str2 differ
; Used registers:
; rax* (ret)
; rdi Pointer to str1
; rsi Pointer to str2
; rcx* Counter for scasb
; rdx* Length of str1
; r8* Backup for rdi
strcmp:
xor rax, rax
cmp byte [rdi], EOS
je .equal
cmp byte [rsi], EOS
je .equal
mov r8, rdi
call strlen
mov rcx, rax
mov rdx, rax
mov rdi, r8
cld
repe cmpsb
je .equal
mov rax, rdx
sub rax, rcx
jmp .quit
.equal:
cmp byte [rsi], EOS
jne .quit
xor rax, rax
.quit:
ret