开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 1251|回复: 5
收起左侧

[求助] 求助帖:快速文本到数组问题

[复制链接]
发表于 2020-1-6 11:10:54 | 显示全部楼层 |阅读模式   陕西省宝鸡市
在自己制作程序时遇到了问题,在大量文本(行>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
.计次循环首 (取数组成员数 (文本数组), 循环值)
    .如果真 (循环值 = 取数组成员数 (文本数组))
        合并字符 = “”
    .如果真结束
    文本长度 = 取文本长度 (文本数组 [循环值] + 合并字符)
    写到内存 (文本数组 [循环值] + 合并字符, 缓冲指针 + 偏移地址, 文本长度)
    偏移地址 = 偏移地址 + 文本长度
.计次循环尾 ()
返回 (删首尾空 (缓冲文本))


xxx.jpg
 楼主| 发表于 2022-1-26 11:00:16 | 显示全部楼层   陕西省宝鸡市
已经解决,谢谢大家。
回复 支持 反对

使用道具 举报

发表于 2020-1-6 18:26:54 | 显示全部楼层   云南省昆明市
     辛苦了
回复 支持 反对

使用道具 举报

签到天数: 7 天

发表于 2020-1-6 14:22:36 | 显示全部楼层   山西省晋中市
花点钱定制下。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-6 11:33:41 | 显示全部楼层   陕西省宝鸡市
cf2006a 发表于 2020-1-6 11:31
分割文本到数组,经常出错…!汇编速度快不过bug多

给个建议,庞大数量的文本,如果用循环卡顿太明显了。
回复 支持 反对

使用道具 举报

结帖率:97% (31/32)

签到天数: 21 天

发表于 2020-1-6 11:31:31 | 显示全部楼层   福建省福州市
分割文本到数组,经常出错…!汇编速度快不过bug多


评分

参与人数 1精币 +1 收起 理由
冬夏 + 1 很赞同,谢谢!

查看全部评分

回复 支持 反对

使用道具 举报

  高级模式
B Color Image Link Quote Code Smilies |上传

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表