ICS大作业--hello程序人生

2023-11-06

										摘  要

Hello是每个程序员第一个接触的程序,在本文中利用计算机系统所学的知识,基于Linux平台,通过gcc、objdump、gdb、edb等工具,从c源程序的预处理开始,跟踪分析程序编译、汇编、链接、进程管理、存储管理、I\O管理整个过程,完整的参与hello的程序人生。走过C语言程序生命周期的四季,见证shell命令之春,fork进程之夏,加载执行之秋,回收释放之冬,感悟计算机系统之美。

关键词:计算机系统 汇编 链接 进程 虚拟内存

										**第1章 概述**

1.1 Hello简介
在linux中,hello.c经过cpp的预处理、ccl的编译、as的汇编、ld的链接最终成为可执行目标程序hello,在shell中键入相应命令行参数后,shell解析命令并构建argc,argv[]和envp[]参数列表,shell再调用fork()函数创建一个子进程,子进程获得与父进程完全相同的虚拟存储空间的一个备份。将解析得到的argc,argv[]和envp[]参数列表传给execve()函数作为参数,execve()函数启动加载器,在当前的上下文中开始执行可执行文件hello第一条指令即将控制转移到子进程,于是hello便从Program摇身一变成为Process,这便是P2P的过程。
开始执行程序后,随着虚拟存储的访问程序开始载入物理内存,然后进入 main函数执行目标代码,CPU通过上下文切换为运行的hello分配时间片执行逻辑控制流。当hello进程运行结束后,内核将子进程的退出状态传递给父进程,父进程shell(或init进程)负责回收hello进程,内核删除相关数据结构,以上全部便是020的过程。
1.2 环境与工具
硬件环境:Intel Core i5-8300H x64CPU 2.3GHZ,8G RAM,128G SSD +1T HDD.
软件环境:Ubuntu18.04.1 LTS
开发与调试工具:gdb,gcc,as,ld,edb,readelf,HexEdit
1.3 中间结果
hello.i 预处理之后文本文件
hello.s 编译之后的汇编文件
hello.o 汇编之后的可重定位目标执行
hello 链接之后的可执行目标文件
hello.o.objdump Hello.o的反汇编文件
hello.objdump Hello的反汇编文件

1.4 本章小结
程序有四季,往来知春秋。Hello波澜壮阔的人生画卷即将展开。。。

(第1章0.5分)

第2章 预处理
2.1 预处理的概念与作用
预处理:预处理程序(CPP)对源程序中以字符#开头的命令进行处理。
作用:c预处理程序为cpp(C Preprocessor),主要用于C语言编译器对各种预处理命令进行处理,包括对头文件的包含,宏定义的扩展,条件编译的选择等,例如,对于#include指示的处理结果,就是将相应的.h文件的内容插入到源程序文件中。

2.2在Ubuntu下预处理的命令
预处理命令:
在这里插入图片描述

具体过程:
在这里插入图片描述
在这里插入图片描述
2.3 Hello的预处理结果解析
在这里插入图片描述
Hello.i文件部分截图

解析:预处理主要是对各种预处理命令进行处理,具体包括对头文件的包含,宏定义的扩展,条件编译的选择等。预处理主要是根据#符号进行处理,在hello中,对于#include指示的处理结果,就是将相应的.h文件的内容插入到源程序文件中,上图中的主要是对stdio.h unistd.h stdlib.h的依次展开,之后再对宏定义进行拓展,再进行条件编译的选择,即根据条件值来决定是否执行包含其中的逻辑。
2.4 本章小结
预处理开启程序编译之路,#符谱写hello人生初章。字字句句头文件,点点滴滴宏定义,条件编译一线牵。

(第2章0.5分)

				**第3章 编译**

3.1 编译的概念与作用
编译:编译程序(CCL)对预处理后的源程序进行编译,生成一个汇编语言源程序文件。
作用:主要是将C语言文件翻译为汇编语言文件。C编译器在进行具体的程序翻译之前,会先对源程序进行词法分析和语法分析,然后根据分析的结果进行代码优化和存储分配,最终把C语言源程序翻译为汇编语言程序。

3.2 在Ubuntu下编译的命令
编译命令:
在这里插入图片描述

编译过程:
在这里插入图片描述
在这里插入图片描述

3.3 Hello的编译结果解析
部分编译结果:
在这里插入图片描述

汇编指令:
指令 含义
.file 声明源文件
.text 以下是代码段
.globl 声明一个全局变量
.data 表明在.data节
.section .rodata 以下是.rodata节
.align 声明对指令或者数据的存放地址进行对齐的方式
.type 用来指定是函数类型或是对象类型
.size 声明大小
.long、.string 声明一个long、string类型

结果解析:
3.3.1 整数(int 型)

1.全局变量 sleepsecs:
在这里插入图片描述
由代码可见,首先在.text节中被声明为global变量,之后在.data节中声明对齐方式为4字节对齐,为对象类型,声明大小为4字节,另外设置为long类型其值为2(long类型在linux下与int相同为4B,将int声明为long应该是编译器偏好)。
2.局部变量 i: 在栈中分配内存,只读段和读写数据段均不做声明。如下所示,64位下通过rbp分配栈空间给i
在这里插入图片描述

	3.命令行参数 argc: 由shell解析后构造出,传递给execve作为参数启动加载器,存放在main的栈帧之上。
	4.立即数:在代码段中,运行程序时放入栈或寄存器中。

3.3.2 数组
Argv和envp: 由shell解析后构造出,传递给execve作为参数启动加载器,存放在main的栈帧之上。
在这里插入图片描述

3.3.3 字符串
在这里插入图片描述
Printf函数的命令行格式串,首先声明在.rodata节中,再声明类型为string,分别用.LC0和.LC1指代

3.3.4 赋值
程序中涉及的赋值操作有:
1.int sleepsecs=2.5 :因为sleepsecs是全局变量,所以直接在.data节中将sleepsecs声明为值2的long类型数据。
2.i=0:整型数据的赋值使用mov指令完成,在栈或寄存器中分配存储空间,根据数据的大小不同使用不同后缀

3.3.5 类型转换(隐式)
在这里插入图片描述
隐式类型转换,将float转换为int型。当在double或float向int进行类型转换的时候,程序改变数值和位模式的原则是:值会向零舍入,直接舍掉小数点后的部分。如果溢出则为NAN, 与Intel兼容的微处理器指定位模式[10…000]为整数不确定值,故会产生一个不确定值。

3.3.6 算术操作
在这里插入图片描述
i++为运算操作,在汇编中通过add或lea实现,在程序中为:
在这里插入图片描述

3.3.7 关系操作
在这里插入图片描述
在这里插入图片描述
< , !=为关系操作,在汇编中通过cmp,test,set等实现,例如cmp a,b,通过(b-a)设置标志位,如果结果为负则SF置为1,结果为0则ZF置为1,有符号数进位则CF置为1,无符号数溢出则OF置为1(还要考虑取反的影响),再根据设置好的符号为逻辑运算后确定比较结果。
在这里插入图片描述
在这里插入图片描述

3.3.8 数组/指针/结构操作
在这里插入图片描述
argv数组是shell由命令行参数构造出的,传递给main函数的第二个参数,具体在栈中的内存映像见3.3.2中的图。在汇编中,栈如下:
32(rbp)
28 i
24
20
16
12 argc
8
4
0(rsp) 指向argv

通过rbp在栈中寻找argv的首地址,由于是char *类型,故分别加8加16得到argv[1],argv[2],取内存内容后分别放入rsi和rdx,传给printf函数作为参数。
在这里插入图片描述

3.3.9 控制转移
在这里插入图片描述
在这里插入图片描述
在汇编中通过j进行控制转移,由cmp和j语句构成条件判断语句,在这个程序中,
在这里插入图片描述
在这里插入图片描述
由rbp在栈中分别找到argc和i,用cmp设置符号位后,再根据符号为进行跳转,从而实现控制流的转移。

3.3.10 函数操作
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
1.main函数
在这里插入图片描述
Main符号首先声明在.text节中,再声明为global变量,类型为函数类型。两个参数argc和argv[]由shell构造好后,传入execve作为参数,调用加载器,在之前的上下文中运行程序,故main的栈帧上方就是argc和argv[](envp[]),具体在栈中的内存映像见3.3.2中的图。
2.printf函数
在这里插入图片描述
在这里插入图片描述
第一次调用printf函数,由于只输出一个字符串,实际调用的是puts函数(更快),在汇编程序开头表明了.LC0指代第一个字符串,将它的地址放入rdi中构造好参数后,调用Puts函数。
第二次调用printf函数,分别用rdi,rsi,rdx构造好三个参数后,调用printf函数。
3.exit函数
在这里插入图片描述
exit(x)则将x作为参数放在rdi中,再控制转移调用exit函数即可
4.sleep函数

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ICS大作业--hello程序人生 的相关文章

  • LINUX 系统编程之文件IO

    文件IO 属于系统IO 是系统内核向用户空间提供的接口 直接调用内核提供的系统调用函数 头文件是unistd h 1 open char s flag mode 在fcntl h头文件种声明 函数的作用 创建或打开某个文件 最多包含三个参数

随机推荐

  • java bean对象属性复制,将一个对象的属性值赋值给另一个对象,对象之间的复制方法

    注意依赖 springframework下的复制顺序为 目标对象 新对象 import org springframework beans BeanUtils public static void main String args Inte
  • java 获取 sessionid_通过sessionid获取session方法

    使用HttpSessionListener来监听session的创建和销毁 首先创建HttpSessionListener的实现类 SessionListeners java packagecom test importjava util
  • 【详细学习Docker部署搭建高可用的MySQL集群环境】

    一 MySQL高可用集群搭建 MySQL集群搭建在实际项目中是非常必须的 接下来我们来学习通过PXC Percona XtraDB Cluster 来实现强一致性数据库集群搭建 1 1 MySQL集群搭建 1 1 1 中央仓库查找相关镜像
  • 三年级计算机考试题目及答案,三年级信息技术试题及答案.doc

    三年级信息技术试题及答案 三年级信息技术期末试题 学校 班级 姓名 分数 一 单项选择题 共10题 每小题4 共计40分 1 计算机的心脏是 显示屏 鼠标 2 输入汉字时我们需要选择输入法 是我们使用的输入法之一 它的名字叫 五笔输入法 智
  • 【刷题笔记7】LeetCode 54. 螺旋矩阵(数组模拟)

    用分享的方式成长 用有趣的眼光看世界 欢迎来到12 26 25的博客 热爱编码 算法 知识总结 不定期更新有趣 有料 有营养内容 让我们共同学习 共同进步 系列索引 刷题笔记0 系列目录索引 持续更新 推荐收藏 本题题目 LeetCode
  • NVIDIA FasterTransformer

    NVIDIA FasterTransformer NVIDIA GPU计算专家团队针对transformer推理提出了性能优化方案 FasterTransformer 截止到2022年7月 这套方案支持的模型涵盖了BERT GPT Long
  • Mybatis整合Spring -- typeAliasesPackage

    Mybatis 整合 Spring integration MapperScannerConfigurer Mybatis整合Spring 根据官方的说法 在ibatis3 也就是Mybatis3问世之前 Spring3的开发工作就已经完成
  • python时间计算 周开始第一天和结束天 通过年周计算

    python def year mon for check year week 通过年周获取当前月 按每周最后一天的月份比对 最后一天为周日 end year week str year str week 0 end week result
  • xss入门闯关详解6-10关

    继续进行6 10关 第6关 简单的尝试之后发现闭合掉了 尝试空格或者大小写 tab绕过 大小写成功绕过 Onclick alert 1 第七关 老样子 value gt click alert 1 gt value gt lt gt ale
  • 取消idm下载器和google浏览器的关联(让谷歌浏览器禁止使用idm插件)

    https jingyan baidu com article 597035529ae46b8fc107405d html IDM下载安装成功之后 会自动默认关联你电脑上的所有浏览器 在使用浏览器下载的时候自动会变成IDM下载 如果不想让I
  • 2018-2019-2 网络对抗技术 20165335 Exp2 后门原理与实践

    一 基础问题回答 1 例举你能想到的一个后门进入到你系统中的可能方式 钓鱼网站 搞一个假网站 假淘宝 盗版电影 文库下载文档什么的 下载东西的时候把带隐藏的后门程序附带下载进去 自启动 反弹连接 搞一个小网站 用iframe标签跳转到危险网
  • 自动化测试工具Parasoft c++ test v2021.1全新发布,简化嵌入式测试

    随着Parasoft C C test 2021 1的发布 嵌入式测试和开发团队获得了现代高度自动化CI CD管道的速度和效率 最新版本为团队提供了完全集成的静态和单元测试 以实现持续合规性和质量的交付 新版本继续全面支持最新的合规标准 包
  • 几种查找的时间复杂度

    1 顺序查找 1 最好情况 要查找的第一个就是 时间复杂度为 O 1 2 最坏情况 最后一个是要查找的元素 时间复杂度未 O n 3 平均情况下就是 n 1 2 所以总的来说时间复杂度为 O n 2 二分查找 O log2n gt log以
  • 在Ubuntu上编译安装LLVM

    章节索引 Motivation 环境 Git 下载LLVM源码 CMake 编译 安装 文件链接 验证 后记 Motivation 两周前实验室要求我配置一个叫Speedy js的编译器 配置这个编译器需要先配置好LLVM 根据这个编译器作
  • Unity 流程控制

    异步函数 Invoke 被调用的方法不是立刻执行 而是过一段时间后才执行 注 Invoke是不能接受有参数的方法的 Invoke是受Time timeScale的影响 所以当Time timeScale 0 的时候 Invoke是无效的 因
  • python测试url是否可访问,网站是否连通的方法

    目录 前言 1 requests库 1 1 传参 1 2 响应内容 2 python web 前言 一般这种方法用在校验 比如 前端界面传回后端的url 如果返回值不是200 不保存其值 调用的接口不通 直接返回非200 爬虫网站 验证ur
  • C# Dictionary用法总结

    1 常规用法 增加键值对之前需要判断是否存在该键 如果已经存在该键而且不判断 将抛出异常 所以这样每次都要进行判断 很麻烦 在备注里使用了一个扩展方法 public static void DicSample1 Dictionary
  • 【今日CV 计算机视觉论文速览 第111期】Fri, 3 May 2019

    今日CS CV 计算机视觉论文速览 Fri 3 May 2019 Totally 29 papers 上期速览 更多精彩请移步主页 Interesting Single Image Portrait Relighting单图肖像光照重建 本
  • 【Java基础】使用HashMap和For循环查找数据并且统计耗费时长

    准备一个ArrayList其中存放3000000 三百万个 Hero对象 其名称是随机的 格式是hero 4位随机数 hero 3229 hero 6232 hero 9365 因为总数很大 所以几乎每种都有重复 把名字叫做 hero 55
  • ICS大作业--hello程序人生

    摘 要 Hello是每个程序员第一个接触的程序 在本文中利用计算机系统所学的知识 基于Linux平台 通过gcc objdump gdb edb等工具 从c源程序的预处理开始 跟踪分析程序编译 汇编 链接 进程管理 存储管理 I O管理整个