程序人生csapp大作业

打印 上一主题 下一主题

主题 563|帖子 563|积分 1689






 
盘算机系统


盘算机系统


大作业



题     目  程序人生-Hellos P2P
专       业  盘算机与科学技能      
学     号  2021110669            
班   级  2103101               
学       生  陈欣然                
指 导 教 师  刘宏伟                 






盘算机科学与技能学院

2022年5月

摘  要

本文将周游hello程序的一生,即hello是如何生成,运行及最终被回收的。我们将具体地先容hello.c的预处置惩罚,编译,汇编,链接过程,以及lunix下的进程管理,进而深入了解盘算机系统的奥秘。

关键词:hello;预处置惩罚;编译;汇编;链接;进程管理;lunix








目  录


第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本章小结

第7章 hello的存储管理

7.1 hello的存储器地址空间

7.2 Intel逻辑地址到线性地址的变更-段式管理

7.3 Hello的线性地址到物理地址的变更-页式管理

7.4 TLB与四级页表支持下的VA到PA的变更

7.5 三级Cache支持下的物理内存访问

7.6 hello进程fork时的内存映射

7.7 hello进程execve时的内存映射

7.8 缺页故障与缺页中断处置惩罚

7.9动态存储分配管理

7.10本章小结

第8章 hello的IO管理

8.1 Linux的IO设备管理方法

8.2 简述Unix IO接口及其函数

8.3 printf的实现分析

8.4 getchar的实现分析

8.5本章小结

结论

附件

参考文献



第1章 概述

1.1 Hello简介

P2P:From Program to Process
hello.c最初是通过编译器输入的一段程序代码,即Program。此时hello.c是一个文本文件。然后,hello.c通过预处置惩罚(cpp)、编译(ccl)、汇编(as)、链接(ld)最终成为可执目标程序hello。当我们在shell中输入./hello后,内核调用fork()函数产生子进程,并且在子进程中调用execeve,实行hello,并且分给它时间片,它就成为了一个进程(Process)。
020:From Zero-0 to Zero-0

  • from 0
最开始,内存中没有hello文件,这便是“From 0”。但是程序员编写了hello.c文件,创造了hello.c。

  • to 0
hello.c经过预处置惩罚、编译、的汇编、链接的流程,生成了可执目标程序hello。通过在Shell下输入命令,内核调用execve函数,系统会将hello文件载入内存,实行代码,当程序运行竣事后, hello进程被回收,并由内核删除hello相关数据,这即为“to 0”。
1.2 环境与工具

列出你为编写本论文,折腾Hello的整个过程中,使用的软硬件环境,以及开发与调试工具。
硬件环境:X64 CPU;2GHz;2G RAM;256GHD Disk
软件环境:Windows10;Vmware 11;Ubuntu 16.04 LTS 64位
调试工具:gcc,vim,edb,gdbhello.c:源程序(文本文件)
1.3 中心效果



hello.c:源程序(文本文件)
hello.i:预处置惩罚后的文本文件(文本文件)
hello.s:编译后汇编程序文本文件(文本文件)
hello.o:汇编后的可重定位目标程序(二进制文件)
hello:链接后的可实行目标文件(二进制文件)


1.4 本章小结

本章重要先容了hello的p2p和020的过程和程序实行时的中心效果。


第2章 预处置惩罚

2.1 预处置惩罚的概念与作用

预处置惩罚的概念:
预处置惩罚(预编译),是预处置惩罚器(cpp)以字符#开头的命令,修改原始的C程序,最终生成.i文件的过程。

预处置惩罚的作用:
预处置惩罚的重要作用是将头文件中的内容插入(“include”格式包含的文件)到源文件中和根据宏定义在源程序中举行替换(用“#define”定义的字符串)和删除(注释和空缺字符),根据“#if”后面的条件决定需要编译的部分。

2.2在Ubuntu下预处置惩罚的命令

gcc -E hello.c -o hello.i

 

2.3 Hello的预处置惩罚效果剖析

用vscode检察hello.i的信息,发现在hello.i文件中把include格式包含的文件复制到了main函数之前,并且注释内容已经被删除。

此为hello.c文件:

 

此为hello.i文件:

 

2.4 本章小结

本章先容了预处置惩罚阶段的概念和作用,在Ubuntu下对hello.c程序举行了预处置惩罚,并且表明白预处置惩罚的效果,探究了预处置惩罚阶段的机制。

第3章 编译


3.1 编译的概念与作用

编译的概念:编译器(ccl)将预处置惩罚后的文本文件.i文件(hello.i)翻译成文本文件.s文件(hello.s)。
编译的作用:把高级语言程序翻译成便于机器明白的低级机器指令。同时,在编译时,一些操作可以被简化。   
3.2 在Ubuntu下编译的命令

gcc -S hello.i -o hello.s

 

3.3 Hello的编译效果剖析

生成的hello.s文件如下:

 

 



效果剖析:

  • 数据:
全局变量:
这两个全局变量分别是字符串"用法: Hello 学号 姓名 秒数!\n"和"Hello %s %s\n"

 

argc:存储在-20(%rbp)中

 

argv[]:地址在-32(%rbp)。

 

i:放在-4(%rbp)中(堆栈里)在每次循环中更新。



  • 赋值:
hello.c中的i=0,对应于hello.s中的部分是:

 使用movl,把0移动到i处。


  • 算数操作:
 hello.c中的i++,对应于hello.s的部分是:

 使用addl,实现i的自增。


  • 关系操作:
hello.c中的argc!=4的判断对应于hello.s的部分是:
 
假如相称,就跳转到L2
hello.c中的i<9,对应于hello.s的部分是:

 假如小于等于8,就跳转到L,即:假如大于9,就退出循环。


  • 数组/指针/结构操作:
argc[]通过首地址+偏移量访问
此处addq $16,%rax是argc[2]
addq $8,%rax是argc[1]
addq $24,%rax是argc[3]

 


  • 控制转移:
if(argc!=4)对应hello.s中的

 

假如argc不等于4,就跳转到L2
for(i=0;i<9;i++)对应hello.s中的

 

使用cmpl举行判断,假如i小于等于8(i<9),用jle跳转,否则,退出循环。


  • 函数操作:
7.1main函数
参数传递:
参数argc存储在%rdi;argv[]存储在%rsi。

 

函数返回:
return 0对应着.s文件中
将存储返回值的寄存器%eax赋值为0,然后再返回。

 

7.2 printf("用法: Hello 学号 姓名 秒数!\n");(printf("Hello %s %s\n",argv[1],argv[2]);类似)
参数传递:把.LCO的地址传递到%rdi


函数调用:使用call指令。
 
7.3exit(1)
参数传递:把1通过movl指令传递给%edi

 

函数调用:使用call指令。
7.4sleep(atoi(argv[3]));
 
参数传递:将atoi的返回值传入%rdi中

函数调用:使用call指令。
7.5atoi(argv[3])
参数传递:将%rax中的值传入%rdi中
函数调用:使用call指令。
函数返回:返回值被传入sleep函数中

 

7.6 getchar();


 
函数调用:使用call指令。
3.4 本章小结

本章先容了编译的概念与作用。我们将hello.i编译成hello.s,并且对其举行数据、赋值、类型转换(隐式或显式) 、sizeof、算术操作、逻辑/位操作、关系操作、控制转移、函数操作等方面的分析,具体地了解了编译的过程。

第4章 汇编

4.1 汇编的概念与作用

(1)概念:汇编是汇编器(as)将.s文件(文本文件)翻译成.o文件(二进制文件)。
(2)作用:汇编将汇编代码翻译成机器可以明白并且实行的语言。
注意:这儿的汇编是指从 .s 到 .o 即编译后的文件到生成机器语言二进制程序的过程。
4.2 在Ubuntu下汇编的命令

gcc hello.s -c -o hello.o


 
4.3 可重定位目标elf格式

指令:readelf -a hello.o >helloref.txt


得到的helloref.txt如下:

 


分析:
ELF头:

 


节头:
 


程序头:无

 

重定位节:


 

4.4 Hello.o的效果剖析

指令:objdump -d -r hello.o  


 

 

区别1:
数据:十进制数->16进制数。
区别2:
函数调用:hello.s仅仅是使用call指令,call +函数名。hello.s的符号用于重定位的部分信息被放到了表内里。
区别3:
全局变量:hello.s是将全局变量值直接赋给寄存器(使用$.LC0、$.LC1给%edi赋值)但是在反汇编代码中,将可重定位文件重定位之后盘算出全局变量的地址,赋值给寄存器。
区别4:
分支转移:hello.s中的跳转指令跳转到代码中的某一个部分。而反汇编中的跳转指令是直接跳转到具体的地址地址。
4.5 本章小结

本章中,我们对hello.s举行了汇编得到hello.o文件,hello.o的ELF可重定位目标文件hello_o_elf.txt,和反汇编hello.o得到hello_o.objdump文件。通过对hello_o_elf.txt和对hello_o.objdump的分析,并且将hello_o.objdump与hello.s对比分析,深入地探究了汇编的过程。


第5章 链接


5.1 链接的概念与作用

链接是指将一个或多个由编译器或汇编器生成的目标文件外加库链接为一个可实行文件,也就是从.o文件到可实行文件的过程。目标文件是包括机器码和链接器可用信息的程序模块。
(2)作用:
链接器可以剖析未定义的符号引用,将目标文件中的占位符替换为符号的地址,以及完成程序中各目标文件的地址空间的构造。
链接器使得分离编译成为大概,也就是把大型的应用程序分解为更小、更好管理的模块,可以独立地修改和编译。当我们改变这些模块中的一个时,只需简单地重新编译它,并重新链策应用,而不必重新编译其他文件。
注意:这儿的链接是指从 hello.o 到hello生成过程。
5.2 在Ubuntu下链接的命令


命令:ld -o hello -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o hello.o /usr/lib/x86_64-linux-gnu/libc.so /usr/lib/x86_64-linux-gnu/crtn.o

 

5.3 可实行目标文件hello的格式

  命令:readelf -a hello > hello1.elf

 

ELF头:

 

节头:


 
 

程序头:


 
 


Dynamic section:在偏移量为0x2e50的位置,包含21个条目。它是可实行文件新增的内容。
 

 

重定位节:可实行文件依然存在重定位节,原因是动态链接时还会需要重定位信息。

 

符号表:符号表有51个条目。



 

 


5.4 hello的假造地址空间

程序在0x400000~0x401000段中载入。并且从0x400000开始,顺序与hello的elf格式文件顺序相同。
   

 



5.5 链接的重定位过程分析

指令:objdump -d -r hello
hello与hello.o对比来看基本相同。区别是hello是CPU直接访问的假造地址,而hello.o是相对偏移。因为重定位的一个过程是链接器修改代码节和数据节中对每个符号的引用,使得它们指向正确的运行时地址。

 







 



5.6 hello的实行流程

使用edb实行hello,调用与跳转的各个子程序名字如下:
ld-2.29.so!_dl_start
ld-2.29.so!_dl_init
Hello!_start
libc-2.29.so!__libc_start_main
Hello!main
Hello!printf@plt
hello!atoi@plt
Hello!sleep@plt
hello!getchar@plt
libc-2.29.so!exit
5.7 Hello的动态链接分析

GOT[1]保存的是指向已经加载的共享库的链表地址。GOT[2]是动态链接器在ld-linux.so模块中的入口。在程序实行时,使用过程链接表PLT和全局偏移量表GOT举行动态链接。GOT采用耽误绑定的战略。GOT中保存着下一条指令的地址。dl_init实行后,通过重定位确定函数地址。

检察hello_elf.txt文件可以得到GOT的起始位置为0x403ff0。再用edb检察.got的内容。

 

调用dl_init前:

 

调用dl_init后:

 



比力可以得知,0x403ff0之后的内容发生了变化,即全局偏移量表GOT[1]和GOT[2]的内容发生了变化。
5.8 本章小结

在这一章中,我们先容了链接的过程。以hello.o链接静态库形成hello可实行文件为例,对hello可实行文件的格式举行分析、hello的假造地址空间,hello的可重定位的过程、hello的动态链接分析。


6hello进程管理


6.1 进程的概念与作用

进程的概念:进程的经典定义是一个实行中程序的实例。系统的每个程序都运行在某个进程的上下文中,上下文是由程序正确运行所需的状态构成的。包括存放在内存中的程序的代码和数据,它的栈、通用目的寄存器的内容、程序计数器、环境变量以及打开文件描述符的聚集。
进程的作用:进程提供程序独占地使用处置惩罚器并且可以独占内存的假象。每次用户通过想shell输入一个可实行目标文件的名字,运行程序是,shell会创建一个新的进程,然后再这个新进程的上下文中运行这个可实行目标文件。应用程序课可以或许创建新进程,并且在这个新进程的上下文中云心它们自己的代码大概其他应用程序。
6.2 简述壳Shell-bash的作用与处置惩罚流程

Shell-bash是一个lunix下的交互型的应用级程序,用户可以通过这个界面访问操作系统的内核,为用户与内核之间提供了一个交互的界面。
Shell的处置惩罚流程:

  • 从命令行中读取用户输入
  • 剖析命令行,查抄第一个参数是否是一个内置的shel命令。   

    • 假如是内置命令,立即表明
    • 假如不是,创建子进程,实行该程序。

    3、如多参数的末了为&,shell不会等待程序竣事;否则,shell会调用waitpid()函数来等待前台作业的竣事。


6.3 Hello的fork进程创建过程

在命令行输入./hello 2021110669  chenxinran 1 后,shell查抄该命令是否为内置命令。因为这个命令不是一个内置命令,shell调用fork函数创建一个新的子进程,子进程得到与父进程用户级假造地址空间相同的一份副本,但是PID不同。
6.4 Hello的execve过程

调用函数fork创建新的子进程之后,子进程会调用execve函数,加载并运行可实行目标文件hello,且带参数列表argv和环境变量列表envp。只有出现错误时,例如找不到hello时,execve才会返回到调用程序。Execve调用一次且从不返回。首先,它加载可实行文件并举行可实行性查抄,在当前的进程中删除当前进程中现有的假造内存段,并将堆栈初始化为0,将新的代码和数据段初始化为可实行文件的内容,跳转到_start的地址,末了举行控制传递。在CPU开始引用被映射的假造页的时间,内核才会将需要用到的数据从磁盘中放入内存中。
6.5 Hello的进程实行

首先明白一些概念:
内核模式:进程可以访问任何内存,调用任何指令。
进程从用户模式变为内核模式的方法:通过中断、故障等异常的调用。
上下文:内核为每一个进程维持一个上下文,上下文就是内核重新启动一个被抢占的进程所需的状态。
内核调理进程的机制:上下文切换。
在hello程序实行时,会有其他进程并发地运行。
时间片:一个进程实行它的控制流的一部分的每一时间段叫做时间片。
接下来具体分析一下hello的进程实行流程:
(1)hello起初初始用户模式,继承运行调用printf函数,进程从用户模式变成内核模式(由于系统调用)。
(2)在printf函数实行完之后又返回到用户模式。继承运行调用sleep函数,内核举行上下文切换,调用其他进程运行,同时计数器记载休眠的时间。因为参数为1,所以内核中的计时器计到1s时,系统发生中断转换到hello进程原先运行的位置,将之前挂起的进程放到运行队列中继承实行。
(3)循环中,hello进程会多次举行用户模式和内核模式的转变。
(4)之后调用getchar函数,进入内核模式,再举行上下文切换,运行别的进程,当数据传输竣事,发生中断,回到hello进程,末了返回,hello进程运行终止。

6.6 hello的异常与信号处置惩罚


(1)中断(异步)
中断是来自处置惩罚器外部的I/O设备的信号的效果,中断处置惩罚程序运行之后,返回到下一条指令。
(2)陷阱(同步)
陷阱是有意的异常,是实行一条指令的效果,它总是返回到下一条指令。
(3)故障(同步)
故障是由错误环境引起的,当故障发生时,是利器将控制转移给故障处置惩罚程序,假如错误环境可以修正,则将控制返回到引起故障指令,重新实行,否则处置惩罚程序返回到内核abort,终止故障的应用程序。
(4)终止(同步)
终止是不可规复的致命错误造成的效果,会终止应用程序,不会返回。
空格:进程不会被打断。

 



回车:进程被回收。

 

Ctrl+c:进程接收到SIGNIT信号,终止并回收hello进程。

 

Ctrl+z:进程收到SIGSTP信号在屏幕上显示提示信息并挂起hello进程。

 


使用ps可以检察进程的基本信息,如:PID、TTY、TIME、CMD。

 


使用jobs:检察进程状态,此时为suspended。

 

使用pstree:可以检察进程树。

 

使用fg:重新运行



Kill:向进程发送一个信号。

 

6.7本章小结

在这一章中,我们先容了hello的进程管理。首先我们先容了进程的概念和应用,然后我们先容了shell-bash的作用与处置惩罚流程,shell的fork进程创建过程和execve过程,hello的实行,hello的异常与信号处置惩罚。特殊地,对于hello的异常和信号处置惩罚,我们通过在命令行中演示,具体呈现hello的异常和信号处置惩罚机制。


7hello的存储管理


7.1 hello的存储器地址空间

7.2 Intel逻辑地址到线性地址的变更-段式管理

7.3 Hello的线性地址到物理地址的变更-页式管理

7.4 TLB与四级页表支持下的VA到PA的变更

7.5 三级Cache支持下的物理内存访问

7.6 hello进程fork时的内存映射

7.7 hello进程execve时的内存映射

7.8 缺页故障与缺页中断处置惩罚

7.9动态存储分配管理

7.10本章小结



8hello的IO管理


8.1 Linux的IO设备管理方法

设备的模型化:文件
设备管理:unix io接口
8.2 简述Unix IO接口及其函数

8.3 printf的实现分析

从vsprintf生成显示信息,到write系统函数,到陷阱-系统调用 int 0x80或syscall等.
字符显示驱动子程序:从ASCII到字模库到显示vram(存储每一个点的RGB颜色信息)。
显示芯片按照刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)。
8.4 getchar的实现分析

异步异常-键盘中断的处置惩罚:键盘中断处置惩罚子程序。担当按键扫描码转成ascii码,保存到系统的键盘缓冲区。
getchar等调用read系统函数,通过系统调用读取按键ascii码,直到担当到回车键才返回。
8.5本章小结





结论

Hello的一生的过程如下:


  • 源文件:程序员编写的hello.c
  • 预处置惩罚:预处置惩罚(预编译),是预处置惩罚器(cpp)以字符#开头的命令,修改原始的C程序,最终生成hello.i文件.
  • 编译:编译器(ccl)将预处置惩罚后的文本文件hell0.i文件翻译成文本文件hello.s。
  • 汇编:汇编器(as)将hello.s文件(文本文件)翻译成hello.o文件(二进制文件)。
  • 运行:得到hello文件,并且在shell中输入命令行,传入参数。
  • 进程管理:shell调用fork函数为hello创建子进程;exceve()函数加载运行hello程序;hello与很多别的进程是并行的,当发生中断大概异常是,发生上下文切换,进入内核模式。
  • 存储管理:MMU将假造地址翻译为物理地址。
  • IO管理:hello输入输出与外界交互通过linux I/O实现。
  • Hello实行完,末了被shell回收,实现从0到0的一生。
通过对hello一生的研究,我们更好地明白了盘算机系统的原理。我以为这就是深入了解盘算机系统的“深入”地点。
附件
hello.c 源文件
hello.i:经过预处置惩罚器(cpp)以字符#开头的命令,修改原始的C程序,hell0.c最终生成hello.i文件。

hello.s:hello编译后的文件
hello.o:hello汇编后的文件
hello:hello链接之后的文件
hello1.elf : hello文件可重定位目标elf文件
Helloref.txt: hello.o文件可重定位目标elf文件


参考文献
[1]  林来兴. 空间控制技能[M]. 北京:中国宇航出版社,1992:25-42.
[2]  辛希孟. 信息技能与信息服务国际研讨会论文集:A集[C]. 北京:中国科学出版社,1999.
[3]  赵耀东. 新期间的工业工程师[M/OL]. 台北:天下文化出版社,1998 [1998-09-26]. http://www.ie.nthu.edu.tw/info/ie.newie.htm(Big5).
[4]  谌颖. 空间交会控制理论与方法研究[D]. 哈尔滨:哈尔滨工业大学,1992:8-13.
[5]  KANAMORI H. Shaking Without Quaking[J]. Science,1998,279(5359):2063-2064.
[6]  CHRISTINE M. Plant Physiology: Plant Biology in the Genome Era[J/OL]. Science,1998,281:331-332[1998-09-23]. http://www.sciencemag.org/cgi/ collection/anatmorp.


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

三尺非寒

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表