热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

for循环语句的头部执行顺序--汇编语言分析

最近因为在准备面试,所以看了不少面试题。每个都仔细分析,争取不留死角并解决自己的所有疑惑,同时也提高编程水平。今天偶然发现对for循环语句的头部执行顺序还有一点小疑惑,虽然经常使用,但往

       最近因为在准备面试,所以看了不少面试题。每个都仔细分析,争取不留死角并解决自己的所有疑惑,同时也提高编程水平。今天偶然发现对for循环语句的头部执行顺序还有一点小疑惑,虽然经常使用,但往往不太关注某些具体细节。因为是搞嵌入式的,所以对底层细节还是熟悉一点比较好。通过在网上查阅资料发现不少对此知识点的解读,但往往仅就C语言本身进行讲解,没有解释底层实现情况。大学期间学过微机原理,所以对汇编语言也有些了解,前不久在CSDN上看了赵中老师的“C语言指针与汇编内存地址”,最近对汇编级的调试挺感兴趣,所以今天我准备就for循环语句的汇编级实现进行介绍。

       以下程序编写调试的开发环境为Microsoft Visual Studio Professional 2015,所有结果及结论仅适用于本开发环境,其它开发环境的实现情况未亲自测试,在此不做评价。首先编写了一个C语言小程序如下:

#include

char i;

int main()
{

for (i = 0; i <2; i++)
{
printf("hello world\n");
}
}

最初我所理解的执行顺序是:i=0赋值 → 打印输出 → i++ → i<2进行判断 → 打印输出 → i++ →   i<2进行判断 → 打印输出 → i++  ......(红色为一个循环)这样最终执行两次输出,与程序运行输出结果一致。但在反汇编中却发现并不是这样运行的。按F11进行单步调试发现执行顺序如下图,图中printf函数一步跳过执行:

汇编指令的解释在此不做过多介绍。由图可知,首先执行“ mov     byte ptr [i (0F58139h)], 0 ” 即给 i 赋值,i=0,然后程序跳转执行i<2判断语句,之后执行打印输出语句,接着执行i++操作,再进行i<2比较,接着打印输出......这样程序执行流程为: i=0赋值 → i<2进行判断 → 打印输出 → i++ →i<2进行判断 → 打印输出 → i++ →  ......(红色为一个循环)这样最终也执行两次输出,与程序运行输出结果一致。可见我之前的理解是错误的,之所以运行结果一致仅仅是巧合,如果是 for (i = 0; i <0; i++) 则执行结果不一致。只不过这种情况往往很少见到。综上所述,for循环语句的头部执行顺序为(至少在本开发环境中是这样的):

i 初始赋值  执行条件判断   打印输出等语句   i 赋新值  执行条件判断  打印输出等语句   赋新值 ......


推荐阅读
  • C语言基础入门:7个经典小程序助你快速掌握编程技巧
    本文精选了7个经典的C语言小程序,旨在帮助初学者快速掌握编程基础。通过这些程序的实践,你将更深入地理解C语言的核心概念和语法结构。 ... [详细]
  • 本文介绍如何利用栈数据结构在C++中判断字符串中的括号是否匹配。通过顺序栈和链栈两种方式实现,并详细解释了算法的核心思想和具体实现步骤。 ... [详细]
  • C++实现经典排序算法
    本文详细介绍了七种经典的排序算法及其性能分析。每种算法的平均、最坏和最好情况的时间复杂度、辅助空间需求以及稳定性都被列出,帮助读者全面了解这些排序方法的特点。 ... [详细]
  • MySQL索引详解与优化
    本文深入探讨了MySQL中的索引机制,包括索引的基本概念、优势与劣势、分类及其实现原理,并详细介绍了索引的使用场景和优化技巧。通过具体示例,帮助读者更好地理解和应用索引以提升数据库性能。 ... [详细]
  • 深入了解 Windows 窗体中的 SplitContainer 控件
    SplitContainer 控件是 Windows 窗体中的一种复合控件,由两个可调整大小的面板和一个可移动的拆分条组成。本文将详细介绍其功能、属性以及如何通过编程方式创建复杂的用户界面。 ... [详细]
  • 在Java中,this是一个引用当前对象的关键字。如何通过this获取并显示其所指向的对象的属性和方法?本文详细解释了this的用法及其背后的原理。 ... [详细]
  • 本文详细介绍了C语言的起源、发展及其标准化过程,涵盖了从早期的BCPL和B语言到现代C语言的演变,并探讨了其在操作系统和跨平台编程中的重要地位。 ... [详细]
  • 本文探讨了如何通过预处理器开关选择不同的类实现,并解决在特定情况下遇到的链接器错误。 ... [详细]
  • 本文介绍了一种基于选择排序思想的高效排序方法——堆排序。通过使用堆数据结构,堆排序能够在每次查找最大元素时显著提高效率。文章详细描述了堆排序的工作原理,并提供了完整的C语言代码实现。 ... [详细]
  • 本文详细介绍了Java中实现异步调用的多种方式,包括线程创建、Future接口、CompletableFuture类以及Spring框架的@Async注解。通过代码示例和深入解析,帮助读者理解并掌握这些技术。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了C语言中的指针,包括其基本概念、应用场景以及使用时的优缺点。同时,通过实例解析了指针在内存管理、数组操作、函数调用等方面的具体应用,并探讨了指针的安全性问题。 ... [详细]
  • 本文详细介绍了Grand Central Dispatch (GCD) 的核心概念和使用方法,探讨了任务队列、同步与异步执行以及常见的死锁问题。通过具体示例和代码片段,帮助开发者更好地理解和应用GCD进行多线程开发。 ... [详细]
  • InmyapplicationIhaveQGraphicsScenewithpixmapaddedandallisviewedinQGraphicsViewwithsc ... [详细]
  • 1.基本原理边缘检测一般是利用微分等方法,通过对灰度跃变的分析寻找图像上区域边缘的技术。今天的猪脚是梯度算子和Roberts算子。1.梯度算子是怎么来的? ... [详细]
author-avatar
LMS柳树_
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有