鱼C论坛

 找回密码
 立即注册
查看: 2770|回复: 11

用汇编写个子程序

[复制链接]
发表于 2016-10-19 14:27:02 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
谁能用汇编写一个寻找文本或者寻找字节集的子程序,学习一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-10-19 18:39:20 | 显示全部楼层
寻找文本?
在哪找?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-20 00:11:31 | 显示全部楼层
人造人 发表于 2016-10-19 18:39
寻找文本?
在哪找?

传参数啊,原文本,跟要寻找的文本两个必须参数,返回寻找到的位置未找到返回0或者-1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-20 17:11:49 | 显示全部楼层
必须是汇编吗?C不行吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-20 17:54:49 | 显示全部楼层
不知道行不行
#include <stdio.h>


char *find_str(const char *str, const char *src)
{
#if(0)
        int c = 0;
        char *src_bak = src;

        if((str == NULL) || (src == NULL)) return NULL;

        while(1)
        {
                if(*src == '\0')
                {
                        return str - c;
                }
                if(*str == '\0')
                {
                        return NULL;
                }

                if(c != 0)
                {
                        if(*str != *src)
                        {
                                c = 0;
                                src = src_bak;
                        }
                }

                if(*str == *src)
                {
                        c++;
                        src++;
                }
                str++;
        }

#endif

        _asm
        {
                push esi
                push edi
                push ebx
                push ecx
                push edx

                mov esi, [ebp + 8] ; str
                mov edi, [ebp + 12] ; src

                mov ah, 0
                xor ecx, ecx
                mov edx, edi

                cmp [esi], ah
                jne n0
                jmp r
n0:                
                cmp [edi], ah
                jne n

r:
                xor eax, eax
                jmp return

n :
                mov ah, '\0'


w :
                cmp[edi], ah
                jne x1

                mov eax, esi
                sub eax, ecx
                jmp return
x1:


                cmp[esi], ah
                jne x4
                xor eax, eax
                jmp return

x4:                
                cmp ecx, 0
                je x2

                mov bl, [esi]
                cmp bl, [edi]
                je x2

                xor ecx, ecx
                mov edi, edx
x2:

                mov bl, [esi]
                cmp bl, [edi]
                jne x3

                inc ecx
                inc edi
x3:
                inc esi
                jmp w

return :

                pop edx
                pop ecx
                pop ebx
                pop edi
                pop esi
                ; ret
        }
}

int main()
{
        char str[] = "12345645455";

        char *s = find_str(str, "455");
        printf("%d", s - str);

        

        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-21 01:33:00 | 显示全部楼层

看起来好复杂,这么长我都不知道要怎么调用了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-21 12:22:47 | 显示全部楼层
nikezhi 发表于 2016-10-21 01:33
看起来好复杂,这么长我都不知道要怎么调用了

那我也没有办法,汇编语言就是这样
不能用C吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-10-21 15:50:51 | 显示全部楼层
汇编的效率高啊,我是拿来调用的,我没学过c。在一亿的文本长度里面寻找指定的文本,速度在秒已下。如何能够实现,单线程
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-21 16:44:33 | 显示全部楼层
nikezhi 发表于 2016-10-21 15:50
汇编的效率高啊,我是拿来调用的,我没学过c。在一亿的文本长度里面寻找指定的文本,速度在秒已下。如何能 ...

看看这个
http://blog.chinaunix.net/uid-26548237-id-3367953.html
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-1 01:37:06 | 显示全部楼层
本帖最后由 xieglt 于 2016-12-1 07:27 编辑

;_StringLen  PROC __stdcall,string
;求字符串长度,要求字符串以0结束如:  msg  db "Hello,world",0
;返回值在EAX中,长度不包括最后的0 ,如上面的 msg 长度为 11
;调用方法     PUSH   offset msg
;                   CALL    _StringLen
;返回值在EAX中
_StringLen        PROC
        PUSH        EBP
        MOV         EBP,ESP

        PUSH        ECX
        PUSH        EDI

        MOV         EDI,DWORD PTR [EBP + 8]
      
        XOR          EAX,EAX
        XOR          ECX,ECX
        DEC           ECX
        REPNE       SCASB
        NOT          ECX
        MOV         EAX,ECX
        DEC            EAX

        POP                EDI
        POP                ECX
        MOV                ESP,EBP
        POP                EBP
        RET                4
_StringLen     ENDP

;_StringFind  PROC  __stdcall , string1,string2
;在一个字符串(string1)中查找另一个字符串(string2)
;如果没有找到,则返回0,找到则返回子字符串在父字符串中的位置,从0开始计数
;比如:
;str1 DB "Hello,c plus plus!",0
;str2 DB "plus",0
;PUSH   OFFSET str2
;PUSH   OFFSET str1
;CALL   _StringFind
;则返回eax = 8
_StringFind       PROC
                PUSH      EBP
                MOV       EBP,ESP
                SUB       ESP,4
                PUSH      ECX
                PUSH      ESI
                PUSH      EDI

                PUSH      DWORD PTR [EBP + 12]
                CALL      _StringLen
                MOV       DWORD PTR [EBP - 4],EAX

                PUSH      DWORD PTR [EBP + 8]
                CALL      _StringLen

                CMP       EAX,DWORD PTR [EBP - 4]
                JL        _IsNotFound

                MOV       ECX,EAX
                SUB       ECX,DWORD PTR [EBP - 4]
                MOV       ESI,DWORD PTR [EBP + 8]
                MOV       EDI,DWORD PTR [EBP + 12]
_SearchForString:
                PUSH     ESI
                PUSH     EDI
                MOV       EAX,DWORD PTR [EBP - 4]
                XCHG     EAX,ECX
                REPE     CMPSB
                POP      EDI
                POP      ESI
                JCXZ     _FoundIt
                INC      ESI
                XCHG     EAX,ECX
                LOOP     _SearchForString
_IsNotFound:
                XOR      EAX,EAX
                JMP      _FindExit
_FoundIt:
                MOV      EAX,ESI
                SUB      EAX,DWORD PTR [EBP + 8]
_FindExit:
                POP       EDI
                POP       ESI
                POP       ECX
                MOV       ESP,EBP
                POP       EBP
                RET        8
_StringFind       ENDP


字符串处理一定要善用汇编的串处理指令,而不要一个字节一个字节的去比较
SCASB/W/D       串指针 EDI         
CMPSB/W/D      串指针 ESI,EDI
LODSB/W/D       串指针ESI
STOSB/W/D        串指针EDI
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-1 02:04:01 From FishC Mobile | 显示全部楼层
如果你那个父字符串很长,而且已知长度,就没必要再去求长度了。直接给值就好,1亿的字符,最少100M,扫描一次浪费时间
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-1 02:08:39 From FishC Mobile | 显示全部楼层
如果字符串长是2的倍数或4的倍数,那就可以将串指令换成SW或SD,速度更快
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-25 15:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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