C语言编译过程分析及实验验证
一. 实验情况概述
本次实验完成了以下要求:
编写的一个简单C语言例子(至少包括3个C文件、至少一个头文件;含有初始化全局变量、未初始化全局变量、函数内静态变量与局部变量、赋值语句、if语句等),尽量不要包含第三方的头文件,按照预处理->编译->汇编->链接的操作过程,截图分析做成Word文档,理解并分析源程序与可执行程序Section的对应关系,特别是数据与指令,理解编译器的功能。
编写含有while循环、for循环的C程序,分析C语言的每个句子与汇编语言的对应关系,理解编译器的语义分析功能。
请编写含有函数调用(要有参数传递)的C程序,理解编译器在函数调用时所做的动作,并通过汇编试图去分析,验证函数的函数调用中的参数传递、调用与返回等
理解函数内局部变量如何分配,分析栈内分配过程。
编写的例子尝试编写一个makefile文件,然后进行make编译,然后通过make -j #n来编译,并验证加速编译。
二. 试验过程
一, 自己编写一个简单的C语言例子:
该例子包含四个文件,其中一个是头文件,具体如下:
图1.c语言源文件—main.c 图2 function.c
图3. yjy.h 图4 yjy.c
二, 分析编译过程:
1, 预处理:
使用如下命令进行预处理:
预处理后的文件内容如下:
图6 预处理后结果 main.i 图7 预处理后 yjy.i
图8 预处理后function.i
发现预处理的作用就是将头文件复制到.c文件中,并且将#define展开到文件使用的地方.
2.编译:
使用如下指令对文件进行编译:
图9 编译命令
编译后的文件内容为:
图10 编译后生成文件main.s 图11function.s
图12 yjy.s
由上图可知,编译的过程就是将经过宏展开的文件编译成汇编语言程序, 从而便于进一步汇编成为机器可以识别的机器语言程序.
3.汇编:
图13 汇编命令
汇编生成机器语言程序,是二进制程序,所以无法打开查看内容.
使用objdump 指令来查看sections节:
可以发现0.是代码段,1.是数据段,2.是bss未初始化段,3.是drectve,……
代码段大小为0xfc,数据段为0x04,
代码段对应main 中所有语句的内容,包含局部变量的使用,函数调用等,数据段包含静态变量,对应我们定义的全局变量.
下面的symbol table 是符号表,只要包含section符号,函数符号等.
4. 链接:
图14 链接命令
最后生成了可执行程序main.exe, 由于没有调用stdio.h,没有输入输出,所以程序执行完就退出了.
5. 分析可执行程序与源程序sections的对应关系:
使用如下指令查看可执行程序的sections:
使用如下指令查看可执行程序的sections:
结果如下:
可以看到包含很多节,其中代码段,是15,包含main 中的代码,数据段是24段,未初始化段bss是25段.
下面的符号表中定义了sections中的符号的含义,其他符号都定义了一段方法,可以在符号表中找到对应的内容.
三. 分析LLVM形式汇编程序
与高级语言程序 Section之间的对应关系:
在这里仅拿main.ll 举例说明:
使用如下指令进行编译成LLVM格式的中间代码;
图15 生成LLVM命令
结果如下:
现对上图进行分析:
开头四句话分别定义了:
模块ID,
源文件名,
目标数据层
目标编译类型
这些属于文件基本信息,不对应源文件位置.
这里定义了两个全局变量,int32类型,初始值分别为1,0, 4位大小对齐方式.
接下来这里定义了main函数, 第11~20句分配了局部变量, 都是int32类型,四位对齐方式,
第21~24句存储了部分局部变量的初始值,
然后25~26句 加载了函数参数到内存,第27句调用了add函数, 参数为前两句加载的,通过值传递方式, 第28句存储运算结果,这些整体对应
第29~31句对应, 语义分别为:加载%2的值到%14, %15=%14+1;
将%15的值存储到%2的位置, 这样就完成了n++的过程.
接下来32~35句就是调用multiply()的过程, 分别是参数写, 调用函数, 返回值 ,和上述add()类似,在此不做详解.
第36~38句对应,和上述类似.
第39~42句分别为:
参数传递, 比较 %21, %22的大小 ,将结果存入%23, 然后是跳转指令, 根据%23的值决定跳转到label %24 或者 %26. 对应.
之后是24和26两个标签,分别是加载%3到%25,或加载%4到%27然后无条件跳转到%28.
28标签中,有phi指令, phi节点是一个指令,用于根据当前块的前导选择一个值。也就是根据跳转的24或者26选择加载到%29的值到底是%25还是%27,这样就实现了maxn函数返回正确的值. 因为br指令判断后只会跳转一个标签,在这里选择返回哪个执行的值到%29实现正确的返回.然后再无条件跳转到30号标签.
此处我们已经开始了while的判断,30号标签正是判断内容的执行过程.
先加载%2到%31,然后比较判断%31 和 11 ,将结果存入%32,如果%31<11,则%32=0,然后吓一跳br根据%32的值选择跳转的位置.如果是0就跳转到33号标签,继续while内部的执行.
再然后就是33号标签对应while 语句内部的部分..
我们分析llvm的IR,发现最开始两条加载指令对应add函数的两个参数,然后call @add,然后存储返回结果,四条语句对应了一条函数执行的过程.
之后类似,又是四条语句对应了multiply的过程.之后三条语句对应了,这些语句都在前面解释过.
最后又无条件跳转到%30,继续判断是否n<11,然后再选择是否跳转到33继续执行while内的部分.
我们再看第42号lable:
调用fibonacci,调用FrogJumpSteps,定义equal,存储初始值为0,这些类似的都在上面解释过.第77~81行对应
第82~85行,先加载两个局部变量值,然后判断是否相等,然后再根据结果跳转到48或49.
这两个标签就对应给equal赋值赋哪个.然后再无条件跳转到50
50好标签就是返回0.
后面还有一些函数声明,变量声明等.
至此,分析结束
四, 编写makefile文件:
在wsl中使用time make编译, 单进程和多进程多次交叉进行,得到如下
尝试使用Makefile编译,结果如下:
多进程平均时间< 单进程平均时间,故可以得出结论 ,多进程加快了编译.
C语言编译过程分析及实验验证相关推荐
- 各种语言速度之比,实验验证Cgojuliajavapythonoctave
一.Julia在Linux上的运行时间 1.调用python包来实现计时 在PyCall扩展包中,模仿Python的import语句,提供了一个可以导入Python模块的@pyimport宏.并且,为 ...
- 周期置换加密算法用c语言实现,古典密码实验报告.doc
. .. 哈尔滨工程大学 实 验 报 告 实 验 名 称: 古典密码算法 班 级: 学 号: 姓 名: 实 验 时 间: 2014年4月 成 绩: 指 导 教 师: 实验室名称: 哈尔滨工程大学实验室 ...
- 密码学实验报告c语言程序,密码学_实验一_古典密码算法_C语言.doc
您所在位置:网站首页 > 海量文档  > 高等教育 > 实验设计 密码学_实验一_古典密码算法_C语言.doc8页 本 ...
- c语言的适当大小的子集,编译原理上机实验报告
编译原理上机实验报告,编制C语言子集的词法分析程序,编制递归下降法的语法分析程序 编译技术上机实验题目 实验一 一.题目 编制C语言子集的词法分析程序 二.目的 通过设计.编制.调试一个具体的词法分析 ...
- 编译原理实验代码c语言,编译原理实验 简单词法分析(含源代码和实验结果)
可直接运行 原创!! 附录一 实验报告样式 <编译原理>实验报告 实验2 简单词法分析 姓名 陈婷婷 学号 1009050121 班级 计科1001班 时间: 2012/4/5 地点:文波 ...
- c 语言编写编译原理语义分析实验,北邮 编译原理 语义分析实验报告
<北邮 编译原理 语义分析实验报告>由会员分享,可在线阅读,更多相关<北邮 编译原理 语义分析实验报告(14页珍藏版)>请在人人文库网上搜索. 1.编译原理第六章 语义分析目 ...
- Java语言程序设计实验指导_《java语言程序设计》上机实验指导手册(4).doc
<java语言程序设计>上机实验指导手册(4).doc 1JAVA语言程序设计上机实验指导手册(4)2实验四JAVA面向对象编程1[目的]①通过编程和上机实验理解JAVA语言是如何体现面向 ...
- c语言消字母游戏实验报告,C语言编程实验报告格式示例
暨南大学数学系数学系,2011年语言课程设计课程实验项目目录学生姓名: 学生ID: 实验项目名称计划时间和课程每组人数实验属性开放要求要求摘要实验1熟悉使用WinTC / VC验证实验2数据类型,运算 ...
- c语言代码大全表解释_正点原子Linux第十章C语言版LED灯实验
1)资料下载:点击资料即可下载 2)对正点原子Linux感兴趣的同学可以加群讨论:935446741 3)关注正点原子公众号,获取最新资料更新 第十章C语言版LED灯实验 第八章我们讲解了如何用汇编语 ...
最新文章
- J2EE复习(二)XML
- 再测Golang的JSON库
- 危机四伏的千亿级金融放贷市场,我们能做什么?
- CCN:拥有雄厚实力的BCH将成为下一轮牛市的催化剂
- 【转】线性代数的几何意义
- pycharm+python+bootstrap写一个登陆界面_Python--day56(前后台数据交互、bootstrap)
- boost::hana::make_type用法的测试程序
- 08 线性回归 + 基础优化算法【动手学深度学习v2】
- ios 获取固件版本_觉得iOS测试版本BUG太多?系统降级试一试?
- 《探索需求》——阅读笔记三
- 数据结构面试经典问题汇总
- 主板开启网络唤醒_主板远程唤醒设置
- 【HAVENT原创】superagentCallback*** is not defined
- 短视频剪辑怎么做?4步教你快速入门
- APP日志的抓取方法——转载
- 教你win7去除快捷方式小箭头方法
- C++包扩展_Netgear 网件 EAX80 AX6000规格 无线扩展器 开箱拆解评测
- Windows7双系统卸载Ubuntu
- EA绘制类图时,怎样将类由ICON形式(圆形)转为Label形式(方形)
- 大众创业热度不减,好机友项目强势来袭