盘算机体系大作业程序人生-Hello’s P2P

打印 上一主题 下一主题

主题 809|帖子 809|积分 2427


盘算机体系


大作业



题     目  程序人生-Hellos P2P 
专       业     人工智能领域       
学     号     2022110562         
班   级     22WL026           
学       生     吴建锋             
指 导 教 师      郑贵滨             






盘算机科学与技术学院

20245

摘  要

hello程序作为每个人接触的第一个程序,简朴的几条语句背后是整个盘算机体系协同工作的效果。从平凡的01串到屏幕上输出的效果,程序必要颠末编译、汇编、链接、创建进程、内存分配、IO管理等多个过程。本文将从hello程序实现的过程分析各个过程里盘算机体系的工作原理与实现途径,领会人类智慧的结晶。
关键词:盘算机体系;汇编;链接;hello程序                            

(摘要0分,缺失-1分,根据内容精彩称都酌情加分0-1分








目  录


第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简介

Hello World!
这个几乎每个程序员最开始踏上码农道路所实现的第一个程序,我们曾为这简简朴单的一句话欣喜若狂,标志了我们开创了一个新的天下,而且拥有掌握这个天下的能力。但小小的hello.c的运行并不天马行空,在我们看不见的背后隐蔽了盘算机体系的所有奥秘。
从hello.c(Program)到盘算机实行的程序(Process),一样平常由编译器驱动程序完成,将原文件转变为可实行文件。这个从无到有的过程开创天下的过程主要可分为五个步骤:完善规则、解释规则、打造基石、九九归一。
首先是完善规则:就像是“神说要有光!”但很显着除了光天下上还有很多事物神没有直说,hello.c文件也一样那个printf只是你对这个程序的‘多余’要求,而其他要素便在#开头的命令中,以是第一步便是直接将#命令修改为C语言命令,这个过程叫预编译(cpp),产生hello.i文件。
其次是解释规则:作为一个神、你现在使用的天下制造机(CPU)并不是那么智能,你说的话它无法直接明白,以是你只能先将你的想法转换为它所能识别的语言(汇编语言)再喂给这个笨呆板。而这个过程就是编译,产生编译代码文件hello.s。
然后在打造基石这一过程,那个笨呆板终于可以进行工作了,他们根据你的汇编指令转化为这个天下的真实规则,如将太阳点亮。而这些真实规则便是呆板语言,是最终呆板识别并实行的语言,而这一步就是汇编,并将呆板指令生存在hello.o文件中。
最后便是九九归一,形成一个新的天下。你创造的点亮太阳的指令,和一代代老创世神所积累的基石按照肯定链接联系到一起,这个时间你才能真正看见这个天下。而与程序来说,这便是链接。将有关的目标文件彼此相连接,使得所有的目标文件成为一个可以大概被操作体系载入实行的同一团体,即hello。
到此为止,天下设计或者说目标文件hello诞生了,这便是这一小条语句背后的完备秘密,这就是p2p (From Program to Process)。
当然这个程序实行的过程中也存在着内存干系操作,首先将程序代码存入内存中,而后在shell的子进程映射假造内存,在处置惩罚器等操作下运行到代码竣事,回收进程,删除内存中的干系代码以及数据,一切清零。这个过程就是hello的020(From Zero-0 to Zero-0)过程。
1.2 情况与工具

1.2.1 硬件情况

Windows体系:

图1.2.1

Linux体系:

图1.2.2

1.2.2 软件情况


图1.2.3
1.2.3 开发工具

Visual Studio 2022
1.3 中间效果

hello.i: ASCII码的中间文件(预处置惩罚器产生),用于分析预处置惩罚过程。

hello.s: ASCII汇编语言文件(预处置惩罚器产生),用于分析编译的过程。

hello.o:可重定位目标程序(汇编器产生),用于分析汇编的过程。

hello:可实行目标文件(链接器产生),用于分析链接的过程。

hello.txt:hello可实行文件反汇编文件。

dump.s:hello.o反汇编文件。

ELF.txt:hello可实行文件ELF头。

1.4 本章小结

在第一章中主要报告Hello程序过程的扼要概述,基本简述后续章节的内容。其次先容本次程序人生的情况与工具,与中间效果文件及其作用。

(第1章0.5分)

第2章 预处置惩罚

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

预处置惩罚也称预编译,是c语言编译器在对源代码编译之前,将其中的伪指令进行处置惩罚,进而得到.i结尾的c语言文件,其本质上仍为高级语言文件,可以较轻松地阅读与明白。
预处置惩罚的主要作用包罗下面3种范例:

  • 将所有的#define删除,而且睁开所有宏定义;
  • 处置惩罚条件编译指令,如:#if、#elif、#else、#endif等;
  • 处置惩罚头文件包罗指令,如#include,将被包换的文件插入到该预编译指令的位置;
2.2在Ubuntu下预处置惩罚的命令

在泰山服务器终端输入 gcc -E hello.c -o hello.s
图2.2.1

2.3 Hello的预处置惩罚效果解析
图2.3.1


展示hello.i部分代码,详细可看附件hello.i,可以看出hello主函数的基本结构没有发生变化,但是代码上下新增大量代码,是将#include所引用头文件的内容加入到当出息序中,其次代码段中的注释也被全部删除。源代码在颠末预处置惩罚后,输出(.i文件)被直接交给编译器,编译器检查程序是否有错误,并经程序翻译为目标代码。

2.4 本章小结

第二章主要先容程序实行过程中的预处置惩罚阶段,简述了预处置惩罚的概念与其基本操作范例。最后将hello.c文件在linux体系下预处置惩罚为hello.i文件,并叙述了在hello.i中的实际操作。

(第2章0.5分)


第3章 编译


3.1 编译的概念与作用

编译的概念是编译器(ccl)将预处置惩罚完的文本文件hello.i进行一系列的词法分析、语法分析、语义分析和优化,翻译成文本文件hello.s。汇编语言以一种文本格式形貌了低级呆板语言指令。汇编语言是非常有用的,因为它为不同高级语言的不同编译器提供了通用的输出语言。
编译过程可分为6步:词法分析、语法分析、语义分析、源代码优化、代码生成、目标代码优化。
词法分析:扫描器(Scanner)将源代的字符序列分割成一系列的暗号(Token)。 语法分析:语法分析器将暗号(Token)产生语法树(Syntax Tree)。
语义分析:包罗静态语义(在编译器可以确定的语义)与动态语义(只能在运行期才能确定的语义)。
源代码优化:源代码优化器(Source Code Optimizer),将整个语法书转化为中间代码(Intermediate Code)(中间代码是与目标呆板和运行情况无关的)。
目标代码生成:代码生成器(Code Generator).
目标代码优化:目标代码优化器(Target Code Optimizer)。        

3.2 在Ubuntu下编译的命令

在泰山服务器终端输入 gcc -S hello.i -o hello.s

图3.2.1
hello.s内容如下:

.file "hello.c"

.text

.section .rodata

.align 8

.LC0:

.string "\347\224\250\346\263\225: Hello \345\255\246\345\217\267 \345\247\223\345\220\215 \346\211\213\346\234\272\345\217\267 \347\247\222\346\225\260\357\274\201"

.LC1:

.string "Hello %s %s %s\n"

.text

.globl main

.type main, @function

main:

.LFB6:

.cfi_startproc

endbr64

pushq %rbp

.cfi_def_cfa_offset 16

.cfi_offset 6, -16

movq %rsp, %rbp

.cfi_def_cfa_register 6

subq $32, %rsp

movl %edi, -20(%rbp)

movq %rsi, -32(%rbp)

cmpl $5, -20(%rbp)

je .L2

leaq .LC0(%rip), %rdi

call puts@PLT

movl $1, %edi

call exit@PLT

.L2:

movl $0, -4(%rbp)

jmp .L3

.L4:

movq -32(%rbp), %rax

addq $24, %rax

movq (%rax), %rcx

movq -32(%rbp), %rax

addq $16, %rax

movq (%rax), %rdx

movq -32(%rbp), %rax

addq $8, %rax

movq (%rax), %rax

movq %rax, %rsi

leaq .LC1(%rip), %rdi

movl $0, %eax

call printf@PLT

movq -32(%rbp), %rax

addq $32, %rax

movq (%rax), %rax

movq %rax, %rdi

call atoi@PLT

movl %eax, %edi

call sleep@PLT

addl $1, -4(%rbp)

.L3:

cmpl $9, -4(%rbp)

jle .L4

call getchar@PLT

movl $0, %eax

leave

.cfi_def_cfa 7, 8

ret

.cfi_endproc

.LFE6:

.size main, .-main

.ident "GCC: (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0"

.section .note.GNU-stack,"",@progbits

.section .note.gnu.property,"a"

.align 8

.long  1f - 0f

.long  4f - 1f

.long  5

0:

.string  "GNU"

1:

.align 8

.long  0xc0000002

.long  3f - 2f

2:

.long  0x3

3:

.align 8

3.3 Hello的编译效果解析

main源代码内容如图3.3.1:
图3.3.1
通过对比源文件与编译文件,可以分析出编译器是怎么处置惩罚C语言的各个数据范例以及各类操作。
3.3.1 数据

1.常量:在源文件中出现的常量为字符串:“用法: Hello 学号 姓名 秒数! \n”和“Hello %s %s\n”。
在汇编文件中存在LC0与LC1字段中:
LC0:

.string "\347\224\250\346\263\225: Hello \345\255\246\345\217\267 \345\247\223\345\220\215 \346\211\213\346\234\272\345\217\267 \347\247\222\346\225\260\357\274\201"

.LC1:

.string "Hello %s %s %s\n"


2.变量:main.c函数中局部变量i,根据干系知识可知,局部变量存储 在程序的栈中,在hello.s中干系代码为
.L2:

movl $0, -4(%rbp)

jmp .L3
还有main函数参数argc与argv也存放在栈中
movl %edi, -20(%rbp)

movq %rsi, -32(%rbp)

3.3.2操作

1.赋值操作:源文件赋值操作为i=0,而由上文可知,i为局部变量存在栈中, 以是只需更改栈中数值即可。
.L2:

movl $0, -4(%rbp)

jmp .L3

2.算术操作:在循环中进行计时器i++操作,则如赋值操作相同进行add操作。
addl $1, -4(%rbp)

3.条件转移操作:
1)if(argc != 5)使用比较代码如下:
cmpl $5, -20(%rbp)

je .L2

检查argc是否为5,如果相等则跳转到L2

  • for(i=0;i<10;i++)代码如下:
cmpl $9, -4(%rbp)

jle .L4

通过比较i与9判断是否继承循环。
4.数组操作:
对数组操作主要是变址寻址,如对argv数组进行操作时:

movq (%rax), %rcx

movq -32(%rbp), %rax

addq $16, %rax

movq (%rax), %rdx

movq -32(%rbp), %rax

addq $8, %rax

movq (%rax), %rax

movq %rax, %rsi

通过依靠对栈帧寄存器偏移量实现数组操作。
5.函数操作:
源文件调用了puts,exit,printf,sleep,atoi,getchar函数。在编译文件中使用call指令进行函数调用,如:
call exit@PLT
3.4 本章小结

本章主要分析程序的编译过程,在linux体系下生成汇编文件hello.s。并依据源C文件内容实例对汇编文件进行语句分析,并逐一解释了常量、变量、赋值操作、关系跳转操作、数组操作与函数操作等汇编代码。
(第3章2分)


第4章 汇编


4.1 汇编的概念与作用

汇编是汇编器(as)将编译完的汇编代码文件hello.s翻译成呆板语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将效果生存在目标文件hello.o中,hello.o是一个二进制文件。
汇编作用:将汇编代码转变为呆板指令,生成目标文件(.o)。
4.2 在Ubuntu下汇编的命令

在泰山服务器终端输入 gcc hello.s -c -o hello.o
图4.2.1

4.3 可重定位目标elf格式

4.3.1 ELF
在linux体系下用命令 readelf -h hello.o 查看可重定位文件ELF(如图4.3.1)
图4.3.1
分析elf格式可以得到以下信息:
hello.o是64位文件;数据的存储形式为补码、小端序存储;文件的范例为REL(可重定位文件),入口点地点为0x0,程序头出发点为0,节头表的起始位置为1264;文件共有14节.
4.3.2头节表
在linux体系下用命令 readelf -S hello.o 查看头节表(如图4.4.2)
图4.3.2
通过头节表我们可以知道.o文件中各节的字节大小,地点,偏移量,访问方式等信息。
4.3.3符号表
在linux体系下用命令 readelf -s hello.o 查看头节表(如图4.4.3)
图4.3.3
在符号表中存储着本程序使用的符号及其信息:范例、全局符号、字节大小等信息。
4.3.4重定位节
在linux体系下用命令 readelf -r hello.o 查看头节表(如图4.4.4)
图4.4.4
在重定位字段中表现了本程序必要重定位的符号及信息。
4.4 Hello.o的效果解析

在linux体系下用命令 objdump -d -r hello.o >dump.s 可以查看hello.o的反汇编信息,并将其存入至dump.s中,内容如下:
hello.o:     file format elf64-x86-64



Disassembly of section .text:


0000000000000000 <main>:

   0: f3 0f 1e fa           endbr64

   4: 55                    push   %rbp

   5: 48 89 e5              mov    %rsp,%rbp

   8: 48 83 ec 20           sub    $0x20,%rsp

   c: 89 7d ec              mov    %edi,-0x14(%rbp)

   f: 48 89 75 e0           mov    %rsi,-0x20(%rbp)

  13: 83 7d ec 05           cmpl   $0x5,-0x14(%rbp)

  17: 74 16                 je     2f <main+0x2f>

  19: 48 8d 3d 00 00 00 00  lea    0x0(%rip),%rdi        # 20 <main+0x20>

1c: R_X86_64_PC32 .rodata-0x4

  20: e8 00 00 00 00        callq  25 <main+0x25>

21: R_X86_64_PLT32 puts-0x4

  25: bf 01 00 00 00        mov    $0x1,%edi

  2a: e8 00 00 00 00        callq  2f <main+0x2f>

2b: R_X86_64_PLT32 exit-0x4

  2f: c7 45 fc 00 00 00 00  movl   $0x0,-0x4(%rbp)

  36: eb 53                 jmp    8b <main+0x8b>

  38: 48 8b 45 e0           mov    -0x20(%rbp),%rax

  3c: 48 83 c0 18           add    $0x18,%rax

  40: 48 8b 08              mov    (%rax),%rcx

  43: 48 8b 45 e0           mov    -0x20(%rbp),%rax

  47: 48 83 c0 10           add    $0x10,%rax

  4b: 48 8b 10              mov    (%rax),%rdx

  4e: 48 8b 45 e0           mov    -0x20(%rbp),%rax

  52: 48 83 c0 08           add    $0x8,%rax

  56: 48 8b 00              mov    (%rax),%rax

  59: 48 89 c6              mov    %rax,%rsi

  5c: 48 8d 3d 00 00 00 00  lea    0x0(%rip),%rdi        # 63 <main+0x63>

5f: R_X86_64_PC32 .rodata+0x2c

  63: b8 00 00 00 00        mov    $0x0,%eax

  68: e8 00 00 00 00        callq  6d <main+0x6d>

69: R_X86_64_PLT32 printf-0x4

  6d: 48 8b 45 e0           mov    -0x20(%rbp),%rax

  71: 48 83 c0 20           add    $0x20,%rax

  75: 48 8b 00              mov    (%rax),%rax

  78: 48 89 c7              mov    %rax,%rdi

  7b: e8 00 00 00 00        callq  80 <main+0x80>

7c: R_X86_64_PLT32 atoi-0x4

  80: 89 c7                 mov    %eax,%edi

  82: e8 00 00 00 00        callq  87 <main+0x87>

83: R_X86_64_PLT32 sleep-0x4

  87: 83 45 fc 01           addl   $0x1,-0x4(%rbp)

  8b: 83 7d fc 09           cmpl   $0x9,-0x4(%rbp)

  8f: 7e a7                 jle    38 <main+0x38>

  91: e8 00 00 00 00        callq  96 <main+0x96>

92: R_X86_64_PLT32 getchar-0x4

  96: b8 00 00 00 00        mov    $0x0,%eax

  9b: c9                    leaveq

  9c: c3                    retq   
通过对比编译文件与反汇编文件可以看出两者大要相同,但有一些差别的地方:

  • 分支跳转:hello.s的跳转指令是通过段名字进行跳转的,而反汇编文件是直接给出跳转地点实现的。
  • 函数调用:hello.s中函数调用是通过call指令加函数名称实现的,而反汇编文件call指令后加的是指令的地点。
  • 全局变量访问:hello.s中全局变量访问是段的名称+寄存器,反汇编文件中全局变量访问是0+寄存器,因为全局变量数据的地点在运行时已经确定,访问也必要重定位。
这些不同说明呆板语言的构成,与汇编语言的映射关系。特殊是呆板语言中的操作数与汇编语言不同等,特殊是分支转移函数调用等。
4.5 本章小结

本章先容了程序的汇编过程,并在linux下生成汇编文件hello.o。并对汇编文件ELF,符号表,重定位表进行了导出与分析。最后反汇编.o文件,并对比分析了反汇编文件与编译文件(hello.s)的不同及原因。
以下格式自行编排,编辑时删除
(第4章1分)


5链接


5.1 链接的概念与作用

链接概念:链接(linking)是由叫链接器(linker)的程序主动实行的将各种代码和数据片段收集并组合成为一个单一文件的过程,这个文件可被加载(复制)到内存并实行。链接可以实行于编译时(compile time),也就是在源代码被翻译成呆板代码时;也可以实行于加载时(load time),也就是在程序被加载器(loader)加载到内存并实行时;乃至实行于运行时(run time),也就是由应用程序来实行。
原hello程序调用了一系列编译器已经准备好的函数。以printf函数举例,它存在于一个名为printf.o的单独的预编译好了的目标文件中,连接器(ld)负责把这个文件合并到我们的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.2.1

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

5.3.1ELF头
在linux体系下用命令 readelf -a hello > ELF.txt 查看程序文件ELF头信息(如图5.3.1)
图5.3.1
图5.3.1截出ELF中ELF头信息,在其中可以知道关于本程序信息:
hello以补码、小端序形式存储,入口点地点为0x4010f0,程序头节点气质为64,节头表起始地点为14208,对比可重定位文件表明文件已经重定位完成。
5.3.2节头表
图5.3.2
在节头表中记录了hello中各节信息,如大小、范例等。对比可重定位文件中的节头表,可以看出节的数目变多,其次在可重定位文件中各节的地点全为零,而在hello节头表中的各节都有详细地点,说明已经重定位完成。
5.3.3符号表
图5.3.3
在符号表中记录了hello程序所引用和定义的符号,而且指明了此符号的大小、范例、距离地点节的偏移量等信息。
5.4 hello的假造地点空间

在linux体系下使用edb运行hello程序,运行效果如图5.4.1。
图5.4.1
通过图中信息可以得出,程序被加载到假造地点0x401000到0x402000中,各节地点等信息与可实行文件ELF中记录的信息同等。
5.5 链接的重定位过程分析

在泰山服务器终端输入 objdump -d -r hello > hello.txt如图5.5.1,记录反汇码代码。
图5.5.1

部分效果如下(图5.5.2、图5.5.3、图5.5.4):
图5.5.2

图5.5.3
相比较hello.o反汇编文件多了一些链接库中的函数,这是通过重定位垒放到程序代码段的,而且每个重定位符号都有确切地点。
图5.5.4
在main函数段中,跳转指令发生变化,连接过程重定位各函数地点,盘算相对距离,修改了跳转地点,形成了完备的反汇编代码。
hello的重定位方式是将各可重定位文件与库文件中的各节按照肯定规矩从高地点到低地点垒放在一起并盘算各符号的相对位置,进行重定位代码更换,最终形成完备的程序文件。
5.6 hello的实行流程

使用gdb/edb实行hello,说明从加载hello到_start,到call main,以及程序终止的所有过程(主要函数)。请列出其调用与跳转的各个子程序名或程序地点。
_dl_start、_dl_init

_start

_libc_start_main

_main

_printf

_exit

_sleep_getchar

_dl_runtime_resolve_xsave

_dl_fixup

_dl_lookup_symbol_x

Exit

ld-2.27.so!_dl_start

ld-2.27.so!_dl_init

hello!_start

lib-2.27.so!__libc_start_main

hello!puts@plt
5.7 Hello的动态链接分析

动态链接是指编译器在程序加载之前为共享库函数生成一条重定位记录,然后动态链接器在加载程序时再解析此记录。GNU使用延迟绑定将过程地点的绑定推迟到第一次调用时绑定。延迟绑定由GOT与PLT构成。其中GOT是一个8字节地点数组,GOT[O]和GOT[1]包罗动态链接器在解析函数地点时会使用的信息。GOT[2]是动态链接器在1d-linux.so模块中的入口点。其余的每个条目对应于一个被调用的函数,其地点必要在运行时被解析。每个条目都有一个相匹配的PLT条目。而PLT是一个16字节代码数组,PLT[0]是一个特殊条目,它跳转到动态链接器中。每个被可实行程序调用的库函数都有它本身的PLT条目。每个条目都负责调用一个详细的函数。
在程序文件中.got节用于动态链接,其中包罗所有符号的地点表,当动态链接时,会更新这个表,以便程序正确访问各符号。.got.plt节与.got节类似,只有在函数第一次调用时才会进行符号的重定位并更新.goy.plt中的符号地点。
5.8 本章小结


本章主要先容了程序的链接过程,并在linux下链接生成可实行目标文件hello。并分析了程序文件ELF内容并与第四章内容进行对比,分析了重定位的详细操作,最后根据hello反汇编文件与hello.o反汇编文件的不同分析了动态链接的实现。
(第5章1分)



6hello进程管理


6.1 进程的概念与作用

进程是盘算机体系中正在运行的程序的实例。它是操作体系对程序实行的基本单位,可以看作是程序在实行过程中的动态体现。每个进程都有本身的内存空间、代码、数据和实行状态。多个进程可以同时运行在盘算机体系中。进程是具有独建功能的程序在一个数据集合上运行的过程,它是体系进行资源分配和调度的一个独立单位。
作用:进程可以解决在一个体系可以并发实行多个任务的问题,提高程序的实行服从。
6.2 简述壳Shell-bash的作用与处置惩罚流程

Shell是Linux下的命令行解释器。将用户的命令翻译给内核来处置惩罚命将最后的处置惩罚效果反馈给用户,避免了用户与核的直接沟通,掩护内核不被误处置惩罚。
处置惩罚流程:

  • 读取用户输入的命令
  • 对命令进行分析与处置惩罚
  • 建立一个子进程,子进程进行处置惩罚或出现异常后报告给父进程
  • 等候子进程竣事并进行回收
6.3 Hello的fork进程创建过程

首先父进程新建一个子进程,然后在内核中分配一个PCB,将其挂在PCB表上。子进程获得与父进程相同的假造地点空间,复制它的父进程的情况并为其分配资源。最后复制父进程地点空间里的内容,如:代码共享等。将进程置成停当状态,并将其放入停当队列,等候CPU调度。
6.4 Hello的execve过程

hello通过fork()新建子程序后,如果想让子程序调用新的可实行文件则必要子程序运行exceve()函数来加载并启动新的程序。内核在调用exceve时,这个函数先打开目标映像文件并读入其ELF文件头,然后调用另一个函数search_binary_handler()搜索Linux支持的可实行文件范例队列进行匹配,然后调用load_binary函数指针所指向的处置惩罚函数来处置惩罚目标映像文件,加载可实行文件。
6.5 Hello的进程实行

6.5.1进程上下文信息
进程上下文实际上是进程实行活动全过程的静态形貌。 我们把已实行过的进程指令和数据在干系 寄存器 与 堆栈 中的内容称为上文,把正在实行的指令和数据在寄存器和堆栈中的内容称为正文,把待实行的指令和数据在寄存器与堆栈中的内容称为下文。内核通过控制上下文切换机制来控制跳转到新的进程。
6.5.2进程时间片
时间片即CPU分配给各个程序的时间,每个线程被分配一个时间段,即该进程允许运行的时间,使各个程序从外貌上看是同时进行的。如果在时间片竣事时进程还在运行,则CPU将被剥夺并分配给另一个进程。如果进程在时间片竣事前阻塞或竣事,则CPU立即进行切换。而不会造成CPU资源浪费。由于只有一个CPU,一次只能处置惩罚程序要求的一部分,怎样处置惩罚公平,一种方法就是引入时间片,每个程序轮番实行。
6.5.3进程调度过程
进程调度的过程主要进行以下步骤:所有准备好实行的进程都在停当队列中等候。CPU根据特定的算法选择一个进程来实行。进行上下切换,生存当前运行进程的状态,并加载所选进程的上下文。实行被选中的进程。当进程终止时,从体系中移除。

6.5.4用户态与核心态转换
内核态和用户态的切换主要通过中断和体系调用来实现.当用户态的进程必要实行内核态的代码时,通常会通过体系调用陷入到内核态。这个过程涉及到生存用户态的上下文到内核态,然后加载新的内核态的上下文开始实行。 当内核态的代码实行完毕后,它会将控制权返回给用户态,并恢复原来的上下文,完成从内核态到用户态的切换。
6.6 hello的异常与信号处置惩罚

程序的异常控制流主要分为以下四种:异常、中断、陷阱与故障。异常是指为了相应某个事件而将控制转移给操作体系内核的情况。异常处置惩罚类似于过程调用,异常根据发生的时钟周期可以分为同步异常与异步异常。而中断是异步发生的,由外部I/O设备产生,处置惩罚终端的程序称为中断处置惩罚程序。陷阱是一种人为设置的异常,体系调用提供了用户程序与内核之间的接口。故障是意外发生但大概被修复的异常,例如缺页、浮点异常等。

  • 对于hello正常运行情况如图6.6.1:
图6.6.1

  • 输入ctrl +Z(如图6.6.2)
图6.6.2

  • 通过ps命令查看进程发现有hello进程(图6.6.3)没有终止,被临时挂起。
图6.6.3


  • 使用jobs命令查看(图6.6.4)
图6.6.4

  • 使用pstree命令查看hello进程的位置(图6.6.5)
图6.6.5


  • 输入fg 1将后台进程转到前台(图6.6.6)
图6.6.6


  • 输入ctrl+C命令终止进程(图6.6.7-6.6.8)
图6.6.7 图6.6.8

6.7本章小结

本章主要先容了linux的壳Shell的作用与工作流程,进而引出了进程的概念与进程调用的干系函数等。最后依据理论知识分析了hello程序的进程实现与干系命令的征象,先容了hello异常与信号处置惩罚流程。
(第6章1分)


7hello的存储管理


7.1 hello的存储器地点空间

1.逻辑地点:编译器生成呆板指令时所带有的地点,即程序中数据与函数相对段的偏移量。
2.线性地点:指令的逻辑地点加上段基址形成线性地点,整个程序代码线性排列在内存空间中。
3.假造地点:在页式管理机制中程序映射到假造内存,其地点为假造地点。
4.物理地点:在页式管理机制中程序映射到物理内存,其地点为物理地点。
7.2 Intel逻辑地点到线性地点的变换-段式管理

段式管理就是段基地点加偏移地点,最终覆盖一维空间。
以下格式自行编排,编辑时删除
7.3 Hello的线性地点到物理地点的变换-页式管理

页式管理是将各进程的假造空间分别为若干长度相等的页。内存空间按页的大小建立页表。页结构体由页号、页面偏移构成,用来分配物理内存运行程序。其工作方式类似cache全相联映射。
7.4 TLB与四级页表支持下的VA到PA的变换

多级页表假造地点被分别成为k个VPN和1个VPO。每个VPN i都是一个到第i级页表的索引,其中1≤i≤k。第j级页表中的每个PTE,1≤j≤k-1,都指向第j+1级的某个页表的基址。属于四级页表的一到三级页表中存放的数据是指向下一级页表的首地点,而不是物理页号。逐步访问到第四级页表,第四级页表中装的就是物理页号,通过第四级页表读出的物理页号链接上假造地点中的VPO获得物理地点。
7.5 三级Cache支持下的物理内存访问

CPU提供的地点w,从其中间抽取出6位组索引。这些位被解释个一个对应于一个组号的无符号整数。接下来必要确定是否有字w的一个副本存储在组i的一个高速缓存行中,只有标记位相匹配且有效位为1的时间才缓存命中,否则缓存不命中。如果缓存命中,根据提供的块偏移位,我们就可以将其取出 并返还给CPU。如果缓存不命中,那么它必要从存储器层次结构中的下一层取出被哀求的块,然后将新的块存储到组索引位指示的组中的一个高速缓存行中。如果组中都是有效高速缓存,那么必须驱逐出一个现有的行,可以接纳最近最少使用策略LFU进行更换。

7.6 hello进程fork时的内存映射

当fork函数被当进步程调用时,内核为新进程创建各种数据结构,并分配给它一个唯一的PID。为了给这个新进程创建假造内存,它创建了当进步程的mm_struct、区域结构和页表的原样副本。它将两个进程中的每个页面都标记为只读,而且把两个进程中的每个区域结构都标记为私有的写时复制。
当fork在新进程中返回时,新进程现在的假造内存刚好和调用fork时存在的假造内存相同。当这两个进程的任一个厥后进行写操作时,写时复制机制就会创建新页面,因此,也就为每个进程保持了私有地点空间的抽象概念。
7.7 hello进程execve时的内存映射

execve在当进步程中加载并运行新程序主要为以下几个步骤:


  • 删除已存在的用户区域
  • 映射私有区域,为新程序的代码、数据等创建新的区域结构,都是私有的写时复制的。
  • 映射共享区域,把动态链接库映射到共享区域
  • 设置程序计数器(PC),使之指向代码区域的入口点。
7.8 缺页故障与缺页中断处置惩罚

缺页故障即进程在实行一条指令时,如果发现他要访问的页没有在内存中,那么停止该指令的实行,并产生一个页不存在的异常,对应的故障处置惩罚程序可通过从外存加载该页的方法来清除故障,之后,原先引起的异常的指令就可以继承实行,而不再产生异常。
缺页中断处置惩罚:中断处置惩罚函数为arch/arm/mm/fault.c文件中的do_page_fault函数。
7.9动态存储分配管理

动态存储分配主要在堆中进行。brk指向堆的顶部,分配器将堆视为一组不同大小的块的集合来维护,每个块就是一个连续的假造内存片,要么是已分配的,要么是空闲的。已分配的块显式地保存为供应用程序使用。空闲块可用来分配。空闲块保持空闲,直到它显式地被应用所分配。一个已分配的块保持已分配状态,直到它被释放,这种释放要么是应用程序显式实行的,要么是内存分配器自身隐式实行的。
printf调用malloc函数,会先访问堆中是否有合适大小的空闲块,如果有相应的空闲块则分配这个块给Hello,返回一个指针指向这个分配块的首地点。如果没有合适的空闲块,体系会拓展堆空间,改变brk的值来保证有合适的空闲块。
7.10本章小结

本章主要解释了程序怎样加载到假造内存与物理内存并运行的过程,引出页结构完成对应页的映射关系,并简介hello在运行时内存的使用情况包罗fork等进程函数的调用与堆的动态内存空间管理等。
(第7章 2分)


8hello的IO管理


8.1 Linux的IO设备管理方法

Linux的设备管理的主要任务是控制设备完成输入输出操作。它的任务是把各种设备硬件的复杂物理特性的细节屏蔽起来,提供一个对各种不同设备使用同一方式进行操作的接口。Linux把设备看作是特殊的文件,体系通过处置惩罚文件的接口—假造文件体系VFS来管理和控制各种设备。

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

unixI/O:将设备映射为文件的方式,允许Unix内核引出一个简朴、低级的应用接口。 Linux/unix IO的体系调用有5个函数:open (打开)、close (关闭)、read (读)、write (写)、lseek (定位)。
8.3 printf的实现分析

vsprintf的作用就是格式化。它接受确定输特殊式的格式字符串fmt。用格式字符串对个数变化的参数进行格式化,产生格式化输出。 代码中的vsprintf只实现了对16进制的格式化。

Write体系函数的功能就是不断的打印出字符,直到碰到'\0'。

syscall将字符串中的字节“Hello 2022110562 吴建锋 11111111111 1”从寄存器中通过总线复制到显卡的显存中,显存中存储的是字符的ASCII码。

字符表现驱动子程序:从ASCII到字模库到表现vram(存储每一个点的RGB颜色信息)。

字符表现驱动子程序将通过ASCII码在字模库中找到点阵信息将点阵信息存储到vram中。

表现芯片会按照肯定的革新频率逐行读取vram,并通过信号线向液晶表现器传输每一个点(RGB分量)。

于是我们的打印字符串“Hello 2022110562 吴建锋 11111111111 1”就表现在了屏幕上。

8.4 getchar的实现分析

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

本章主要先容了linux体系的IO设备管理方法,包罗Unix IO接口与函数,最后分析了printf与getchar函数实现体系与外设工作的干系内容。
(第8章1分)

结论

盘算机的产生是人类历史上的巨大飞跃,人类从使用规则开拓到创造规则的领域,并可以随着各种奇思妙想进一步发展、进化。简简朴单的hello程序运行:从编译到汇编、从链接到内存分配,其背后确实整个人类智慧的结晶。在逐步分析的过程中我可以感受到先辈们遇山开路、遇水架桥的精力,也正是这种精力推动着整个盘算机体系的蓬勃发展。
(结论0分,缺失 -1分,根据内容酌情加分)

附件

列出所有的中间产物的文件名,并予以说明起作用。
hello.i: ASCII码的中间文件(预处置惩罚器产生),用于分析预处置惩罚过程。

hello.s: ASCII汇编语言文件(预处置惩罚器产生),用于分析编译的过程。

hello.o:可重定位目标程序(汇编器产生),用于分析汇编的过程。

hello:可实行目标文件(链接器产生),用于分析链接的过程。

hello.txt:hello可实行文件反汇编文件。

dump.s:hello.o反汇编文件。

ELF.txt:hello可实行文件ELF头。

(附件0分,缺失 -1分)


参考文献


为完本钱次大作业你翻阅的书籍与网站等

[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.
(参考文献0分,缺失 -1分)



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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

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

本版积分规则

天空闲话

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

标签云

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