|
在自己制作程序时遇到了问题,在大量文本(行>10000行,文本字符定义在整数范围)分配到数组时,使用循环方式太慢,使用别人例程时不能达到要求,所以请求大家帮助修改下源码。本人对ASM不熟悉,老虎吃天没法下爪!
谢谢各位了!!!不知为什么我发不了源码。
我想要的结果:
在对文本快速分割时,数组保留分割符
1,2,3,4,5 -->
数组[1]: 1,
数组[2]: 2,
数组[3]: 3,
数组[3]: 4,
数组[3]: 5,
同时求一个上述数组快速合并为文本例程!
分割文本ASM如下:
===========================================================
.版本 2
.子程序 _分割文本, 整数型, , 将指定文本进行分割,返回分割后的一维文本数组成员数。本命令为初级命令。
.参数 待分割文本, 文本型, , 如果参数值是一个长度为零的文本,则返回一个空数组,即没有任何成员的数组。
.参数 用作分割的文本, 文本型, , 可以被省略。参数值用于标识子文本边界。如果是一个长度为零的文本,则返回的数组仅包含一个成员,即完整的“待分割文本”。
.参数 返回的文本数组, 文本型, 参考 数组, 说明:这个和易语言有点区别的是如果第二参数是在文本最后..那成员会比易语言的多出1个
.局部变量 局部_栈句柄, 整数型, , , [ebp-4] GetProcessHeap();返回值
.局部变量 局部_RtlAllocateHeap_地址, 整数型, , , [ebp-8] RtlAllocateHeap;函数地址
.局部变量 局部_HeapFree_地址, 整数型, , , [ebp-0c] HeapFree;函数地址
.局部变量 局部_参数一文本长度, 整数型, , , [ebp-10] lstrlenA;待分割文本长度
.局部变量 局部_参数二文本长度, 整数型, , , [ebp-14] lstrlenA;用作分割的文本长度
.局部变量 局部_临时数组, 整数型, , , [ebp-18] 临时数组地址,地址+0为成员数,地址+4为第一成员,+8为第二成员,+0c为第三个成员.如此类推
' 针对第三个参数的说明作出以下的举例:
' 比如:_分割文本 (“1,2,”, “,”, 局部_文本数组) 分割后会有3个成员,最后一个成员为空文本
' 比如:_分割文本 (“1,2”, “,”, 局部_文本数组) 分割后会有2个成员
置入代码 ({ 81 }) ' push ecx
置入代码 ({ 82 }) ' push edx
置入代码 ({ 83 }) ' push ebx
置入代码 ({ 86 }) ' push esi
置入代码 ({ 87 }) ' push edi
' 保存寄存器
' -----------------------------------------------------------------------------
局部_栈句柄 = GetProcessHeap ()
局部_RtlAllocateHeap_地址 = _取函数入口 (“ntdll.dll”, “RtlAllocateHeap”)
局部_HeapFree_地址 = _取函数入口 (“kernel32.dll”, “HeapFree”)
局部_参数一文本长度 = lstrlenA (待分割文本)
局部_参数二文本长度 = lstrlenA (用作分割的文本)
' -------------------------------------------------------------------------------
置入代码 ({ 139, 133, 240, 255, 255, 255 }) ' mov eax,[ebp-10]
置入代码 ({ 129, 192, 0, 1, 0, 0 }) ' add eax,100
置入代码 ({ 80 }) ' push eax
置入代码 ({ 104, 0, 0, 0, 0 }) ' push 0
置入代码 ({ 255, 181, 252, 255, 255, 255 }) ' push [ebp-4]
置入代码 ({ 255, 149, 248, 255, 255, 255 }) ' call [ebp-8]
' call RtlAllocateHeap,局部_栈句柄,0,局部_参数一文本长度+100
' 开辟一个临时数组空间,保存分割后的文本成员地址.
' -----------------------------------------------------------------------------
置入代码 ({ 137, 133, 232, 255, 255, 255 }) ' mov [ebp-18],eax
' 局部_临时数组=eax
' -----------------------------------------------------------------------------
置入代码 ({ 199, 0, 0, 0, 0, 0 }) ' mov dword ptr [eax],0
' 初始化数组空间
' -----------------------------------------------------------------------------
置入代码 ({ 139, 141, 236, 255, 255, 255 }) ' mov ecx,[ebp-14]
' ecx=局部_参数二文本长度
' -----------------------------------------------------------------------------
置入代码 ({ 51, 192 }) ' xor eax,eax
置入代码 ({ 139, 181, 8, 0, 0, 0 }) ' mov esi,[ebp+8]
置入代码 ({ 139, 54 }) ' mov esi,dword ptr [esi]
' 待分割文本地址
' -----------------------------------------------------------------------------
置入代码 ({ 139, 189, 12, 0, 0, 0 }) ' mov edi,[ebp+0c]
置入代码 ({ 139, 63 }) ' mov edi,dword ptr [edi]
' 用作分割的文本地址
' -----------------------------------------------------------------------------
置入代码 ({ 139, 222 }) ' mov ebx,esi
' 保存临时地址,用作下一次的地址和上一次的地址相比
' -----------------------------------------------------------------------------
' 标号A:
置入代码 ({ 86 }) ' push esi
置入代码 ({ 87 }) ' push edi
置入代码 ({ 81 }) ' push ecx
置入代码 ({ 243, 38, 166 }) ' repe cmps byte ptr es:[edi],byte ptr es:[esi]
' 根据参数一的偏移地址的内容和参数二的内容对比
' -----------------------------------------------------------------------------
置入代码 ({ 116, 12 }) ' je 标号A:
' 找到就跳
' -----------------------------------------------------------------------------
置入代码 ({ 89 }) ' pop ecx
置入代码 ({ 95 }) ' pop edi
置入代码 ({ 94 }) ' pop esi
' 恢复比较前的寄存器
' -----------------------------------------------------------------------------
置入代码 ({ 128, 62, 0 }) ' cmp byte ptr [esi],0x0
置入代码 ({ 116, 41 }) ' je 标号B:
' 判断是否为0.如果为0就跳
' -----------------------------------------------------------------------------
置入代码 ({ 70 }) ' inc esi
置入代码 ({ 64 }) ' inc eax
置入代码 ({ 235, 236 }) ' jmp 标号:A
' -----------------------------------------------------------------------------
' 标号B:
置入代码 ({ 139, 206 }) ' mov ecx,esi
置入代码 ({ 43, 203 }) ' sub ecx,ebx
置入代码 ({ 43, 77, 236 }) ' 2B4D EC sub ecx,dword ptr [ebp-0x14]
' 计算出左边的文本长度
' -----------------------------------------------------------------------------
置入代码 ({ 232, 133, 0, 0, 0 }) ' E8 8B000000 call 004012C7
' call 复制字符串
' -----------------------------------------------------------------------------
' 备注:临时数组结构
' 临时数组地址+0 存放着临时成员数
' 临时数组地址+4 存放第一个成员的地址
' 临时数组地址+8 存放第二个成员的地址
' 如此类推
置入代码 ({ 139, 141, 232, 255, 255, 255 }) ' mov ecx,[ebp-18] 取出临时数组的地址
置入代码 ({ 255, 1 }) ' inc dword ptr [ecx] ' 成员加1
置入代码 ({ 139, 17 }) ' mov edx,dword ptr [ecx]
置入代码 ({ 193, 226, 2 }) ' shl edx,0x2
置入代码 ({ 137, 4, 10 }) ' mov dword ptr [edx+ecx],eax
置入代码 ({ 139, 222 }) ' mov ebx,esi
置入代码 ({ 67 }) ' inc ebx
置入代码 ({ 137, 116, 36, 8 }) ' mov dword ptr [esp+8],esi
置入代码 ({ 235, 207 }) ' jmp X00401224
' 跳上去继续分割
' -----------------------------------------------------------------------------
置入代码 ({ 139, 206 }) ' mov ecx,esi
置入代码 ({ 43, 203 }) ' sub ecx,ebx
' 计算出左边的文本长度
' -----------------------------------------------------------------------------
置入代码 ({ 232, 99, 0, 0, 0 }) ' E8 69000000 call 004012C7
' call 复制字符串
' -----------------------------------------------------------------------------
置入代码 ({ 139, 141, 232, 255, 255, 255 }) ' mov ecx,[ebp-18] 取出临时数组的地址
置入代码 ({ 255, 1 }) ' inc dword ptr [ecx]
置入代码 ({ 139, 17 }) ' mov edx,dword ptr [ecx]
置入代码 ({ 193, 226, 2 }) ' shl edx,0x2
置入代码 ({ 137, 4, 10 }) ' mov dword ptr [edx+ecx],eax
置入代码 ({ 139, 149, 232, 255, 255, 255 }) ' mov edx,[ebp-18]
置入代码 ({ 139, 242 }) ' mov esi,edx
置入代码 ({ 139, 14 }) ' mov ecx,dword ptr [esi]
置入代码 ({ 193, 225, 2 }) ' shl ecx,0x2
置入代码 ({ 131, 193, 8 }) ' add ecx,8
' 计算返回的数组空间大小
' -----------------------------------------------------------------------------
置入代码 ({ 81 }) ' push ecx ; HeapSize
置入代码 ({ 106, 0 }) ' push 0x0 ; Flags = 0
置入代码 ({ 255, 181, 252, 255, 255, 255 }) ' push [ebp-4] hHeap
置入代码 ({ 255, 149, 248, 255, 255, 255 }) ' call [ebp-8] RtlAllocateHeap
' 申请一块返回数组的空间
' -----------------------------------------------------------------------------
置入代码 ({ 139, 77, 16 }) ' mov ecx,dword ptr [ebp+0x10] 参数三的栈地址
置入代码 ({ 137, 1 }) ' mov dword ptr [ecx],eax
置入代码 ({ 199, 0, 1, 0, 0, 0 }) ' mov dword ptr [eax],1 数组地址+0 的值为1
置入代码 ({ 139, 14 }) ' mov ecx,dword ptr [esi]
置入代码 ({ 137, 72, 4 }) ' mov dword ptr [eax+4],ecx 数组地址+4 的值为成员数量
' 初始化数组
' -----------------------------------------------------------------------------
置入代码 ({ 81 }) ' push ecx 保存返回成员数 .在后面会用pop eax来恢复
置入代码 ({ 139, 248 }) ' mov edi,eax
置入代码 ({ 131, 198, 4 }) ' add esi,0x4 计算出临时数组第一个成员的地址
置入代码 ({ 131, 199, 8 }) ' add edi,0x8 计算出返回数组的第一个成员的地址
置入代码 ({ 243, 165 }) ' rep movs dword ptr es:[edi],dword ptr [esi] 从临时数组拷贝到返回数组
' 复制临时数组地址到返回数组里面去
' -----------------------------------------------------------------------------
置入代码 ({ 82 }) ' push edx ; pMemory
置入代码 ({ 106, 0 }) ' push 0 ; Flags = 0
置入代码 ({ 255, 181, 252, 255, 255, 255 }) ' push [ebp-4] 栈句柄 ; hHeap
置入代码 ({ 255, 149, 244, 255, 255, 255 }) ' call [ebp-0c] ; HeapFree
' 释放临时数组空间
' -----------------------------------------------------------------------------
置入代码 ({ 88 }) ' pop eax
置入代码 ({ 95 }) ' pop edi
置入代码 ({ 94 }) ' pop esi
置入代码 ({ 91 }) ' pop ebx
置入代码 ({ 90 }) ' pop edx
置入代码 ({ 89 }) ' pop ecx
置入代码 ({ 201 }) ' leave
置入代码 ({ 194, 12, 0 }) ' retn 0xC
' ------------------------------------------复制字符串-------------------------------------------------------------------------
置入代码 ({ 81 }) ' push ecx
置入代码 ({ 83 }) ' push ebx
置入代码 ({ 81 }) ' push ecx
置入代码 ({ 104, 0, 0, 0, 0 }) ' push 0
置入代码 ({ 255, 181, 252, 255, 255, 255 }) ' push [ebp-4]
置入代码 ({ 255, 149, 248, 255, 255, 255 }) ' call [ebp-8] call HeapAlloc
置入代码 ({ 139, 248 }) ' mov edi,eax
置入代码 ({ 94 }) ' pop esi
置入代码 ({ 89 }) ' pop ecx
置入代码 ({ 139, 209 }) ' mov edx,ecx
置入代码 ({ 193, 233, 2 }) ' shr ecx,2
置入代码 ({ 243, 165 }) ' rep movs dword ptr es:[edi],dword ptr [esi]
置入代码 ({ 139, 202 }) ' mov ecx,edx
置入代码 ({ 129, 225, 3, 0, 0, 0 }) ' and ecx,03
置入代码 ({ 243, 164 }) ' rep movs byte ptr es:[edi],byte ptr [esi]
置入代码 ({ 198, 7, 0 }) ' mov byte ptr [edi],0
置入代码 ({ 195 }) ' ret
返回 (0)
我的合并数组到文本(内存叠加)
===========================================================
.版本 2
.支持库 spec
.子程序 合并文本数组到文本, 文本型, , 连接数组合并一个文本数组到字符串。
.参数 文本数组, 文本型, 数组
.参数 合并字符, 文本型, 可空, 可空,默认为,
.局部变量 返回文本, 文本型
.局部变量 当前文本, 文本型
.局部变量 叠加文本, 整数型
.局部变量 叠加地址, 整数型
.局部变量 偏移地址, 整数型
.局部变量 循环值, 整数型
.局部变量 文本长度, 整数型
.局部变量 缓冲长度, 整数型
.局部变量 数组大小, 整数型
' 判断合并间隔字符
合并字符 = 选择 (是否为空 (合并字符), “,”, 合并字符)
' 获取需要的文本长度
.计次循环首 (取数组成员数 (文本数组), 循环值)
缓冲长度 = 缓冲长度 + 取文本长度 (文本数组 [循环值] + 合并字符)
.计次循环尾 ()
' 获得数组的数据量
数组大小 = 取数组成员数 (文本数组)
' 执行叠加
叠加地址 = 申请内存 (缓冲长度 × 4, 真)
.计次循环首 (数组大小, 循环值)
.如果真 (循环值 = 数组大小)
合并字符 = “”
.如果真结束
当前文本 = 文本数组 [循环值] + 合并字符
文本长度 = 取文本长度 (当前文本)
叠加文本 = lstrcpyn_文本 (当前文本, 当前文本, 0)
CopyMemory (叠加地址 + 偏移地址, 叠加文本, 文本长度)
偏移地址 = 偏移地址 + 文本长度
.计次循环尾 ()
返回文本 = 指针到文本 (叠加地址)
释放内存 (叠加地址)
返回 (返回文本)
我的合并数组到文本2:
===========================================================
.版本 2
.支持库 spec
.子程序 快速合并文本数组, 文本型, , 连接数组合并一个文本数组到字符串。
.参数 文本数组, 文本型, 数组
.参数 合并字符, 文本型, 可空, 可空,默认为,
.局部变量 缓冲文本, 文本型
.局部变量 缓冲长度, 长整数型
.局部变量 缓冲指针, 整数型
.局部变量 循环值, 整数型
.局部变量 文本长度, 整数型
.局部变量 偏移地址, 整数型
合并字符 = 选择 (是否为空 (合并字符), “,”, 合并字符)
.计次循环首 (取数组成员数 (文本数组), 循环值)
缓冲长度 = 缓冲长度 + 取文本长度 (文本数组 [循环值]) + 取文本长度 (合并字符)
.计次循环尾 ()
缓冲文本 = 取空白文本 (缓冲长度)
缓冲指针 = 取变量数据地址 (缓冲文本)
偏移地址 = 0
.计次循环首 (取数组成员数 (文本数组), 循环值)
.如果真 (循环值 = 取数组成员数 (文本数组))
合并字符 = “”
.如果真结束
文本长度 = 取文本长度 (文本数组 [循环值] + 合并字符)
写到内存 (文本数组 [循环值] + 合并字符, 缓冲指针 + 偏移地址, 文本长度)
偏移地址 = 偏移地址 + 文本长度
.计次循环尾 ()
返回 (删首尾空 (缓冲文本))
|
-
|