专业游戏门户,分享手游网游单机游戏百科知识攻略!

嗨游网
嗨游网

strchr函数的介绍及用法

来源:小嗨整编  作者:小嗨  发布时间:2023-02-27 05:22
摘要:strchr函数的介绍及用法如果要写一个从字符串中查找一个字符的函数,相信你不难想到如下代码:char__cdeclstrchr_1( charconst_Str, int _Val) while(_Str&&_Str!=_...

由于这里是反汇编,是加载到内存中的,没有标号,跳转的时候指定的是跳转目标地址,这里将地址放到语句之后。

这里可以看到,反汇编代码和我们之前看到的明显不同,应该就是之前包含进来的代码了。那么,它都做了些什么呢?

在这里,我们从intel文档中查看几个命令:

pshuflw:

strchr函数的介绍及用法

movlhps:

strchr函数的介绍及用法

movdqu:

strchr函数的介绍及用法

pxor:

strchr函数的介绍及用法

pcmpeqb:

strchr函数的介绍及用法

pmovmskb:

strchr函数的介绍及用法

cmovne:

strchr函数的介绍及用法

bsf:

strchr函数的介绍及用法

第一行和第二行,是一个判断,我们看到,如果 ds:[7BEB92DCh] 处的值大于或等于1,则跳转到第 34 行(7BEA4348),为什么会有这个跳转呢?我们看看34行代码,并和之前看到的汇编代码作比较:

strchr函数的介绍及用法

我们发现,后面的代码和之前我们看到的汇编源代码一模一样。所以,这里我们可以认为是在判断是否支持SSE,至于为什么如此判断,暂时还没有调查清楚,如果有清楚的,麻烦在评论区回复下,不胜感激。

在了解到执行代码后面部分一致的情况下,我们此时就可以将重点放在前半部分了,为了方便,我们这里再次引用反汇编得到的代码前面部分,并忽略第一句,如下:

movzx       eax,byte ptr [esp+8]              ; 7BEA42E9  mov         edx,eax                           ; 7BEA42EE  shl         eax,8                             ; 7BEA42F0  or          edx,eax                           ; 7BEA42F3  movd        xmm3,edx                          ; 7BEA42F5  pshuflw     xmm3,xmm3,0                       ; 7BEA42F9  movlhps     xmm3,xmm3                         ; 7BEA42FE  mov         edx,dword ptr [esp+4]             ; 7BEA4301  mov         ecx,0Fh                           ; 7BEA4305  or          eax,0FFFFFFFFh                    ; 7BEA430A  and         ecx,edx                           ; 7BEA430D  shl         eax,cl                            ; 7BEA430F  sub         edx,ecx                           ; 7BEA4311  movdqu      xmm1,xmmword ptr [edx]            ; 7BEA4313  pxor        xmm2,xmm2                         ; 7BEA4317  pcmpeqb     xmm2,xmm1                         ; 7BEA431B  pcmpeqb     xmm1,xmm3                         ; 7BEA431F  por         xmm2,xmm1                         ; 7BEA4323  pmovmskb    ecx,xmm2                          ; 7BEA4327  and         ecx,eax                           ; 7BEA432B  jne         7BEA4337                          ; 7BEA432D  or          eax,0FFFFFFFFh                    ; 7BEA432F  add         edx,10h                           ; 7BEA4332  jmp         7BEA4313                          ; 7BEA4335  bsf         eax,ecx                           ; 7BEA4337  add         eax,edx                           ; 7BEA433A  movd        edx,xmm3                          ; 7BEA433C  xor         ecx,ecx                           ; 7BEA4340  cmp         dl,byte ptr [eax]                 ; 7BEA4342  cmovne      eax,ecx                           ; 7BEA4344  ret                                           ; 7BEA4347

1 - 4行:原理和之前类似,[esp+8] 处为要查找的目标字符值,到第四行,将edx寄存器的0-7位,和8-15位均设置为查找目标字符。

5 - 7行:将 xmm3 寄存器的每字节均设置为目标字符值,如果我们查找 'x' 字符,则 xmm3 的值为 "xxxxxxxxxxxxxxxx"。

8 - 13行:将查询的源字符串的地址进行16位对齐,并指向源字符串地址之前。并将 eax 值左移目标字符串地址的低四位值(意味着将eax作为之后取值的mask);

14 - 31 行:是查询的主要逻辑,下面我们详细讨论。

第14行,将edx指针指向内存开始的16字节复制到 xmm1寄存器中;

第15行,将xmm2寄存器所有字节设置为0;

第16行,将xmm1中所有的字节与xmm2字节做比较,比较结果放到xmm2中(如果xmm1中字节和xmm2中字节相等,则xmm2对应字节将被设置为0xff,否则将被设置为0x00);

第17行,将xmm3(每个字节值均为目标字符值)和xmm1中的字节做比较,结果放置到xmm1中,如果是第一次做比较,则xmm1中可能存有查找字符串之前的内容,而且有可能包含查找的目标字符,这种情况将在第20行进行处理;

第18行,将xmm1中(源字符串中16个字符或者字符串n个字节内容+字符串前n个字符和要查找的目标字符的比对结果,即前n个字符的擦护照结果)和xmm2中内容执行字节或运算。并将结果放到 xmm2 中。

第19行,按照xmm2中字节内容,生成一个 mask值,并将其放到 ecx 寄存器;

第20行,将ecx和eax(如果第一次,有效位被第12行设置为1,无效位被置为0)执行 and 运算;

第21行,如果20行执行结果不为0(说明找到了目标值),跳转到第25行;

第22行,eax 所有位均置为1;

第23行,将源字符串指针前移16(10h)个字节;

第24行,跳转到循环初始位置,开始新的一轮循环;

第25行,查找ecx中为1的位的编号,并将编号放置到eax;

第26行,将源字符串指针前移eax个字节,这就是目标字符所在位置了;

第27行,从xmm3(每个字节均为查找目标字符)中读取4个字节,并将值放置到edx中;

第28行,置ecx为0,以备返回(目标字符未找到);

第29行,比较dl(edx最低字节)和eax指向的字符;

第30行,如果29行比较结果不相等,说明没有找到目标字符,就置eax为0,否则eax不变;

第31行,返回;

这里可以看到,因为使用了 xmm 寄存器,我们每次都处理了16个字节,那为什么效率提升不是16倍呢?只能归结为xmm寄存器增加了电路复杂性,使得处理周期增加了一倍吧。


本文地址:软件教程频道 https://www.eeeoo.cn/ruanjian/903427_2.html,嗨游网一个专业手游免费下载攻略知识分享平台,本站部分内容来自网络分享,不对内容负责,如有涉及到您的权益,请联系我们删除,谢谢!

共2页 1 2 当前是最后一页

软件教程
小编:小嗨整编
相关文章相关阅读
  • 办公软件快捷键大全表(办公软件函数公式大全)

    办公软件快捷键大全表(办公软件函数公式大全)

    办公软件快捷键大全表(办公软件函数公式大全)办公软件快捷键大全表1.Alt系列2.Ctrl+数字3.Ctrl+Shift4.Shift系列办公软件函数公式大全1、Ctrl+字母Ctrl+A全选Ctrl+P打印Ctrl+C复制Ctrl+V粘贴...

  • c语言的输入函数有哪些

    c语言的输入函数有哪些

    c语言的输入函数有:1、scanf()函数、从标准输入stdin读取格式化输入;2、getchar()函数,从标准输入stdin获取一个字符;3、gets()函数,从标准输入stdin读取一行;4、getch()函数,从stdin流中读取字...

  • 什么是构造函数?详解JavaScript中的构造函数

    什么是构造函数?详解JavaScript中的构造函数

    作为原型和原型链的基础,先了解清楚构造函数以及它的执行过程才能更好地帮助我们学习原型和原型链的知识。本篇文章带大家详细了解一下javascript中的构造函数,介绍一下怎么利用构造函数创建一个js对象,希望对大家有所帮助!一个普通的函数被用...

  • Excel函数学习之CHOOSE函数 vs IF函数

    Excel函数学习之CHOOSE函数 vs IF函数

    如果Excel函数圈也有江湖,那CHOOSE函数绝对算得上扫地僧。它不如IF函数那般威震江湖,但它的本领却更胜一筹。今天小花就带大家好好见识一下被大多数人冷遇的CHOOSE函数!   CHOOSE函数使用index_num返回数值参数列...

  • Matlab中length函数怎么用

    Matlab中length函数怎么用

    在matlab中,length函数用于返回向量、数组或字符串中的元素个数。以下是length函数的一些用法示例:1、返回向量中的元素个数:v = [1, 2, 3, 4, 5];  numElements = length(v); % 结果...

  • mysql列转行函数是什么

    mysql列转行函数是什么

    在mysql中,列转行函数是“group_concat()”函数;该函数用于将非空列值按照分组条件进行合并并最终返回,如果其中有空值则返回的结果是空,语法为“selectgroup_concat(name separator';')列...

  • excel求差值用什么函数

    excel求差值用什么函数

    在excel中求差值是没有专门的函数,excel求差值的方法是:首先打开excel工作表;然后在f7单元格内输入“=d7-e7”公式;最后按回车即可得到两个数之间的差值即可。本文操作环境:Windows7系统、DellG3电脑、Micro...

  • Excel Mid函数的使用方法

    Excel Mid函数的使用方法

    在Excel中,提取指定长度的字符有两个函数,分别为Mid函数和Midb函数,前者用于提取指定长度的字符个数,后者用于提取指定长度的字节个数。用Mid函数提取时,无论是汉字、字母还是数字都算一个字符;用Midb函数提取时,汉字算两个字节...

  • 周排行
  • 月排行
  • 年排行

精彩推荐