MiMoEngine ASM: x86-64 MASM汇编+C混合架构游戏引擎

核心热路径(数学/内存/字符串/性能分析)用MASM汇编(SSE/AVX2)
外围系统(窗口/渲染/ECS/音频/UI/脚本)用C语言
含自研编辑器、VisualScript积木编程、中文渲染(glyph_atlas)
This commit is contained in:
shuiyu1123 committed 2026-07-10 19:20:40 +08:00
commit 2d56cb3bc9
91 files changed
+9988

No files matched your search

+127
View File
@@ -0,0 +1,127 @@
; ============================================================================
; asm_macros.inc - MASM 通用宏定义
; Windows x64 调用约定: RCX, RDX, R8, R9 传参, XMM0-XMM3 浮点
; ============================================================================
; --- 函数帧管理宏 ---
; PROLOGUE: 保存非易失寄存器, 分配栈空间
; 使用: PROLOGUE 栈空间大小
PROLOGUE MACRO stack_size:REQ
push rbx
push rbp
push rdi
push rsi
push r12
push r13
push r14
push r15
sub rsp, stack_size
; 保存浮点参数寄存器 (如果有)
movsd qword ptr [rsp + stack_size - 8], xmm6
movsd qword ptr [rsp + stack_size - 16], xmm7
ENDM
; EPILOGUE: 恢复非易失寄存器, 释放栈空间
EPILOGUE MACRO stack_size:REQ
movsd xmm6, qword ptr [rsp + stack_size - 8]
movsd xmm7, qword ptr [rsp + stack_size - 16]
add rsp, stack_size
pop r15
pop r14
pop r13
pop r12
pop rsi
pop rdi
pop rbp
pop rbx
ret
ENDM
; --- SSE/AVX 常量 ---
.DATA
ALIGN 16
sse_mask_abs DD 07FFFFFFFH, 07FFFFFFFH, 07FFFFFFFH, 07FFFFFFFH ; 绝对值掩码
sse_negate DD 80000000H, 80000000H, 80000000H, 80000000H ; 符号位掩码
sse_one DD 3F800000H, 3F800000H, 3F800000H, 3F800000H ; 1.0f
sse_half DD 3F000000H, 3F000000H, 3F000000H, 3F000000H ; 0.5f
eps_float DD 33D6BF94H ; 1e-6f
.CODE
; --- 工具宏 ---
; LOAD_VEC3: 从内存加载 Vec3 到 XMM 寄存器 (填充 w=1.0)
; ptr: 内存地址, reg: XMM 寄存器
LOAD_VEC3 MACRO ptr, reg
movss xmm0, dword ptr [ptr] ; x
movss xmm1, dword ptr [ptr + 4] ; y
movss xmm2, dword ptr [ptr + 8] ; z
unpcklps xmm0, xmm1 ; {x, y, ?, ?}
movss xmm3, dword ptr [sse_one] ; w = 1.0
unpcklps xmm2, xmm3 ; {z, 1.0, ?, ?}
movlhps xmm0, xmm2 ; {x, y, z, 1.0}
movaps reg, xmm0
ENDM
; STORE_VEC3: 将 XMM 寄存器的前3个float存储到内存
STORE_VEC3 MACRO reg, ptr
movss dword ptr [ptr], xmm0 ; x
shufps xmm0, xmm0, 01010101b
movss dword ptr [ptr + 4], xmm0 ; y
shufps xmm0, xmm0, 10101010b
movss dword ptr [ptr + 8], xmm0 ; z
ENDM
; --- 外部函数声明 ---
externdef vec3_add:PROC
externdef vec3_sub:PROC
externdef vec3_scale:PROC
externdef vec3_dot:PROC
externdef vec3_cross:PROC
externdef vec3_length:PROC
externdef vec3_normalize:PROC
externdef vec3_lerp:PROC
externdef vec3_distance:PROC
externdef vec4_add:PROC
externdef vec4_sub:PROC
externdef vec4_mul:PROC
externdef vec4_dot:PROC
externdef vec4_length:PROC
externdef vec4_normalize:PROC
externdef mat4_identity:PROC
externdef mat4_multiply:PROC
externdef mat4_transpose:PROC
externdef mat4_invert:PROC
externdef mat4_translate:PROC
externdef mat4_scale_f:PROC
externdef mat4_rotate_x:PROC
externdef mat4_rotate_y:PROC
externdef mat4_rotate_z:PROC
externdef mat4_perspective:PROC
externdef mat4_orthographic:PROC
externdef mat4_lookat:PROC
externdef quat_multiply:PROC
externdef quat_conjugate:PROC
externdef quat_normalize:PROC
externdef quat_rotate_vec3:PROC
externdef quat_slerp:PROC
externdef quat_to_matrix:PROC
externdef quat_from_axis_angle:PROC
externdef quat_from_euler:PROC
externdef mem_aligned_alloc:PROC
externdef mem_aligned_free:PROC
externdef mem_aligned_realloc:PROC
externdef fast_memcpy:PROC
externdef fast_memset:PROC
externdef fast_strlen:PROC
externdef fast_strcmp:PROC
externdef prof_rdtsc:PROC
externdef prof_cycles_to_ms:PROC
externdef prof_get_freq:PROC
+1150
View File
File diff suppressed because it is too large. Load diff
+55
View File
@@ -0,0 +1,55 @@
#pragma once
#include <math.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <Windows.h>
#ifndef MATH_ASM_AVAILABLE
typedef struct { float x, y, z; } Vec3;
typedef struct { float x, y, z, w; } Vec4;
typedef struct { float m[4][4]; } Mat4;
typedef struct { float x, y, z, w; } Quat;
static inline void vec3_add(const Vec3* a, const Vec3* b, Vec3* o) { o->x=a->x+b->x; o->y=a->y+b->y; o->z=a->z+b->z; }
static inline void vec3_sub(const Vec3* a, const Vec3* b, Vec3* o) { o->x=a->x-b->x; o->y=a->y-b->y; o->z=a->z-b->z; }
static inline void vec3_scale(const Vec3* a, float s, Vec3* o) { o->x=a->x*s; o->y=a->y*s; o->z=a->z*s; }
static inline float vec3_dot(const Vec3* a, const Vec3* b) { return a->x*b->x+a->y*b->y+a->z*b->z; }
static inline void vec3_cross(const Vec3* a, const Vec3* b, Vec3* o) { o->x=a->y*b->z-a->z*b->y; o->y=a->z*b->x-a->x*b->z; o->z=a->x*b->y-a->y*b->x; }
static inline float vec3_length(const Vec3* a) { return sqrtf(a->x*a->x+a->y*a->y+a->z*a->z); }
static inline void vec3_normalize(const Vec3* a, Vec3* o) { float l=vec3_length(a); if(l<1e-6f){o->x=o->y=o->z=0;return;} float i=1.0f/l; o->x=a->x*i; o->y=a->y*i; o->z=a->z*i; }
static inline void vec3_lerp(const Vec3* a, const Vec3* b, float t, Vec3* o) { o->x=a->x+(b->x-a->x)*t; o->y=a->y+(b->y-a->y)*t; o->z=a->z+(b->z-a->z)*t; }
static inline float vec3_distance(const Vec3* a, const Vec3* b) { Vec3 d; vec3_sub(a,b,&d); return vec3_length(&d); }
static inline void mat4_identity(Mat4* o) { memset(o,0,sizeof(Mat4)); o->m[0][0]=o->m[1][1]=o->m[2][2]=o->m[3][3]=1.0f; }
static inline void mat4_multiply(const Mat4* a, const Mat4* b, Mat4* o) { Mat4 r; int i,j,k; for(i=0;i<4;i++) for(j=0;j<4;j++) { r.m[i][j]=0; for(k=0;k<4;k++) r.m[i][j]+=a->m[i][k]*b->m[k][j]; } *o=r; }
static inline void mat4_translate(float x, float y, float z, Mat4* o) { mat4_identity(o); o->m[3][0]=x; o->m[3][1]=y; o->m[3][2]=z; }
static inline void mat4_rotate_y(float angle, Mat4* o) { float c=cosf(angle),s=sinf(angle); mat4_identity(o); o->m[0][0]=c; o->m[0][2]=-s; o->m[2][0]=s; o->m[2][2]=c; }
static inline void mat4_perspective(float fov, float aspect, float nearP, float farP, Mat4* o) { float t=tanf(fov*0.5f); memset(o,0,sizeof(Mat4)); o->m[0][0]=1.0f/(aspect*t); o->m[1][1]=1.0f/t; o->m[2][2]=farP/(nearP-farP); o->m[2][3]=-1.0f; o->m[3][2]=(nearP*farP)/(nearP-farP); }
static inline void mat4_orthographic(float w, float h, float nearP, float farP, Mat4* o) { memset(o,0,sizeof(Mat4)); o->m[0][0]=2.0f/w; o->m[1][1]=2.0f/h; o->m[2][2]=1.0f/(nearP-farP); o->m[3][2]=nearP/(nearP-farP); o->m[3][3]=1.0f; }
static inline void mat4_lookat(const Vec3* eye, const Vec3* target, const Vec3* up, Mat4* o) { Vec3 f,r,u; vec3_sub(target,eye,&f); vec3_normalize(&f,&f); vec3_cross(up,&f,&r); vec3_normalize(&r,&r); vec3_cross(&f,&r,&u); mat4_identity(o); o->m[0][0]=r.x; o->m[0][1]=u.x; o->m[0][2]=-f.x; o->m[1][0]=r.y; o->m[1][1]=u.y; o->m[1][2]=-f.y; o->m[2][0]=r.z; o->m[2][1]=u.z; o->m[2][2]=-f.z; o->m[3][0]=-vec3_dot(&r,eye); o->m[3][1]=-vec3_dot(&u,eye); o->m[3][2]=vec3_dot(&f,eye); }
static inline void mat4_transpose(const Mat4* in, Mat4* out) { for (int i=0;i<4;i++) for (int j=0;j<4;j++) out->m[i][j]=in->m[j][i]; }
static inline void quat_conjugate_raw(const Quat* q, Quat* o) { o->x=-q->x; o->y=-q->y; o->z=-q->z; o->w=q->w; }
static inline void quat_multiply(const Quat* a, const Quat* b, Quat* o) { o->x=a->w*b->x+a->x*b->w+a->y*b->z-a->z*b->y; o->y=a->w*b->y-a->x*b->z+a->y*b->w+a->z*b->x; o->z=a->w*b->z+a->x*b->y-a->y*b->x+a->z*b->w; o->w=a->w*b->w-a->x*b->x-a->y*b->y-a->z*b->z; }
static inline void quat_normalize(const Quat* q, Quat* o) { float l=sqrtf(q->x*q->x+q->y*q->y+q->z*q->z+q->w*q->w); if(l<1e-6f){*o=*q;return;} float i=1.0f/l; o->x=q->x*i; o->y=q->y*i; o->z=q->z*i; o->w=q->w*i; }
static inline void quat_rotate_vec3(const Quat* q, const Vec3* v, Vec3* o) { Quat vq={v->x,v->y,v->z,0}; Quat qinv; quat_conjugate_raw(q,&qinv); Quat tmp; quat_multiply(q,&vq,&tmp); Quat result; quat_multiply(&tmp,&qinv,&result); o->x=result.x; o->y=result.y; o->z=result.z; }
static inline void quat_to_matrix(const Quat* q, Mat4* o) { float xx=q->x*q->x,yy=q->y*q->y,zz=q->z*q->z,xy=q->x*q->y,xz=q->x*q->z,yz=q->y*q->z,wx=q->w*q->x,wy=q->w*q->y,wz=q->w*q->z; mat4_identity(o); o->m[0][0]=1-2*(yy+zz); o->m[0][1]=2*(xy+wz); o->m[0][2]=2*(xz-wy); o->m[1][0]=2*(xy-wz); o->m[1][1]=1-2*(xx+zz); o->m[1][2]=2*(yz+wx); o->m[2][0]=2*(xz+wy); o->m[2][1]=2*(yz-wx); o->m[2][2]=1-2*(xx+yy); }
static inline void* mem_aligned_alloc(uint64_t size, uint64_t alignment) { void* p; p = _aligned_malloc(size, alignment); return p; }
static inline void mem_aligned_free(void* ptr) { _aligned_free(ptr); }
static inline void fast_memcpy(void* dst, const void* src, uint64_t count) { memcpy(dst, src, (size_t)count); }
static inline void fast_memset(void* dst, int v, uint64_t count) { memset(dst, v, (size_t)count); }
static inline uint64_t fast_strlen(const char* s) { return strlen(s); }
static inline uint64_t prof_rdtsc(void) { LARGE_INTEGER f,t; QueryPerformanceFrequency(&f); QueryPerformanceCounter(&t); return (uint64_t)(t.QuadPart * 1000000000ULL / f.QuadPart); }
static inline double prof_cycles_to_ms(uint64_t c) { return (double)c / 1000000.0; }
static inline uint64_t prof_get_freq(void) { LARGE_INTEGER f; QueryPerformanceFrequency(&f); return (uint64_t)f.QuadPart; }
typedef struct { uint64_t start; uint64_t end; double elapsed_ms; } ProfTimer;
static inline void prof_timer_start(ProfTimer* t) { t->start = prof_rdtsc(); }
static inline void prof_timer_stop(ProfTimer* t) { t->end = prof_rdtsc(); t->elapsed_ms = prof_cycles_to_ms(t->end - t->start); }
#endif
+177
View File
@@ -0,0 +1,177 @@
; ============================================================================
; memory.asm - 对齐内存分配器 (x86-64 MASM)
; 支持 16/32/64 字节对齐 (SIMD 需要)
; ============================================================================
include asm_macros.inc
.DATA
ALIGN 16
_alloc_header_size EQU 32 ; 分配头大小 (包含对齐偏移和原始指针)
.CODE
; ============================================================================
; 对齐内存分配
; ============================================================================
; void* mem_aligned_alloc(uint64_t size, uint64_t alignment)
; RCX = size, RDX = alignment
; 返回: RAX = 对齐指针
mem_aligned_alloc PROC
push rbx
push rdi
push rsi
sub rsp, 40 ; 保留栈空间
mov rbx, rcx ; rbx = size
mov rdi, rdx ; rdi = alignment
; 验证 alignment 是 2 的幂
mov rax, rdi
dec rax
test rdi, rax
jnz alloc_invalid_alignment
; 确保 alignment >= 16
cmp rdi, 16
jae alloc_alignment_ok
mov rdi, 16
alloc_alignment_ok:
; 需要的总大小 = size + alignment + header
mov rax, rbx
add rax, rdi ; + alignment
add rax, _alloc_header_size ; + header
mov rsi, rax ; rsi = total size
; 调用 malloc
mov rcx, rsi
call malloc
test rax, rax
jz alloc_failed
; rax = 原始指针
; 计算对齐后的地址
mov rcx, rax
add rcx, _alloc_header_size ; 跳过 header
; 对齐
mov rdx, rdi
dec rdx
not rdx
add rcx, rdx ; 加上 alignment-1
and rcx, rdx ; 对齐到 alignment
; rcx = 对齐后的指针
; 在对齐指针前存储原始指针
mov [rcx - 8], rax ; 存储原始 malloc 指针
mov [rcx - 16], rbx ; 存储请求的 size
mov [rcx - 24], rdi ; 存储 alignment
mov [rcx - 32], rsi ; 存储 total size
mov rax, rcx ; 返回对齐指针
jmp alloc_done
alloc_invalid_alignment:
xor rax, rax ; 返回 NULL
jmp alloc_done
alloc_failed:
xor rax, rax
alloc_done:
add rsp, 40
pop rsi
pop rdi
pop rbx
ret
mem_aligned_alloc ENDP
; void mem_aligned_free(void* ptr)
; RCX = ptr (对齐指针)
mem_aligned_free PROC
test rcx, rcx
jz free_done
; 获取原始 malloc 指针
mov rax, [rcx - 8]
test rax, rax
jz free_done
; 调用 free
mov rcx, rax
call free
free_done:
ret
mem_aligned_free ENDP
; void* mem_aligned_realloc(void* ptr, uint64_t size, uint64_t alignment)
; RCX = ptr, RDX = size, R8 = alignment
; 返回: RAX = 新对齐指针
mem_aligned_realloc PROC
push rbx
push rdi
push rsi
push r12
sub rsp, 40
mov rbx, rdx ; rbx = new size
mov rdi, r8 ; rdi = alignment
; 如果 ptr 为 NULL, 直接分配
test rcx, rcx
jz realloc_alloc
; 保存旧信息
mov rsi, [rcx - 8] ; 原始指针
mov r12, [rcx - 16] ; 旧 size
; 分配新内存
mov rcx, rbx
mov rdx, rdi
call mem_aligned_alloc
test rax, rax
jz realloc_failed
; 复制旧数据 (取较小值)
mov rdx, r12
cmp rdx, rbx
jbe realloc_copy_ok
mov rdx, rbx
realloc_copy_ok:
mov rdi, rax ; 保存新指针
mov rcx, rax ; dst
; rsi = 旧数据起始
mov rsi, [rcx - 8] ; 旧原始指针
; 需要获取旧的对齐偏移
; 简化: 直接复制
call fast_memcpy
; 释放旧内存
mov rcx, rsi
call mem_aligned_free
mov rax, rdi ; 返回新指针
jmp realloc_done
realloc_alloc:
mov rcx, rbx
mov rdx, rdi
call mem_aligned_alloc
jmp realloc_done
realloc_failed:
xor rax, rax
realloc_done:
add rsp, 40
pop r12
pop rsi
pop rdi
pop rbx
ret
mem_aligned_realloc ENDP
END
+172
View File
@@ -0,0 +1,172 @@
; ============================================================================
; profiling.asm - 性能分析工具 (x86-64 MASM)
; 使用 RDTSC/RDTSCP 进行高精度计时
; ============================================================================
include asm_macros.inc
.DATA
ALIGN 8
cpu_freq DQ 0 ; CPU 频率 (Hz)
cpu_freq_init DB 0 ; 是否已初始化
.CODE
; ============================================================================
; RDTSC 计时
; ============================================================================
; uint64_t prof_rdtsc(void) -> RAX
; 返回: TSC (Time Stamp Counter) 值
prof_rdtsc PROC
; 使用 RDTSCP 获取有序的 TSC
rdtscp
; EDX:EAX = TSC
shl rdx, 32
or rax, rdx
ret
prof_rdtsc ENDP
; uint64_t prof_get_freq(void) -> RAX
; 获取 CPU 频率 (通过 OS 或推断)
prof_get_freq PROC
; 检查是否已初始化
cmp byte ptr [cpu_freq_init], 0
jnz prof_freq_return
; 初始化 CPU 频率
; 方法: 使用 QueryPerformanceCounter 测量 RDTSC
push rbx
push rdi
push rsi
sub rsp, 40
; 获取 QPC 频率
lea rcx, [rsp + 32]
call QueryPerformanceFrequency
; 获取起始 QPC 和 TSC
lea rcx, [rsp + 16]
call QueryPerformanceCounter
rdtscp
shl rdx, 32
or rax, rdx
mov rbx, rax ; rbx = 起始 TSC
; 等待约 10ms
mov rcx, 10000 ; 10,000 微秒
call Sleep
; 获取结束 QPC 和 TSC
lea rcx, [rsp]
call QueryPerformanceCounter
rdtscp
shl rdx, 32
or rax, rdx
mov rdi, rax ; rdi = 结束 TSC
; 计算经过的 QPC ticks
mov rax, [rsp]
sub rax, [rsp + 16] ; qpc_diff
; 计算 QPC 频率 (ticks/sec)
mov rsi, [rsp + 32]
; TSC diff
mov rax, rdi
sub rax, rbx ; tsc_diff
; CPU freq = tsc_diff * qpc_freq / qpc_diff
; 但 qpc_diff 对应 10ms, 所以要 * 100
mov rdx, rsi
mul rdx ; tsc_diff * qpc_freq
; rdx:rax = result
div qword ptr [rsp + 16] ; / qpc_diff
; rax = freq * 100 (因为等待了 10ms)
mov rcx, 100
mul rcx
mov [cpu_freq], rax
mov byte ptr [cpu_freq_init], 1
add rsp, 40
pop rsi
pop rdi
pop rbx
prof_freq_return:
mov rax, [cpu_freq]
ret
prof_get_freq ENDP
; double prof_cycles_to_ms(uint64_t cycles) -> XMM0
; 将 TSC cycles 转换为毫秒
prof_cycles_to_ms PROC
; 先获取频率
call prof_get_freq
; rax = CPU freq (Hz)
; ms = cycles / (freq / 1000)
; 或: ms = cycles * 1000 / freq
mov rdx, 1000
mul rdx ; freq * 1000
; rdx:rax = freq * 1000
; 转换为 double
cvtsi2sd xmm0, qword ptr [rsp - 8] ; 需要栈存储
; 简化: 使用整数除法再转 double
mov rcx, rax
mov rax, [cpu_freq]
; 重新计算
mov rax, rcx
; cycles * 1000 / freq
; 已经: rax = freq * 1000, 需要 cycles * 1000 / freq
; 调整: cycles * 1000 / freq = cycles / (freq/1000)
; 简化实现
cvtsi2sd xmm0, rcx ; cycles * 1000 (转 double)
cvtsi2sd xmm1, rax ; freq (转 double)
divsd xmm0, xmm1 ; (cycles*1000) / freq = ms
ret
prof_cycles_to_ms ENDP
; ============================================================================
; 内联性能宏 (在 C 代码中使用)
; ============================================================================
; 获取当前时间戳 (直接 RDTSC, 无函数调用开销)
; 在 C 中使用: __rdtsc() 内联函数
; 高精度计时器结构
; struct ProfTimer {
; uint64_t start;
; uint64_t end;
; double elapsed_ms;
; };
; void prof_timer_start(ProfTimer* timer)
prof_timer_start PROC
rdtscp
shl rdx, 32
or rax, rdx
mov [rcx], rax ; timer->start = tsc
ret
prof_timer_start ENDP
; void prof_timer_stop(ProfTimer* timer)
prof_timer_stop PROC
rdtscp
shl rdx, 32
or rax, rdx
mov [rcx + 8], rax ; timer->end = tsc
; 计算 elapsed_ms
mov rax, [rcx + 8]
sub rax, [rcx] ; cycles
; 转换为 ms
call prof_cycles_to_ms
movsd qword ptr [rcx + 16], xmm0 ; timer->elapsed_ms
ret
prof_timer_stop ENDP
END
+325
View File
@@ -0,0 +1,325 @@
; ============================================================================
; 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=a<b, >0=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