%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