鱼C论坛

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

用汇编写个子程序

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

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

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

x
谁能用汇编写一个寻找文本或者寻找字节集的子程序,学习一下
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2016-10-19 18:39:20 | 显示全部楼层
寻找文本?
在哪找?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

传参数啊,原文本,跟要寻找的文本两个必须参数,返回寻找到的位置未找到返回0或者-1
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-20 17:11:49 | 显示全部楼层
必须是汇编吗?C不行吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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


  2. char *find_str(const char *str, const char *src)
  3. {
  4. #if(0)
  5.         int c = 0;
  6.         char *src_bak = src;

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

  8.         while(1)
  9.         {
  10.                 if(*src == '\0')
  11.                 {
  12.                         return str - c;
  13.                 }
  14.                 if(*str == '\0')
  15.                 {
  16.                         return NULL;
  17.                 }

  18.                 if(c != 0)
  19.                 {
  20.                         if(*str != *src)
  21.                         {
  22.                                 c = 0;
  23.                                 src = src_bak;
  24.                         }
  25.                 }

  26.                 if(*str == *src)
  27.                 {
  28.                         c++;
  29.                         src++;
  30.                 }
  31.                 str++;
  32.         }

  33. #endif

  34.         _asm
  35.         {
  36.                 push esi
  37.                 push edi
  38.                 push ebx
  39.                 push ecx
  40.                 push edx

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

  43.                 mov ah, 0
  44.                 xor ecx, ecx
  45.                 mov edx, edi

  46.                 cmp [esi], ah
  47.                 jne n0
  48.                 jmp r
  49. n0:               
  50.                 cmp [edi], ah
  51.                 jne n

  52. r:
  53.                 xor eax, eax
  54.                 jmp return

  55. n :
  56.                 mov ah, '\0'


  57. w :
  58.                 cmp[edi], ah
  59.                 jne x1

  60.                 mov eax, esi
  61.                 sub eax, ecx
  62.                 jmp return
  63. x1:


  64.                 cmp[esi], ah
  65.                 jne x4
  66.                 xor eax, eax
  67.                 jmp return

  68. x4:               
  69.                 cmp ecx, 0
  70.                 je x2

  71.                 mov bl, [esi]
  72.                 cmp bl, [edi]
  73.                 je x2

  74.                 xor ecx, ecx
  75.                 mov edi, edx
  76. x2:

  77.                 mov bl, [esi]
  78.                 cmp bl, [edi]
  79.                 jne x3

  80.                 inc ecx
  81.                 inc edi
  82. x3:
  83.                 inc esi
  84.                 jmp w

  85. return :

  86.                 pop edx
  87.                 pop ecx
  88.                 pop ebx
  89.                 pop edi
  90.                 pop esi
  91.                 ; ret
  92.         }
  93. }

  94. int main()
  95. {
  96.         char str[] = "12345645455";

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

  99.        

  100.         return 0;
  101. }
复制代码

小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

看起来好复杂,这么长我都不知道要怎么调用了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

那我也没有办法,汇编语言就是这样
不能用C吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

看看这个
http://blog.chinaunix.net/uid-26548237-id-3367953.html
小甲鱼最新课程 -> https://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
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

使用道具 举报

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-6 04:24

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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