146 lines
2.8 KiB
NASM
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
|