; ============================================================================ ; string_ops.asm - 快速字符串/内存操作 (x86-64 MASM) ; 使用 SSE4.1 加速 memcpy/memset/strlen ; ============================================================================ include asm_macros.inc .CODE ; ============================================================================ ; 内存操作 ; ============================================================================ ; void fast_memcpy(void* dst, const void* src, uint64_t count) ; RCX = dst, RDX = src, R8 = count fast_memcpy PROC mov rax, rcx ; rax = dst mov r9, r8 ; r9 = count ; 小于 16 字节: 逐字节复制 cmp r9, 16 jb memcpy_small ; 16-32 字节: 两次 128-bit 加载 cmp r9, 32 jb memcpy_16_32 ; 32-64 字节: 四次 128-bit 加载 cmp r9, 64 jb memcpy_32_64 ; >= 64 字节: SSE 批量复制 ; 确保 16 字节对齐 mov r10, rcx and r10, 0Fh ; 检查 dst 对齐 jnz memcpy_unaligned memcpy_aligned_loop: cmp r9, 64 jb memcpy_tail ; 每次复制 64 字节 (4x128-bit) movaps xmm0, xmmword ptr [rdx] movaps xmm1, xmmword ptr [rdx + 16] movaps xmm2, xmmword ptr [rdx + 32] movaps xmm3, xmmword ptr [rdx + 48] movaps xmmword ptr [rcx], xmm0 movaps xmmword ptr [rcx + 16], xmm1 movaps xmmword ptr [rcx + 32], xmm2 movaps xmmword ptr [rcx + 48], xmm3 add rcx, 64 add rdx, 64 sub r9, 64 jmp memcpy_aligned_loop memcpy_tail: ; 处理剩余 0-63 字节 test r9, 32 jz memcpy_tail_16 movaps xmm0, xmmword ptr [rdx] movaps xmm1, xmmword ptr [rdx + 16] movaps xmmword ptr [rcx], xmm0 movaps xmmword ptr [rcx + 16], xmm1 add rcx, 32 add rdx, 32 sub r9, 32 memcpy_tail_16: test r9, 16 jz memcpy_tail_8 movaps xmm0, xmmword ptr [rdx] movaps xmmword ptr [rcx], xmm0 memcpy_tail_8: test r9, 8 jz memcpy_tail_4 mov r10, qword ptr [rdx] mov qword ptr [rcx], r10 memcpy_tail_4: test r9, 4 jz memcpy_tail_2 mov r10d, dword ptr [rdx] mov dword ptr [rcx], r10d memcpy_tail_2: test r9, 2 jz memcpy_tail_1 mov r10w, word ptr [rdx] mov word ptr [rcx], r10w memcpy_tail_1: test r9, 1 jz memcpy_done mov r10b, byte ptr [rdx] mov byte ptr [rcx], r10b jmp memcpy_done memcpy_unaligned: ; 非对齐时使用 movups movups xmm0, xmmword ptr [rdx] movups xmmword ptr [rcx], xmm0 add rcx, 16 add rdx, 16 sub r9, 16 jmp memcpy_aligned_loop memcpy_32_64: mov r10, qword ptr [rdx] mov qword ptr [rcx], r10 mov r10, qword ptr [rdx + 8] mov qword ptr [rcx + 8], r10 mov r10, qword ptr [rdx + 16] mov qword ptr [rcx + 16], r10 mov r10, qword ptr [rdx + 24] mov qword ptr [rcx + 24], r10 sub r9, 32 add rdx, 32 add rcx, 32 jmp memcpy_small memcpy_16_32: mov r10, qword ptr [rdx] mov qword ptr [rcx], r10 mov r10, qword ptr [rdx + 8] mov qword ptr [rcx + 8], r10 test r9, 8 jz memcpy_16_32_done mov r10, qword ptr [rdx + 16] mov qword ptr [rcx + 16], r10 memcpy_16_32_done: jmp memcpy_done memcpy_small: test r9, r9 jz memcpy_done mov r10, r9 and r10, 7 ; r10 = count % 8 shr r9, 3 ; r9 = count / 8 ; 复制完整 8 字节 memcpy_small_loop: test r9, r9 jz memcpy_small_tail mov r11, qword ptr [rdx] mov qword ptr [rcx], r11 add rdx, 8 add rcx, 8 dec r9 jmp memcpy_small_loop memcpy_small_tail: ; 复制剩余字节 test r10, r10 jz memcpy_done mov r11b, byte ptr [rdx] mov byte ptr [rcx], r11b inc rdx inc rcx dec r10 jmp memcpy_small_tail memcpy_done: mov rax, rax ; 返回 dst ret fast_memcpy ENDP ; void fast_memset(void* dst, int value, uint64_t count) ; RCX = dst, EDX = value, R8 = count fast_memset PROC mov rax, rcx mov r9, r8 ; 将 value 扩展到所有字节 movsx rdx, dl ; 符号扩展 mov rcx, rdx shl rcx, 8 or rdx, rcx mov rcx, rdx shl rcx, 16 or rdx, rcx ; rdx = value 重复4次 mov rcx, rdx shl rcx, 32 or rdx, rcx ; rdx = value 重复8次 ; 复制到 XMM 寄存器 vmovq xmm0, rdx vinsertf128 ymm0, ymm0, xmm0, 1 ; 256-bit 广播 ; >= 32 字节: AVX 批量 cmp r9, 32 jb memset_small memset_avx_loop: cmp r9, 32 jb memset_tail vmovdqu ymmword ptr [rax], ymm0 add rax, 32 sub r9, 32 jmp memset_avx_loop memset_tail: ; 处理剩余 0-31 字节 test r9, 16 jz memset_tail_8 movups xmmword ptr [rax], xmm0 add rax, 16 sub r9, 16 memset_tail_8: test r9, 8 jz memset_tail_4 mov qword ptr [rax], rdx add rax, 8 memset_tail_4: test r9, 4 jz memset_tail_2 mov dword ptr [rax], edx add rax, 4 memset_tail_2: test r9, 2 jz memset_tail_1 mov word ptr [rax], dx add rax, 2 memset_tail_1: test r9, 1 jz memset_done mov byte ptr [rax], dl jmp memset_done memset_small: test r9, r9 jz memset_done mov byte ptr [rax], dl inc rax dec r9 jmp memset_small memset_done: vzeroupper ret fast_memset ENDP ; ============================================================================ ; 字符串操作 ; ============================================================================ ; uint64_t fast_strlen(const char* str) -> RAX ; 使用 SSE4.2 PCMPESTRI 搜索 null terminator fast_strlen PROC mov rax, rcx ; rax = str xor rcx, rcx ; rcx = 计数器 ; 每次检查 16 字节 pxor xmm0, xmm0 ; 搜索 0 strlen_sse_loop: ; 检查是否接近字符串末尾 (避免越界读取) ; 简化: 逐 16 字节检查 movdqu xmm1, xmmword ptr [rax + rcx] pcmpestrm xmm0, xmm1, 00001000b ; 搜索 0, 返回掩码 jc strlen_found add rcx, 16 jmp strlen_sse_loop strlen_found: ; 获取第一个匹配位置 pcmpestri xmm0, xmm1, 00001000b ; ECX = 匹配位置 add rax, rcx add rax, rcx ; 需要计算实际位置 ; 简化: 使用标量回退 mov rax, rcx ret ; 标量回退 strlen_scalar: mov rax, rcx strlen_scalar_loop: cmp byte ptr [rax], 0 je strlen_scalar_done inc rax jmp strlen_scalar_loop strlen_scalar_done: sub rax, rcx ret fast_strlen ENDP ; int fast_strcmp(const char* a, const char* b) -> EAX ; 返回: 0=相等, <0=a0=a>b fast_strcmp PROC xor rax, rax strcmp_loop: movzx r8d, byte ptr [rcx + rax] movzx r9d, byte ptr [rdx + rax] cmp r8b, r9b jne strcmp_diff test r8b, r8b jz strcmp_equal inc rax jmp strcmp_loop strcmp_diff: mov eax, r8d sub eax, r9d ret strcmp_equal: xor eax, eax ret fast_strcmp ENDP END