nikezhi 发表于 2016-10-19 14:27:02

用汇编写个子程序

谁能用汇编写一个寻找文本或者寻找字节集的子程序,学习一下

人造人 发表于 2016-10-19 18:39:20

寻找文本?
在哪找?

nikezhi 发表于 2016-10-20 00:11:31

人造人 发表于 2016-10-19 18:39
寻找文本?
在哪找?

传参数啊,原文本,跟要寻找的文本两个必须参数,返回寻找到的位置未找到返回0或者-1

人造人 发表于 2016-10-20 17:11:49

必须是汇编吗?C不行吗?

人造人 发表于 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, ; str
                mov edi, ; src

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

                cmp , ah
                jne n0
                jmp r
n0:               
                cmp , ah
                jne n

r:
                xor eax, eax
                jmp return

n :
                mov ah, '\0'


w :
                cmp, ah
                jne x1

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


                cmp, ah
                jne x4
                xor eax, eax
                jmp return

x4:               
                cmp ecx, 0
                je x2

                mov bl,
                cmp bl,
                je x2

                xor ecx, ecx
                mov edi, edx
x2:

                mov bl,
                cmp bl,
                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;
}

nikezhi 发表于 2016-10-21 01:33:00

人造人 发表于 2016-10-20 17:54
不知道行不行

看起来好复杂,这么长我都不知道要怎么调用了{:5_99:}

人造人 发表于 2016-10-21 12:22:47

nikezhi 发表于 2016-10-21 01:33
看起来好复杂,这么长我都不知道要怎么调用了

那我也没有办法,汇编语言就是这样
不能用C吗?

nikezhi 发表于 2016-10-21 15:50:51

汇编的效率高啊,我是拿来调用的,我没学过c。在一亿的文本长度里面寻找指定的文本,速度在秒已下。如何能够实现,单线程

人造人 发表于 2016-10-21 16:44:33

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

看看这个
http://blog.chinaunix.net/uid-26548237-id-3367953.html

xieglt 发表于 2016-12-1 01:37:06

本帖最后由 xieglt 于 2016-12-1 07:27 编辑

;_StringLenPROC __stdcall,string
;求字符串长度,要求字符串以0结束如:msgdb "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
      
      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

;_StringFindPROC__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
                CALL      _StringLen
                MOV       DWORD PTR ,EAX

                PUSH      DWORD PTR
                CALL      _StringLen

                CMP       EAX,DWORD PTR
                JL      _IsNotFound

                MOV       ECX,EAX
                SUB       ECX,DWORD PTR
                MOV       ESI,DWORD PTR
                MOV       EDI,DWORD PTR
_SearchForString:
                PUSH   ESI
                PUSH   EDI
                MOV       EAX,DWORD PTR
                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
_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

xieglt 发表于 2016-12-1 02:04:01

如果你那个父字符串很长,而且已知长度,就没必要再去求长度了。直接给值就好,1亿的字符,最少100M,扫描一次浪费时间

xieglt 发表于 2016-12-1 02:08:39

如果字符串长是2的倍数或4的倍数,那就可以将串指令换成SW或SD,速度更快
页: [1]
查看完整版本: 用汇编写个子程序