注册 登录
编程论坛 汇编论坛

观看了库函数 strlen 函数的原型 尝试着自己模仿写了一下 但是看反汇编代码 感觉还是不太一样

wp231957 发布于 2014-07-22 16:15, 3022 次点击
库函数strlen的调用代码及反汇编代码

程序代码:

00401000 >/$ 55             PUSH EBP
00401001  |. 8BEC           MOV EBP,ESP
00401003  |. 83EC 18        SUB ESP,18
00401006  |. C745 FC EC2040>MOV DWORD PTR SS:[EBP-4],w5.004020EC     ;  ASCII "This is a test text."
0040100D  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
00401010  |. 8945 F4        MOV DWORD PTR SS:[EBP-C],EAX
00401013  |. 8B4D F4        MOV ECX,DWORD PTR SS:[EBP-C]
00401016  |. 83C1 01        ADD ECX,1
00401019  |. 894D F0        MOV DWORD PTR SS:[EBP-10],ECX
0040101C  |> 8B55 F4        /MOV EDX,DWORD PTR SS:[EBP-C]
0040101F  |. 8A02           |MOV AL,BYTE PTR DS:[EDX]
00401021  |. 8845 EF        |MOV BYTE PTR SS:[EBP-11],AL
00401024  |. 8345 F4 01     |ADD DWORD PTR SS:[EBP-C],1
00401028  |. 807D EF 00     |CMP BYTE PTR SS:[EBP-11],0
0040102C  |.^75 EE          \JNZ SHORT w5.0040101C
0040102E  |. 8B4D F4        MOV ECX,DWORD PTR SS:[EBP-C]
00401031  |. 2B4D F0        SUB ECX,DWORD PTR SS:[EBP-10]
00401034  |. 894D E8        MOV DWORD PTR SS:[EBP-18],ECX
00401037  |. 8B55 E8        MOV EDX,DWORD PTR SS:[EBP-18]
0040103A  |. 8955 F8        MOV DWORD PTR SS:[EBP-8],EDX
0040103D  |. 8B45 F8        MOV EAX,DWORD PTR SS:[EBP-8]
00401040  |. 50             PUSH EAX                                 ; /<%d>
00401041  |. 68 04214000    PUSH w5.00402104                         ; |format = "len=%d
"
00401046  |. FF15 A0204000  CALL DWORD PTR DS:[<&MSVCR100.printf>]   ; \printf
0040104C  |. 83C4 08        ADD ESP,8
0040104F  |. 33C0           XOR EAX,EAX
00401051  |. 8BE5           MOV ESP,EBP
00401053  |. 5D             POP EBP
00401054  \. C3             RETN

对应c代码如下:

#include <stdio.h>
#include <string.h>

int main(void)
{
   char* p=
"This is a test text.";
   int len=strlen(p);
   printf(
"len=%d\n",len);
   return 0;
}
9 回复
#2
wp2319572014-07-22 16:15
我自己按照上面的反汇编代码 模仿写了一下  但是貌似不太一样呢

程序代码:

00401000 >/$ 55             PUSH EBP
00401001  |. 8BEC           MOV EBP,ESP
00401003  |. 83EC 0C        SUB ESP,0C
00401006  |. C745 FC EC2040>MOV DWORD PTR SS:[EBP-4],w5.004020EC     ;  ASCII "This is a test text."
0040100D  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
00401010  |. 8945 F8        MOV DWORD PTR SS:[EBP-8],EAX
00401013  |> 8B4D FC        /MOV ECX,DWORD PTR SS:[EBP-4]
00401016  |. 0FBE11         |MOVSX EDX,BYTE PTR DS:[ECX]
00401019  |. 85D2           |TEST EDX,EDX
0040101B  |. 74 0B          |JE SHORT w5.00401028
0040101D  |. 8B45 FC        |MOV EAX,DWORD PTR SS:[EBP-4]
00401020  |. 83C0 01        |ADD EAX,1
00401023  |. 8945 FC        |MOV DWORD PTR SS:[EBP-4],EAX
00401026  |.^EB EB          \JMP SHORT w5.00401013
00401028  |> 8B4D FC        MOV ECX,DWORD PTR SS:[EBP-4]
0040102B  |. 2B4D F8        SUB ECX,DWORD PTR SS:[EBP-8]
0040102E  |. 894D F4        MOV DWORD PTR SS:[EBP-C],ECX
00401031  |. 8B55 F4        MOV EDX,DWORD PTR SS:[EBP-C]
00401034  |. 52             PUSH EDX                                 ; /<%d>
00401035  |. 68 04214000    PUSH w5.00402104                         ; |format = "len=%d
"
0040103A  |. FF15 A0204000  CALL DWORD PTR DS:[<&MSVCR100.printf>]   ; \printf
00401040  |. 83C4 08        ADD ESP,8
00401043  |. 33C0           XOR EAX,EAX
00401045  |. 8BE5           MOV ESP,EBP
00401047  |. 5D             POP EBP
00401048  \. C3             RETN

对应代码如下:
#include <stdio.h>
#include <string.h>

int main(void)
{
   char* p=
"This is a test text.";
   int len0=(int)(p);
   while(*p!='\0') p++;
   int len=(int)(p)-len0;
   printf(
"len=%d\n",len);
   return 0;
}
#3
hu9jj2014-07-23 07:28
效果差不多就行。原代码不同,编译后的程序再反编译,代码当然会不同。甚至于有时反编译的代码与原代码也会有少许差异的。
#4
funyh2502014-07-23 10:53
时间和空间上都是等效的
如楼上所说就是代码不一样而已
#5
wp2319572014-07-23 15:06
看了strlen.c  主题思路是对的 但是还是有区别的

程序代码:

size_t __cdecl strlen (const char * str)
{
        const char *eos = str;
        while( *eos++ ) ;
        return( (int)(eos - str - 1) );
}



[ 本帖最后由 wp231957 于 2014-7-23 15:26 编辑 ]
#6
funyh2502014-07-23 16:05
while( *eos++ ) ;


while(*p!='\0')
         p++;


精炼啊 学习了
#7
zklhp2014-07-23 17:43
精炼也没用

这个代码 在编译器里面其实是内联的 对于不同的数据长度 编译出来的不一样
#8
funyh2502014-07-23 19:12
回复 7 楼 zklhp
又长知识了
#9
GoldenSpider2014-08-02 20:27
程序代码:
int __declspec(naked) strlenGS(char *dest)
{
  _asm
    {
        push  edi
        mov      edi,[esp+8]
        or      ecx,-1
        xor      al,al
        repnz scasb
        neg      ecx
        lea   eax,[ecx-2]
        pop   edi
        ret
    }
}
1