0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

C语言的3种循环结构分析

Q4MP_gh_c472c21 来源:计算机与网络安全 作者:计算机与网络安全 2021-05-20 13:43 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

C语言的循环结构有for循环、while循环、do循环和goto循环。本文介绍前3种循环方式。

1. for循环结构

for循环也可以称为步进循环,它的特点是常用于已经明确了循环的范围。看一个简单的C语言代码,具体如下:

#include 《stdio.h》int main(){ int nNum = 0, nSum = 0; for ( nNum = 1; nNum 《= 100; nNum ++ ) { nSum += nNum; } printf(“nSum = %d

”, nSum); return 0;}

这是很典型的求1~100的累加和的程序。通过这个程序来认识关于for循环结构的反汇编代码。

.text:00401028 mov [ebp+nNum], 0.text:0040102F mov [ebp+nSum], 0.text:00401036 mov [ebp+nNum], 1.text:0040103D jmp short LOC_CMP.text:0040103F ; ---------------------------------------------------------.text:0040103F.text:0040103F LOC_STEP: ; CODE XREF: _main+47j.text:0040103F mov eax, [ebp+nNum].text:00401042 add eax, 1.text:00401045 mov [ebp+nNum], eax.text:00401048.text:00401048 LOC_CMP: ; CODE XREF: _main+2Dj.text:00401048 cmp [ebp+nNum], 64h.text:0040104C jg short LOC_ENDFOR.text:0040104E mov ecx, [ebp+nSum].text:00401051 add ecx, [ebp+nNum].text:00401054 mov [ebp+nSum], ecx.text:00401057 jmp short LOC_STEP.text:00401059 ; ---------------------------------------------------------.text:00401059.text:00401059 LOC_ENDFOR: ; CODE XREF: _main+3Cj.text:00401059 mov edx, [ebp+nSum].text:0040105C push edx.text:0040105D push offset Format ; “nSum = %d

”.text:00401062 call _printf.text:00401067 add esp, 8.text:0040106A xor eax, eax

这次的反汇编代码,修改了其中的变量、标号,看起来更加直观。从修改的标号来看,for结构可以分为3部分,在LOC_STEP上面的部分是初始化部分,在LOC_STEP下面的部分是修改循环变量的部分,在LOC_CMP下面和LOC_ENDFOR上面部分是比较循环条件和循环体的部分。

for循环的反汇编结构如下:

; 初始化循环变量 jmp LOC_CMPLOC_STEP: ; 修改循环变量LOC_CMP: ; 循环变量的判断 jxx LOC_ENDFOR ; 循环体 jmp LOC_STEPLOC_ENDOF:

再用IDA来看一下生成的流程结构图,如图1所示。

c69876aa-b3ed-11eb-bf61-12bb97331649.jpg

图1 for结构的流程图

2. do…while循环结构

do循环的循环体总是会被执行一次,这是do循环与while循环的区别。这里还是1~100的累加和代码,来看一下它的反汇编结构。先看C语言代码,具体如下:

#include 《stdio.h》int main(){ int nNum = 1, nSum = 0; do { nSum += nNum; nNum ++; } while ( nNum 《= 100 ); printf(“nSum = %d

”, nSum); return 0;}

do循环的结构要比for循环的结构简单很多,反汇编代码也少很多。先来看一下IDA生成的流程图,如图2所示。

c6a590e2-b3ed-11eb-bf61-12bb97331649.jpg

图2 do循环流程图

反汇编代码如下:

.text:00401028 mov [ebp+nNum], 1.text:0040102F mov [ebp+nSum], 0.text:00401036.text:00401036 LOC_DO: ; CODE XREF: _main+3Cj.text:00401036 mov eax, [ebp+nSum].text:00401039 add eax, [ebp+nNum].text:0040103C mov [ebp+nSum], eax.text:0040103F mov ecx, [ebp+nNum].text:00401042 add ecx, 1.text:00401045 mov [ebp+nNum], ecx.text:00401048 cmp [ebp+nNum], 64h.text:0040104C jle short LOC_DO.text:0040104E mov edx, [ebp+nSum].text:00401051 push edx.text:00401052 push offset Format ; “nSum = %d

”.text:00401057 call _printf.text:0040105C add esp, 8.text:0040105F xor eax, eax

do循环的主体就在LOC_DO和0040104C的jle之间。其结构整理如下:

; 初始化循环变量LOC_DO: ; 执行循环体 ; 修改循环变量 ; 循环变量的比较 Jxx LOC_DO

3. while循环结构

while循环与do循环的区别在于,在进入循环体之前需要先进行一次条件判断,循环体有可能因为循环条件的不成立而一次也不执行。看1~100累加和的while循环代码:

#include 《stdio.h》int main(){ int nNum = 1, nSum = 0; while ( nNum 《= 100 ) { nSum += nNum; nNum ++; } printf(“nSum = %d

”, nSum); return 0;}

再来看一下它的反汇编代码,while循环比do循环多了一个条件的判断,因此会多一条分支。反汇编代码如下:

.text:00401028 mov [ebp+nNum], 1.text:0040102F mov [ebp+nSum], 0.text:00401036.text:00401036 LOC_WHILE: ; CODE XREF: _main+3Ej.text:00401036 cmp [ebp+nNum], 64h.text:0040103A jg short LOC_WHILEEND.text:0040103C mov eax, [ebp+nSum].text:0040103F add eax, [ebp+nNum].text:00401042 mov [ebp+nSum], eax.text:00401045 mov ecx, [ebp+nNum].text:00401048 add ecx, 1.text:0040104B mov [ebp+nNum], ecx.text:0040104E jmp short LOC_WHILE.text:00401050 ; -----------------------------------------------------------.text:00401050.text:00401050 LOC_WHILEEND: ; CODE XREF: _main+2Aj.text:00401050 mov edx, [ebp+nSum].text:00401053 push edx.text:00401054 push offset Format ; “nSum = %d

”.text:00401059 call _printf.text:0040105E add esp, 8.text:00401061 xor eax, eax

while循环的主要部分全部在LOC_WHILE和LOC_WHILEEND之间。在LOC_WHILE下面的两句是cmp和jxx指令,在LOC_WHILEEND上面是jmp指令。这两部分是固定的格式,其结构整理如下:

; 初始化循环变量等LOC_WHILE: cmp xxx, xxx jxx LOC_WHILEEND ; 循环体 jmp LOC_WHILELOC_WHILEEND:

再来看一下IDA生成的流程图,如图3所示。

c6c288f0-b3ed-11eb-bf61-12bb97331649.jpg

图3 while循环流程图

对于for循环、do循环和while循环这3种循环而言,do循环的效率显然高些,而while循环相对来说比for循环效率又高些。

参考文献:C++ 黑客编程揭秘与防范(第3版)

编辑:jq

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • C语言
    +关注

    关注

    183

    文章

    7646

    浏览量

    146113
  • 程序
    +关注

    关注

    117

    文章

    3847

    浏览量

    85453

原文标题:C语言逆向之循环结构分析

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    C语言主要特点

    3.数据类型丰富。C语言提供的数据类型包括整形、浮点型、字符型、数组类型、指针类型、结构体类型和共用体类型等,C99又扩充了复数浮点型、
    发表于 01-05 07:41

    C语言中实现函数宏的三方式

    (0) 不同的是,({}) 不能提前退出函数宏与支持返回值。({}) 毕竟不是 while 循环,不能直接使用 break退出函数宏是比较容易理解。那支持返回值是什么意思呢? 答案是 C 语言规定
    发表于 12-29 07:34

    C语言C++的区别及联系

    C语言C++到底是什么关系? 首先C++和C语言本来就是两
    发表于 12-24 07:23

    C语言循环队列

    data; } return -1; // Buffer is empty } 循环队列是一高效的数据结构,适用于缓冲区和数据流应用,例如串口通信接收缓冲。
    发表于 12-12 08:28

    C语言的编程技巧

    一个成员是一个未知大小的数组,适用于动态分配内存并关联一个可变长度的数组。‌ ‌3、匿名结构体和联合体‌:C语言允许在结构体或联合体中定义不
    发表于 11-27 06:46

    C语言程序的结构

    ,87LPC764有4KB的Flash ROM,而笔者的程序量只有2KB多点,因而第一个想法是改用C语言作为主要的开发语言,应该不至于导致代码空间不够用。其次,考虑到需要定时功能的模块(或称任务,以下统称任务
    发表于 11-26 08:12

    C语言的分支结构介绍

    1.简单if语句 C语言中的分支结构语句中的if条件语句。 简单if语句的基本结构如下: 代码语言:javascript if(表达
    发表于 11-25 07:48

    C语言和单片机C语言有什么差异

    汇编语言机器才能读懂,所以每个平台的编译器编译成对应平台汇编的程序,每个平台的汇编不一样,当然编译器也不一样。 DOS上的TC2 TC3 WINDOWS上的VC 8051的C51都有自已的编译器。具体
    发表于 11-14 07:55

    C语言结构体使用

    型的数据组合。 结构体的声明与定义 结构体的声明一般形式为: c struct 结构体名{ 成员1; 成员2; ... }; //注意分号 例如:
    发表于 11-12 08:30

    第4章 C语言基础以及流水灯的实现(4.5 4.6)

    (表达式)        {            循环体语句;        } 在C语言里,通常“表达式”符合条件叫做真,不符合条件,叫做假。比如前边i while(表达式)这个括号里的表达式,为真的时候,就会执行
    的头像 发表于 11-06 11:21 502次阅读

    人工智能行业如何使用for循环语句进行循环

    人工智能行业可以使用以下是关于for循环在不同编程语言中的基本用法说明: Python中的for循环: 主要用于遍历序列(列表、元组、字符串等) 典型结构:for item in se
    的头像 发表于 09-10 12:55 680次阅读

    C语言精彩编程百例-364页

    内容提要 C是一通用的程序设计语言,它包含了紧凑的表达式、丰富的运算符集合、现代控制流以及数据结构等四个部分。C
    发表于 06-13 17:28

    《ESP32S3 Arduino开发指南》第三章 C/C++语言基础

    执行的,先执行步骤1,然后再执行步骤2,最后执行步骤3。3.8 选择结构选择结构,又称分支结构,可以控制程序的部分流程是否被执行,或者是从多条执行路径
    发表于 06-10 09:20

    程序设计与数据结构

    的地址)出发,采用推导的方式,深入浅出的分析了广大C程序员学习和开发中遇到的难点。 2. 从方法论的高度对C语言在数据结构和算法方面的应用
    发表于 05-13 16:45

    深入理解C语言C语言循环控制

    C语言编程中,循环结构是至关重要的,它可以让程序重复执行特定的代码块,从而提高编程效率。然而,为了避免程序进入无限循环
    的头像 发表于 04-29 18:49 2205次阅读
    深入理解<b class='flag-5'>C</b><b class='flag-5'>语言</b>:<b class='flag-5'>C</b><b class='flag-5'>语言</b><b class='flag-5'>循环</b>控制