对 strlen 汇编代码的解释

简介:     【原创性声明】在调试到strlen的汇编代码时,我发现其汇编代码略显“古怪”,当时并未有精力去关注,在研究过后重新查看了strlen的汇编代码。对strlen的原理解释并非原创,而是参考了《strlen源码剖析》一文的解释,在理解后感觉有必要写此文记之。

    【原创性声明】在调试到strlen的汇编代码时,我发现其汇编代码略显“古怪”,当时并未有精力去关注,在研究过后重新查看了strlen的汇编代码。对strlen的原理解释并非原创,而是参考了《strlen源码剖析》一文的解释,在理解后感觉有必要写此文记之。

 

    首先我们创建一个测试项目,来比较以下我们自己用常规方法写的的strlen函数和<string.h> 中的strlen的时间消耗水平,这里我用 GetTickCount()做一个初步的估算(并不精确),测试代码如下:

 

 

img_405b18b4b6584ae338e0f6ecaf736533.gif strlen时间消耗测试
#include  " stdafx.h "
#include 
< stdlib.h >
#include 
< stdio.h >
#include 
< string .h >
#include 
< windows.h >

// 这是我们自己按常规算法实现的strlen,即逐个byte判断是否为0
size_t mystrlen( char *  s)
{
    
char *  p  =  s;
    
while ( * p)  ++ p;
    
return  (p  -  s);
}

int  main( int  argc,  char *  argv[])
{
    
char *  s;
    size_t result, i;
    DWORD tickcount;

    s 
=  ( char * )malloc( 4096 );
    memset(s, 
' a ' 4096 );
    s[
4091 =   0 ;

    
// 粗略测试两种strlen的时间
    
// 标准库中的strlen:
    tickcount  =  GetTickCount();
    
for (i = 0 ; i < 20000 ; i ++ )
    {
        result 
=  strlen(s);
    }
    printf(
" strlen  :  %ld ms, result = %ld\n " , GetTickCount()  -  tickcount, result);

    
// 我们自己编写的strlen:
    tickcount  =  GetTickCount();
    
for (i = 0 ; i < 20000 ; i ++ )
    {
        result 
=  mystrlen(s);
    }
    printf(
" mystrlen:  %ld ms, result = %ld\n " , GetTickCount()  -  tickcount, result);

    free(s);
    
return   0 ;
}

 

 

 

    该测试的输出结果如下:

    strlen  :  16 ms, result = 4091
    mystrlen:  218 ms, result = 4091

 

    首先毫无疑问两种方法的时间复杂度相同(O(n)),区别在于常数系数不同,在这里我们自己写的函数的时间消耗大约是标准库版本的 13 倍之多。下面我们可以分别看下两个版本的汇编代码。

 

    首先是我们自己编写的mystrlen版本,编译器产生的汇编代码如下:

 

 

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码

.
text: 00401020  mystrlen        proc near
.
text: 00401020
.
text: 00401020  var_44          = dword ptr -44h
.
text: 00401020  var_4           = dword ptr - 4
.
text: 00401020  arg_0           = dword ptr   8
.
text: 00401020
.
text: 00401020                   push     ebp
.
text: 00401021                   mov      ebp, esp
.
text: 00401023                   sub      esp, 44h
.
text: 00401026                   push     ebx
.
text: 00401027                   push     esi
.
text: 00401028                   push     edi
.
text: 00401029                   lea      edi, [ebp+var_44]
.
text: 0040102C                   mov      ecx, 11h
.
text: 00401031                   mov      eax, 0CCCCCCCCh
.
text: 00401036                   rep   stosd
.
text: 00401038                   mov      eax, [ebp+arg_0]   ;
. text: 0040103B                   mov      [ebp+var_4], eax   ;  char* p = s;
. text: 0040103E
.
text: 0040103E   loc_40103E:                               ;  
. text: 0040103E                   mov      ecx, [ebp+var_4]
.
text: 00401041                   movsx    edx, byte ptr [ecx]  ;  edx = *p;
. text: 00401044                   test     edx, edx             ;  if ( edx == 0 )
. text: 00401046                   jz       short loc_401053     ;      break;
. text: 00401048                   mov      eax, [ebp+var_4]
.
text: 0040104B                   add      eax,  1
.
text: 0040104E                   mov      [ebp+var_4], eax     ;  ++p;
. text: 00401051                   jmp      short loc_40103E     ;   
. text: 00401053   ;  
. text: 00401053
.
text: 00401053   loc_401053:                               ;  CODE XREF: mystrlen+26
目录
相关文章
|
编译器 Linux C语言
函数栈帧的创建和销毁(以C语言代码为例,汇编代码的角度分析)(上)
函数栈帧的创建和销毁(以C语言代码为例,汇编代码的角度分析)
|
3月前
|
网络协议 C++
解决MASM32代码汇编出错: error A2181: initializer must be a string or single item
解决MASM32代码汇编出错: error A2181: initializer must be a string or single item
|
4月前
|
存储 算法 程序员
神秘代码世界惊现高效秘籍!究竟是什么让汇编语言编程如此强大?快来一探究竟!
【8月更文挑战第31天】《代码之美:探索高效汇编语言编程的最佳实践》介绍了汇编语言在系统内核、嵌入式系统及高性能应用中的不可替代作用。书中强调了深入理解处理器架构、提升代码可读性、优化算法与数据结构及有效利用寄存器等最佳实践的重要性。通过具体示例,如在 x86 架构下实现高效的加法函数,展示了如何运用这些技巧编写出既高效又可靠的汇编代码,充分展现了汇编语言的独特魅力及其在现代软件开发中的价值。
45 0
|
3月前
|
Windows
【原创】DOS下TSR程序的汇编演示代码2--黑屏保护程序
【原创】DOS下TSR程序的汇编演示代码2--黑屏保护程序
【原创】DOS下TSR程序的汇编演示代码1--自动按键程序
【原创】DOS下TSR程序的汇编演示代码1--自动按键程序
|
4月前
|
NoSQL 前端开发 程序员
【震撼揭秘!】程序员绝不会告诉你的秘密:掌握汇编语言调试,轻松从软件故障中全身而退——透视代码底层,成为Bug猎人!
【8月更文挑战第31天】《调试的艺术:如何利用汇编语言追踪和解决软件问题》探讨了使用汇编语言进行高效调试的方法。无论是初学者还是资深开发者,面对棘手的 bug 时,高级语言的信息往往不足。文章通过具体示例展示如何通过汇编代码定位问题,如 C 语言中数组求和函数的崩溃问题。借助 `gcc -S` 生成的汇编代码和 GDB 调试器,可以深入理解程序行为,从而更准确地解决问题。掌握这一技能,将使你在复杂问题面前更加从容。
42 2
|
4月前
|
C语言
51单片机汇编语言流水灯代码
51单片机汇编语言流水灯代码
|
4月前
|
C# 开发者 图形学
Xamarin 竟在游戏开发领域大胆探索,跨平台优势与强大功能结合,开启游戏开发新潮流!
【8月更文挑战第31天】《Xamarin在游戏开发领域的探索》介绍了Xamarin作为跨平台开发框架,在移动游戏开发中的应用。它利用C#语言的优势,提供高效的开发体验,并结合各平台图形库实现高质量画面。本文还展示了Xamarin如何简化游戏逻辑处理、支持多线程编程及与Unity等工具集成,提升游戏质量和开发效率。此外,Xamarin还支持热更新和多平台发布,进一步优化游戏维护流程。
44 0
|
7月前
|
Java C++
如何在JAVA代码中嵌入汇编
如何在JAVA代码中嵌入汇编
109 1