From 5278f6def4248391a481382bd7b0042b04c829f2 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Tue, 21 Apr 2026 23:16:50 +0800 Subject: feat: add string manipulation functions derived from musl libc This commit introduces a variety of string manipulation functions, including: - `memmem`: Searches for a substring in a memory area. - `memmove`: Safely copies memory areas, handling overlaps. - `mempcpy`: Copies memory and returns a pointer to the end of the destination. - `memrchr`: Finds the last occurrence of a character in a memory area. - `memset`: Fills a memory area with a specified value. - `rindex`: Returns the last occurrence of a character in a string. - `stpcpy` and `stpncpy`: Copies strings and returns a pointer to the end. - `strcat`, `strchr`, `strcspn`, `strlcat`, `strlcpy`, `strlen`, `strncat`, `strncmp`, `strncpy`, `strnlen`, `strpbrk`, `strrchr`, `strstr`, `strtok`, and `strtok_r`: Various string manipulation functions for concatenation, searching, and tokenization. Assembly implementations for `memcpy`, `memmove`, and `memset` are also included for optimized performance on x86_64 architectures. --- na/lib/string/i386/memcpy.s | 32 +++++++++++++++++++ na/lib/string/i386/memmove.s | 22 +++++++++++++ na/lib/string/i386/memset.s | 76 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 na/lib/string/i386/memcpy.s create mode 100644 na/lib/string/i386/memmove.s create mode 100644 na/lib/string/i386/memset.s (limited to 'na/lib/string/i386') diff --git a/na/lib/string/i386/memcpy.s b/na/lib/string/i386/memcpy.s new file mode 100644 index 0000000..0608dd8 --- /dev/null +++ b/na/lib/string/i386/memcpy.s @@ -0,0 +1,32 @@ +.global memcpy +.global __memcpy_fwd +.hidden __memcpy_fwd +.type memcpy,@function +memcpy: +__memcpy_fwd: + push %esi + push %edi + mov 12(%esp),%edi + mov 16(%esp),%esi + mov 20(%esp),%ecx + mov %edi,%eax + cmp $4,%ecx + jc 1f + test $3,%edi + jz 1f +2: movsb + dec %ecx + test $3,%edi + jnz 2b +1: mov %ecx,%edx + shr $2,%ecx + rep + movsl + and $3,%edx + jz 1f +2: movsb + dec %edx + jnz 2b +1: pop %edi + pop %esi + ret diff --git a/na/lib/string/i386/memmove.s b/na/lib/string/i386/memmove.s new file mode 100644 index 0000000..2a6a504 --- /dev/null +++ b/na/lib/string/i386/memmove.s @@ -0,0 +1,22 @@ +.global memmove +.type memmove,@function +memmove: + mov 4(%esp),%eax + sub 8(%esp),%eax + cmp 12(%esp),%eax +.hidden __memcpy_fwd + jae __memcpy_fwd + push %esi + push %edi + mov 12(%esp),%edi + mov 16(%esp),%esi + mov 20(%esp),%ecx + lea -1(%edi,%ecx),%edi + lea -1(%esi,%ecx),%esi + std + rep movsb + cld + lea 1(%edi),%eax + pop %edi + pop %esi + ret diff --git a/na/lib/string/i386/memset.s b/na/lib/string/i386/memset.s new file mode 100644 index 0000000..d00422c --- /dev/null +++ b/na/lib/string/i386/memset.s @@ -0,0 +1,76 @@ +.global memset +.type memset,@function +memset: + mov 12(%esp),%ecx + cmp $62,%ecx + ja 2f + + mov 8(%esp),%dl + mov 4(%esp),%eax + test %ecx,%ecx + jz 1f + + mov %dl,%dh + + mov %dl,(%eax) + mov %dl,-1(%eax,%ecx) + cmp $2,%ecx + jbe 1f + + mov %dx,1(%eax) + mov %dx,(-1-2)(%eax,%ecx) + cmp $6,%ecx + jbe 1f + + shl $16,%edx + mov 8(%esp),%dl + mov 8(%esp),%dh + + mov %edx,(1+2)(%eax) + mov %edx,(-1-2-4)(%eax,%ecx) + cmp $14,%ecx + jbe 1f + + mov %edx,(1+2+4)(%eax) + mov %edx,(1+2+4+4)(%eax) + mov %edx,(-1-2-4-8)(%eax,%ecx) + mov %edx,(-1-2-4-4)(%eax,%ecx) + cmp $30,%ecx + jbe 1f + + mov %edx,(1+2+4+8)(%eax) + mov %edx,(1+2+4+8+4)(%eax) + mov %edx,(1+2+4+8+8)(%eax) + mov %edx,(1+2+4+8+12)(%eax) + mov %edx,(-1-2-4-8-16)(%eax,%ecx) + mov %edx,(-1-2-4-8-12)(%eax,%ecx) + mov %edx,(-1-2-4-8-8)(%eax,%ecx) + mov %edx,(-1-2-4-8-4)(%eax,%ecx) + +1: ret + +2: movzbl 8(%esp),%eax + mov %edi,12(%esp) + imul $0x1010101,%eax + mov 4(%esp),%edi + test $15,%edi + mov %eax,-4(%edi,%ecx) + jnz 2f + +1: shr $2, %ecx + rep + stosl + mov 4(%esp),%eax + mov 12(%esp),%edi + ret + +2: xor %edx,%edx + sub %edi,%edx + and $15,%edx + mov %eax,(%edi) + mov %eax,4(%edi) + mov %eax,8(%edi) + mov %eax,12(%edi) + sub %edx,%ecx + add %edx,%edi + jmp 1b -- cgit v1.2.3