雁过留声 发表于 2024-7-27 10:25:06

HITiCS大作业——程序人生



https://i-blog.csdnimg.cn/blog_migrate/8a3f224127b80c53c8d100a49a776a5a.png
 

计算机系统

大作业


题     目  程序人生-Hello’s P2P 
专       业     计算机科学与技术     
学     号     2021112155        
班   级      2103103           
学       生      谷佳熠     
指 导 教 师      刘宏伟        






计算机科学与技术学院
2022年11月
摘  要
本篇文章具体的论述了hello的程序人生,从预处理,汇编,编译,链接,到进入shell执行的全过程,并论述了其中的细节信息,使用gdb和edb等程序进行了一些深入的分析,让我对计算机系统课程的知识有更好的掌握。
关键词:预处理;汇编;编译;链接;进程管理                            








目  录

第1章 概述
1.1 Hello简介
1.2 环境与工具
1.3 中央结果
1.4 本章小结
第2章 预处理
2.1 预处理的概念与作用
2.2在Ubuntu下预处理的命令
2.3 Hello的预处理结果剖析
2.4 本章小结
第3章 编译
3.1 编译的概念与作用
3.2 在Ubuntu下编译的命令
3.3 Hello的编译结果剖析
3.4 本章小结
第4章 汇编
4.1 汇编的概念与作用
4.2 在Ubuntu下汇编的命令
4.3 可重定位目标elf格式
4.4 Hello.o的结果剖析
4.5 本章小结
第5章 链接
5.1 链接的概念与作用
5.2 在Ubuntu下链接的命令
5.3 可执行目标文件hello的格式
5.4 hello的假造地点空间
5.5 链接的重定位过程分析
5.6 hello的执行流程
5.7 Hello的动态链接分析
5.8 本章小结
第6章 hello进程管理
6.1 进程的概念与作用
6.2 简述壳Shell-bash的作用与处理流程
6.3 Hello的fork进程创建过程
6.4 Hello的execve过程
6.5 Hello的进程执行
6.6 hello的非常与信号处理
6.7本章小结
结论
附件
参考文献


第1章 概述

1.1 Hello简介

P2p:hello.c颠末预处理器cpp,汇编器cc1,编译器as,链接器ld,先从hello.c酿成修改后的C代码,hello.i;之后酿成汇编代码hello.s;继续进行编译,得到可重定位目标文件hello.o。最后颠末链接器得到可执行目标文件Hello。
020:shell的子进程hello通过函数execve执行颠末非常、信号、假造内存管理等等步骤,最终运行结束,被父进程采取,hello的运行结束。
1.2 环境与工具

软件环境:Windows10,VWmare Tolls,Ubuntu假造机,edb和gdb
硬件环境:ASUS个人笔记本
1.3 中央结果

hello.i:修改过后的C代码,剖析#指令。
hello.s:hello的汇编代码,可以把hello.i酿成汇编语言。
hello.o:可重定位目标文件:可以把hello.s变为二进制文件。
hello:可执行目标文件,用来执行
1.4 本章小结

本章介绍了我完本钱次作业的工具信息,也是hello程序人生的开始。


第2章 预处理

2.1 预处理的概念与作用

预处理阶段,由预处理器cpp根据以字符#开头的命令,修改原始的C程序。如把#include<stdio.h>直接插入到程序文本中,大概替换程序中的#define宏定义。最后得到的是另外一个C程序,一样寻常以.i为后缀。
作用:修改#include,替换#define,确定执行条件#ifndef
2.2在Ubuntu下预处理的命令

https://i-blog.csdnimg.cn/blog_migrate/75edaa978c26c6ae037a56f270a6d09b.png 
图2.2.1 生成预处理文件hello.i的指令
上图为生成预处理文件hello.i的命令
2.3 Hello的预处理结果剖析

hello.i的部分代码如下图所示
https://i-blog.csdnimg.cn/blog_migrate/6a7667a68681e4182c795e56cf1e126e.png 
图2.3.1 hello.i的部分代码
此处完成了对#include<stdio.h>的展开,插入了很多行代码
2.4 本章小结

预处理是程序处理#代码的过程,本章剖析了预处理的过程和原理。预处理是hello程序人生的第一步


第3章 编译

3.1 编译的概念与作用

编译阶段,由编译器ccl将文本文件hello.i编译成hello.s。得到的是一个汇编程序,以.s为后缀
作用:生成汇编程序,进行一些编译器优化与语法分析。
3.2 在Ubuntu下编译的命令

https://i-blog.csdnimg.cn/blog_migrate/d1a54c1c942a6508146a19282929c09b.png 
图3.2.1 生成hello.s的指令
3.3 Hello的编译结果剖析

https://i-blog.csdnimg.cn/blog_migrate/b974e5f2325c60d77c133a4a257667e3.png 
图3.3.1 hello.s的内容
此部分中有.file表示文件名是hello.c,.text表示代码段,.section和.rodata表示只读数据段,其中.rodata包罗格式串跳转表等。.align段存有对数据和指令的地点的对齐要求。.string包罗字符串范例的数据,每3位对应一个UTF-8编码的汉字,以及另外一段字符串。.global表示全局变量或函数,对应于其中的main。.type包罗函数和对象,是符号。
https://i-blog.csdnimg.cn/blog_migrate/4bd688d8fbfe01aed5597d279cbc77aa.png
图3.3.2 hello.s的内容
https://i-blog.csdnimg.cn/blog_migrate/0ef90e0fa156a4fe51b9300fb72161de.png
图3.3.3 hello.s的内容
数据:在hello.c中使用了三种数据,int型的argc和i,char*字符串型的argv和其他的字符串,以及一个数组,即为argv。Argc是main函数的第一个参数,剖析程序中的movl %edi, -20(%rbp)可知,%rdi中的内容作为第一个参数,赋给argc并被存放在-20(%rbp)中,直接引用即可。局部变量i被生存在栈地点-4(%rbp)中。其它常量被生存在.text节中。*argv是命令行参数,来自于键盘I/O设备输入。引用是通过其中的代码movq (%rax) %rax引用。对于数组的每个字符串元素已经在前文中剖析。其它字符串则存放在.string和.rodata段
赋值:对argv的赋值通过I/O进行并存储于(%rax)。
范例转换:通过调用函数atoi函数将字符串范例转换为整数范例。对应指令为call atoi@plt
算术操纵:此程序中绝大多数的算术操纵均被用来对栈进行操纵,其他则是用来在调用中使用,如addq $16,%rax。
逻辑和关系操纵:此程序中险些没有此类操纵,主要的用处使用在跳转,如jle .L4
数组/指针/结构操纵:*argv是命令行参数,来自于键盘I/O设备输入。通过间接寻址的处理。指针处理主要是针对栈指针,如sub $32,%rsp。
控制转移:.L3是一个循环,用-4(%rbp)和8对比控制跳出条件,把循环用跳转表示了。其它控制大多是是使用比力决定跳转。如.L2的内容。
函数操纵:程序hello中使用了printf/exit/sleep/getchar/puts/main等多种函数。调用方式比力类似,均是call。其中sleep执行之前把%rax传给%edi作为第一个参数。
3.4 本章小结

本章节比力具体的论述了编译的过程和其中的符号寄义,表现了很多hello.s的信息。汇编是hello程序人生的第二步。

第4章 汇编

4.1 汇编的概念与作用

汇编阶段,由汇编器as将汇编程序汇编成可重定位目标文件
作用:将文本文件转换二进制文件,即翻译成机器语言程序,并且使得生成的文件可以被重定位。
4.2 在Ubuntu下汇编的命令

https://i-blog.csdnimg.cn/blog_migrate/e1227688c4ef412431f5ace34b70b9f0.png 
图4.2.1 生成hello.o的指令
4.3 可重定位目标elf格式

分析hello.o的ELF格式,用readelf等列出其各节的根本信息,特别是重定位项目分析。
https://i-blog.csdnimg.cn/blog_migrate/a61c7b37b4d2d8fd29d1e56090a56389.png 
图4.3.1 hello.o的elf节
开头为一个16字节数据,分别是ELF字长、字节序、文件版本等等
https://i-blog.csdnimg.cn/blog_migrate/336f5bf19c4e899c1a2862138956e887.png 
图4.3.2 hello.o的其他节信息
.text节,存放已编译程序的机器代码。
.data节,存放已初始化的全局和静态C变量
.bss节,是未初始化的全局和静态C变量,不占用真正的空间
.rodata节,只读数据,比如这段程序中printf里的格式串和跳转表
.symtab节,是一个符号表,存放在程序中定义和引用的函数和全局变量的信息。
.strtab节,是一个包罗.symtab和.debug节的符号表以及节头部表的节名字
节头部表,包罗节名称,节的范例,节的属性(读写权限),节在ELF文件中所占的长度以及节的对齐方式和偏移量。
4.4 Hello.o的结果剖析

https://i-blog.csdnimg.cn/blog_migrate/2f44531c4e857c59a3e5a4e85139be2a.png 
图4.4.1 hello.o的反汇编内容
https://i-blog.csdnimg.cn/blog_migrate/6f912fc5dcf00183085a1ca8d9cce714.png 
图4.4.2 hello.o的反汇编内容
objdump -d -r hello.o  分析hello.o的反汇编,并请与第3章的 hello.s进行对照分析。
机器语言由二进制数构成,每条汇编语言对应一条汇编语言
Hello.o由于尚未重定位,因此函数调用call不直接对应地点,而是对应main+偏移地点的形式。此外,对于全局变量,hello.o的反汇编结果没有具体地点,而是被存放在.rela.text中的重定位信息中。
对于分支转移,hello.s直接通过.L1.L2等地点进行转移,反汇编直接通过jmp语句到段名称来转移。
4.5 本章小结

本章通过展示汇编的结果和概念,并且展示出来其中的内容,显示了可重定位目标文件,表现了很多可重定位目标文件的具体信息。汇编是hello程序人生的第三步。

第5章 链接

5.1 链接的概念与作用

链接阶段,由链接器ld将一些.o文件和动态库静态库链接,从可重定位目标文件生成一个可执行目标文件,可以被加载到内存中由系统执行。
5.2 在Ubuntu下链接的命令

https://i-blog.csdnimg.cn/blog_migrate/d988e7e0caeb0fc00d41eb51ca2bf0e3.png 
图5.2.1 生成hello可执行程序的指令
5.3 可执行目标文件hello的格式

https://i-blog.csdnimg.cn/blog_migrate/5fa32de8ba0520c6d7eb5da4972402bf.png 
图5.3.1 hello的elf节

  开头为一个16字节数据,分别是ELF字长、字节序、文件版本等等
https://i-blog.csdnimg.cn/blog_migrate/f8c7e140931620adc4101b1cd255b444.png 
图5.3.2 hello的其它节信息
5.4 hello的假造地点空间

https://i-blog.csdnimg.cn/blog_migrate/35199fe36cc55cee35916019c54facfd.png 
图5.4.1 hello的假造地点空间信息
使用edb可以检察到地点为401000到40404c
    使用edb加载hello,检察本进程的假造地点空间各段信息,并与5.3对照分析分析。   
5.5 链接的重定位过程分析
https://i-blog.csdnimg.cn/blog_migrate/edd6b54e05fc8e410c416c2e4b5b56a0.png


图5.5.1 反汇编生成hello3.s的指令
https://i-blog.csdnimg.cn/blog_migrate/968d5aba27a9e04ae12998cdce7b1ac7.png
图5.5.2 hello3.s的部分指令
hello得到的反汇编文件相较于原hello.o增加了很多节的信息
此外,hello中的地点是假造地点,并非实际地点
Hello中有一些外部库的代码,如printf@plt
hello中是通过间接寻址算法获取全局变量的信息。
5.6 hello的执行流程

https://i-blog.csdnimg.cn/blog_migrate/0a5a1f634f3854f6b3b45bb86589b8d3.png  
图5.6.1 hello中具体的执行流程
使用gdb设置断点的当时可以寻找到其中的每一步
5.7 Hello的动态链接分析

使用readelf -S能够查询到hello的文件信息获取got信息
https://i-blog.csdnimg.cn/blog_migrate/e3e2f7051668b5eecbb7c8ad6d9299d8.png 
图5.7.1 hello中动态链接的查询
Init前的内容如图所示
https://i-blog.csdnimg.cn/blog_migrate/c1e7f8ec0587408352fed0c28c2eee0e.png 
图5.7.2 init前的内容
Init后的内容改用edb检察,如图所示
https://i-blog.csdnimg.cn/blog_migrate/d47fe65c47fef1958156d7d712c24790.png 
图5.7.3 init后的内容
5.8 本章小结

本章具体论述了链接的过程和链接前后程序的变化,链接是hello程序人生的第四步,也是代表它成为可执行程序可以被执行的开始。


第6章 hello进程管理

6.1 进程的概念与作用

进程是一个执行中的程序实例。
作用:进程给应用程序提供一个关键抽象,其中包罗
一个独立的逻辑控制流,它提供一个假象,好像我们的程序独占地使用处理器。
一个私有的地点空间,它提供一个假象,好像我们的程序独占地使用内存系统。
6.2 简述壳Shell-bash的作用与处理流程

作用:Shell是用户与操纵系统之间完成交互式操纵的一个接口程序,它为用户提供简化了的操纵。而NU组织又进一步开发Borne Again Shell,简称bash,它是Linux系统中默认的shell程序。
处理流程:(1)将用户输入的命令行进行剖析,分析是否是内置命令;
(2)若是内置命令,直接执行;若不是内置命令,则bash在初始子进程的上下文中加载和运行它。
6.3 Hello的fork进程创建过程

Shell本身就是一个进程,当它运行指令./hello时,相称于fork了一个hello子进程。
二者并发执行,并且使用了相同但是独立的地点空间,并且共享stdin和stdout文件。二者的最大差别在于PID不同。
6.4 Hexecve函数在当进步程的上下文加载并运行可执行目标文件Helloello的execve过程

execve函数在当进步程的上下文加载并运行可执行目标文件Hello,在execve加载了Hello之后,它调用启动代码。启动代码设置栈,并将控制传递给新程序的主函数,这个主函数带有环境变量envp。
6.5 Hello的进程执行

进程的上下文信息包罗通用目标寄存器、浮点寄存器、程序计数器、用户栈、状态寄存器、内核栈和各种内核数据结构。
一个进程执行他的控制流的一部分的每一个时间段叫做时间片。
在进程执行的过程中,内核可以决定抢占当进步程,并且规复一个之前被抢占的进程,这一过程称为内核调理了此进程。
在hello的程序人生中,先是由shell在用户模式执行,之后hello进程被创建,进入内核模式,调理hello进程,之后规复用户模式执行hello进程。执行结束之后触发磁盘中断,进入内核模式,由内核调理shell,再次规复用户模式。
执行过程shell和hello享有相同的时间片。
6.6 hello的非常与信号处理

非常是指控制流的突变,用来相应某种变化,分为4类。
(1)中断:异步非常,来自处理器外部的I/O设备。非常处理后会执行下一条指令;
(2)陷阱:同步非常,是执行系统调用函数的结果。函数调用结束后会执行下一条指令;
(3)故障:同步非常,由错误环境引起,如缺页,浮点非常等等。非常处理成功则重新执行该指令,否则程序终止;
(4)终止:同步非常,由致命错误造成。该非常将终止程序。
从键盘随意输入数据不影响结果输出
https://i-blog.csdnimg.cn/blog_migrate/3d83d756981800ae4aaec9fcbc5cb854.png 
图6.6.1 随意输入数据的执行结果
回车:会停止进程。
https://i-blog.csdnimg.cn/blog_migrate/a32edd25c7060424e15e90b9bdab8a09.png 
图6.6.2 使用回车停止进程的执行结果
Ctrl-Z:挂起当进步程,信号是SIGTSTP,内核选择挂起进程
https://i-blog.csdnimg.cn/blog_migrate/0f3e86d1e0a47d1b12fec6668d1c3353.png 
图6.6.3 使用Ctrl-Z挂起进程的执行结果
对应的ps检查如下
https://i-blog.csdnimg.cn/blog_migrate/8c9805d01de8ed431d52b745625d0da1.png 
图6.6.4 使用ps检查进程的执行结果
Ctrl-C:中止当进步程,信号是SIGINT,内核选择中止进程
https://i-blog.csdnimg.cn/blog_migrate/dfecdb75a45eb8e0f36e164dd0aa0fcc.png 
图6.6.5 使用Ctrl-C中止进程的执行结果
Jobs:列出当前被暂停的进程
https://i-blog.csdnimg.cn/blog_migrate/3de5f8c9ffb7958635014aed0e44bb14.png 
图6.6.6 使用Jobs列出暂停进程的执行结果
Pstree:列出各个进程的树状图
https://i-blog.csdnimg.cn/blog_migrate/57464510a697372234e0d1b11524cd1a.png 
图6.6.7 使用pstree列出进程的树状图的执行结果
fg:继续执行被挂起的进程
https://i-blog.csdnimg.cn/blog_migrate/7f47c7312b3b905e0b36d5cf73debf17.png 
图6.6.8 使用fg继续执行被挂起进程的执行结果
Kill:杀死进程,信号是SIGKILL,内核选择杀死进程
https://i-blog.csdnimg.cn/blog_migrate/48f84148fe4c779b2b03f39e064fc0cf.png 
图6.6.9 使用kill杀死进程的执行结果
6.7本章小结

本章主要介绍了四种非常和信号处理,以及非常控制流。非常和信号都是计算机运行程序的紧张概念,也是理解系统的紧张概念,照旧hello的程序人生的执行层面上的紧张环节。



























结论

Hello的程序人生始于hello.c,颠末预处理,汇编,编译,链接酿成可执行文件,在shell上被执行,起于./hello的指令,终止于shell的kill指令或结束后被shell采取
通过本次的大作业,我深刻的体会了一个程序的运行过程,对半年以来计算机系统课程学习的内容有了一个深刻的掌握。在本次大作业中,我使用了edb和gdb结合的创新之处。在二者的结合之下,能够发挥二者的最大效益。
附件

hello.c  源代码
hello.i  对#预处理指令做初步处理
hello.s  汇编代码文件
hello.o  可重定位目标程序,二进制文件
hello   可执行目标程序,可用于执行

参考文献

 大卫.R.奥哈拉伦 兰德尔.E.布赖恩特 深入理解计算机系统 北京:机械工业出版社, 2016.7
 (7条消息) Linux下 可视化 反汇编工具 EDB 根本操纵知识_hahalidaxin的博客-CSDN博客
 HIT-ICS2022大作业要求

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: HITiCS大作业——程序人生