计算机系统大作业——步伐人生

打印 上一主题 下一主题

主题 989|帖子 989|积分 2967




计算机系统


大作业



题     目  步伐人生-Hello’s P2P 
专       业      人工智能范畴                 
学     号      2022112624                 
班     级      22WL028                 
学       生       叶祥              
指 导 教 师       郑贵滨                






计算机科学与技能学院

2024年5月

摘  要

本文重要通过利用计算机系统课程中所学习的有关步伐运行全过程的知识,对预处理,编译,汇编等过程及进程管理、存储管理、IO管理等方面,对hello.c文件进行细致分析,从而更好的相识计算机系统的运行。

关键词:计算机系统,分析                         









目  录


第1章 概述................................................................................... - 4 -
1.1 Hello简介............................................................................ - 4 -
1.2 情况与工具........................................................................... - 4 -
1.3 中间效果............................................................................... - 4 -
1.4 本章小结............................................................................... - 4 -
第2章 预处理............................................................................... - 5 -
2.1 预处理的概念与作用........................................................... - 5 -
2.2在Ubuntu下预处理的命令................................................ - 5 -
2.3 Hello的预处理效果解析.................................................... - 5 -
2.4 本章小结............................................................................... - 5 -
第3章 编译................................................................................... - 6 -
3.1 编译的概念与作用............................................................... - 6 -
3.2 在Ubuntu下编译的命令.................................................... - 6 -
3.3 Hello的编译效果解析........................................................ - 6 -
3.4 本章小结............................................................................... - 6 -
第4章 汇编................................................................................... - 7 -
4.1 汇编的概念与作用............................................................... - 7 -
4.2 在Ubuntu下汇编的命令.................................................... - 7 -
4.3 可重定位目标elf格式........................................................ - 7 -
4.4 Hello.o的效果解析............................................................. - 7 -
4.5 本章小结............................................................................... - 7 -
第5章 链接................................................................................... - 8 -
5.1 链接的概念与作用............................................................... - 8 -
5.2 在Ubuntu下链接的命令.................................................... - 8 -
5.3 可执行目标文件hello的格式........................................... - 8 -
5.4 hello的假造地址空间......................................................... - 8 -
5.5 链接的重定位过程分析....................................................... - 8 -
5.6 hello的执行流程................................................................. - 8 -
5.7 Hello的动态链接分析........................................................ - 8 -
5.8 本章小结............................................................................... - 9 -
第6章 hello进程管理.......................................................... - 10 -
6.1 进程的概念与作用............................................................. - 10 -
6.2 简述壳Shell-bash的作用与处理流程........................... - 10 -
6.3 Hello的fork进程创建过程............................................ - 10 -
6.4 Hello的execve过程........................................................ - 10 -
6.5 Hello的进程执行.............................................................. - 10 -
6.6 hello的非常与信号处理................................................... - 10 -
6.7本章小结.............................................................................. - 10 -
第7章 hello的存储管理...................................................... - 11 -
7.1 hello的存储器地址空间................................................... - 11 -
7.2 Intel逻辑地址到线性地址的变动-段式管理................... - 11 -
7.3 Hello的线性地址到物理地址的变动-页式管理............. - 11 -
7.4 TLB与四级页表支持下的VA到PA的变动.................... - 11 -
7.5 三级Cache支持下的物理内存访问................................ - 11 -
7.6 hello进程fork时的内存映射......................................... - 11 -
7.7 hello进程execve时的内存映射..................................... - 11 -
7.8 缺页故障与缺页中断处理................................................. - 11 -
7.9动态存储分配管理.............................................................. - 11 -
7.10本章小结............................................................................ - 12 -
第8章 hello的IO管理....................................................... - 13 -
8.1 Linux的IO装备管理方法................................................. - 13 -
8.2 简述Unix IO接口及其函数.............................................. - 13 -
8.3 printf的实现分析.............................................................. - 13 -
8.4 getchar的实现分析.......................................................... - 13 -
8.5本章小结.............................................................................. - 13 -
结论............................................................................................... - 14 -
附件............................................................................................... - 15 -
参考文献....................................................................................... - 16 -



第1章 概述

1.1 Hello简介

Hello的P2P:指hello.c作为源文件先通过预处理器cpp形成修改了的源步伐hello.i(文本文件),再通过编译器ccl产生hello.s汇编步伐(文本文件),随后通过汇编器as产生可重定位目标步伐hello.o(二进制文件),最后在通过链接器链接其他.o文件,即可最终产生可执行目标步伐(二进制文件)
020:用户在shell命令行中输入./hello时,系统会通过Fork函数产生一个只与父进程pid不雷同的子进程,并在子进程中调用evecve,它启动加载器,丢弃原有上下文中的内容,并新建出task_struct及其目录的结构。再设置步伐计数器至步伐开始运行处,使步伐运行。在完成一系列变量函数的调用与利用后,步伐停止运行,变为僵尸进程等待接纳。
1.2 情况与工具

硬件情况:
X64 CPU 3.20GHz 16G RAM 521GHD Disk

软件情况:
Windows 11 64位,Visual Basic Code,Dev-c++,XShell,XFTP
1.3 中间效果

列出你为编写本论文,生成的中间效果文件的名字,文件的作用等。
1.4 本章小结

       本章总体分析了hello作为一个步伐的运行全过程,并给出本文所运用的情况与工具。



第2章 预处理

2.1 预处理的概念与作用

预处理的概念:
预处理是编译器在正式编译源代码前,对代码进行开端的处理,预处理器通过读取源代码,根据预处理指令对代码或代码块进行文本替换或修改。
预处理的作用:
能使编译器更高效的处理源代码,并为编程人员提供有效的工具来管理和优化代码。



2.2在Ubuntu下预处理的命令

       命令为gcc hello.c -E -o hello.i,效果如下图所示


图1.Ubuntu下预处理命令效果展示


2.3 Hello的预处理效果解析


图2.Ubuntu下预处理文本效果展示


如图所示,代码总行数大概在3000行左右,远超最初的三四十行,且#include头文件被大量的代码替代,说明预处理过程中完成了代码的修改与替换。
2.4 本章小结

本章明白了预处理的概念及作用,给出预处理文件在ubuntu下生成的命令,并展示了预处理后的文本文件,可以发现预处理文件与源文件相比差别不大,重要是头文件的替换。



第3章 编译

3.1 编译的概念与作用

编译的概念:
编译(Compilation)是将高级编程语言编写的源代码转换为计算机可以执行的低级语言(通常是呆板代码或字节码)的过程。这个过程由编译器完成,编译器是一种专门的软件工具。
编译的作用:编译是将高级编程语言转换为呆板可执行代码的关键步骤。编译器不仅负责翻译代码,还执行语法和语义检查、代码优化、错误报告等功能,从而提高代码的性能、安全性和可靠性,同时加强代码的可读性和可维护性。       

3.2 在Ubuntu下编译的命令

       命令为gcc hello.i -S -o hello.s,效果如下图所示

图3.Ubuntu下编译命令效果展示


3.3 Hello的编译效果解析


图4.main函数栈的空间分配


      如图所示,main函数内部界说了一个未赋值的局部变量int i,局部变量存在栈中,生命周期与main雷同,故rsp指针向下移动32位,为变量留出充足的位置。


图5.循环变量赋值

     
      如图所示,从main函数的汇编代码中可以看出,argc和argv分别存储在%edi和%rsi中,并存放在rbp向下20位的位置与向下32位的位置。

图6.参数存储


      字符串参数存储在.text中并进行标号

图7.字符串存储


      后续访问时,利用rip间址寻址。

图8.间接寻址


      赋值利用通过mov指令实现。

图9.赋值语句


      i++在汇编语言中用addl指令表示。

图10.算术加法


      不等号在汇编语言中,利用cmp和je的组合进行实现。cmp设置标志位,je判断标志位。

图11.不等号的比较运算


      小于号与不等号的处理情势雷同。

图12.小于号的比较运算


      循环变量初始值i=0,与8比较,循环8次

图13.循环利用


      汇编代码中通过首地址并进行偏移利用,取argv中的字符串的地址。argv数组中的内容存在了栈中,取出对应的字符串的地址,并放到%rsi和%rdx中,作为printf的第二和第三个参数,最后完成输出。

图14.数组利用


      Printf函数第一次调用,由于只有一个字符串参数,被转化为puts函数进行处理,利用寄存器%rdi进行传入

图15.printf函数第一次调用


      Printf函数第二次调用,有字符串,argv[0],argv[1]三个参数传入

图16.printf函数第二次调用


      将1传入%edi中作为参数进行传递,执行exit函数

图17.exit函数调用

     

      Argv[3]作为参数传入%rdi寄存器

图18.atoi函数调用


      Atoi函数返回值存入%rax中,再作为参数给寄存器%rdi并最终传入sleep函数中

图19.sleep函数调用


      函数最终返回的过程中会执行以下利用:恢复寄存器为初始状态、恢复旧的帧指针%rbp、跳转到原有控制流的地址。一般会在末端利用ret指令。

图20.函数返回


3.4 本章小结

本章明白了编译的概念及作用,给出编译文件在ubuntu下生成的命令,并展示了编译后的文本文件,对数据、赋值、算术利用、比较利用、数组利用、函数调用、函数返回等利用的汇编代码进行分析与思考。


第4章 汇编

4.1 汇编的概念与作用

       汇编的概念:
汇编是一种低级编程语言,它通过直接对应于计算机硬件的指令来进行编程。汇编语言通常是特定于某种计算机架构的,这意味着不同的处理器范例有不同的汇编语言。

汇编的作用:
汇编语言重要作用是高效控制硬件和性能优化。它允许步伐员直接利用硬件资源,如寄存器和内存地址,从而实现高效利用和优化。在对性能要求极高的步伐中,如利用系统内核、驱动步伐和嵌入式系统,汇编语言可以生成更高效的代码。此外,通过编写和调试汇编代码,步伐员能够深入明白计算机的底层工作机制。
4.2 在Ubuntu下汇编的命令

       指令为as hello.s – o hello.o

图21.Ubuntu下汇编指令效果展示

4.3 可重定位目标elf格式

1. elf头
       通过输入readelf -h hello.o指令实现,效果如下

图22.elf头效果展示


Elf头以一个16进制序列开始,称为魔数,用来形貌文件系统字的巨细及其顺序。余下的部门信息是表明器与目标文件的详细信息。

2. 节头

图23.节头效果展示


       在节头中可以看到有13个节,展示了每一个节的详细信息。表明了其名称,范例,地址等信息。

3.重定位节
       .rela.text节是text节的重定位信息,给出了偏移量、信息、寻址范例、符号的值与符号名称以及addend的数值。

‘.rela.eh_frame’节是eh_frame节的重定位信息。

图24.重定位节


      
4.符号表
       符号表展示了每个符号的编号、值、巨细、范例、局部性大概全局性、是否可见、是否可被界说以及名字

图25.符号表

4.4 Hello.o的效果解析

1.  hello.asm文件有每句汇编语言的地址与编号顺序,而hello.s没有
2.  hello.asm文件中跳转利用的是代码地址,而hello.s是每个段的标号
3.  hello.asm 文件中调用函数是跳转到对应地址,而hello.s是利用函数名进行调用。
4.5 本章小结

本章重要对汇编后的可重定向文件Hello.o进行分析,明白汇编的概念与作用并给出了对应的指令,并深入分析hello.o的信息,最后将其反汇编内容与hello.s的内容进行比对并得到异同。

第5章 链接

5.1 链接的概念与作用

       链接的概念:
链接是将编译后的目标文件(object files)组合成可执行文件或库的过程。它包罗解析符号、解决重定位、整合代码和数据段,以及最终生成可以在特定利用系统和硬件平台上运行的二进制文件。

链接的作用:
链接的重要作用是将多个编译后的目标文件整合成一个可以运行的可执行文件或库。它通过解析和绑定各目标文件中的符号,将未解析的函数调用和变量引用毗连到对应的界说上,解决了符号解析问题。同时,链接器调整代码和数据的地址引用,确保所有引用和调用在内存中的地址准确,完成重定位利用。此外,链接器将各目标文件的代码段和数据段归并,优化和精简代码,删除未利用的符号,最终生成一个独立的可执行文件或库。
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

图26.Ubuntu下链接命令效果展示

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

1. Elf头

图27. Hello的elf头效果展示



开头与hello.o雷同,都是16个字节构成的魔数,后续是ELF头的巨细、目标文件范例、呆板范例、节头部表的文件偏移及此中条目标信息。

2. 节头


图28.hello的节头效果展示


       表示了每一节的名字、种类、地址与偏移量

3.步伐头

图29.hello的步伐头效果展示


       每个步伐头记录了一个内存段或为步伐执行而预先准备的须要信息,包罗范例、偏移量、假造内存地址、段的权限标志与对齐要求。
5.4 hello的假造地址空间

1.节地址
       查看hello的节头表,可以查看到.interp节的详细信息。

图30. .interp在节头表中的信息

    

图31.edb观察到的.interp的汇编代码


2.数据段
       如下图所示为data dump

图32. Data dump示意图

5.5 链接的重定位过程分析

1.地址范例区别
       链接之后的hello.asm中地址利用的是假造内存的地址,而hello.o.asm中利用的是内存的绝对地址。

图33.   hello.asm利用地址范例



图34. hello.o.asm利用地址范例


2. 函数调用
       链接之后的hello.asm中调用函数是直接声明函数名字,而hello.o.asm中利用的是函数地址

图35. hello.asm利用函数表示



图36. hello.o.asm利用函数表示


3. 重定位

图37.重定位前


图38.重定位后


图39.rodata节详细信息

       .rodata节首地址位于0x402000处且偏移量为8,从hello.o.asm中可以看出,在图中的lea命令被执行后,PC值应位于下一条命令的位置,即0x401145。则颠末计算后:0x402000+8-0x401145=0xec3即重定位后lea利用的假造内存地址。
5.6 hello的执行流程

_dl_start
_dl_init
_cax_atexit
_new_exitfn
_libc_start_main
_libc_csu_init
Main
       {
              printf();
              atoi();
              sleep();
}(重复执行八次)
getchar
_exit
_dl_runtime_resolve_xsave
_dl_fixup
_dl_lookup_symbol_x
exit
5.7 Hello的动态链接分析


图40.‘.got’与‘.got.plt’详细信息展示



图41.链接前got的内容

      
       GOT[0]和GOT[1]存储动态链接器在解析各个函数时所需要的全部信息,GOT[2]是动态链接器在ld-linux.so模块中的入口点;别的元素分别对应一个可以被调用的函数,当第一次调用函数时,对应的内容被解析。
5.8 本章小结

本章重要先容了链接的概念与作用,给出了在Ubuntu下的指令,并给出hello的格式如elf头,步伐头表,节头表以及其对应的假造内存地址。并分析了链接的重定向全过程并给出hello执行过程中各部门的顺序,最后分析了hello的动态链接。

第6章 hello进程管理

6.1 进程的概念与作用

进程的概念:
       进程是计算机中步伐执行的实例。它不仅包罗步伐的代码,还包罗步伐计数器、寄存器内容、变量、堆栈、数据段等执行状态信息。每个进程在利用系统中作为独立的运行单元,被分配独立的内存空间和系统资源。

进程的作用:
    进程在利用系统中扮演着至关紧张的角色,通过提供资源管理、并发执行、隔离性、通信与同步以及任务调度等功能,保证计算机系统的高效、稳定和安全运行。
6.2 简述壳Shell-bash的作用与处理流程

作用:
       Shell(Bash)是利用系统的命令表明器,充当用户与利用系统之间的桥梁。它负责解析和执行用户输入的命令,提供脚本编写和执行功能,用于自动化任务和系统管理,同时管理用户的工作情况,包罗情况变量和路径设置。Shell允许用户启动、控制和管理进程,支持输入输出重定向和管道利用。

处理流程:

  • 启动Shell:用户登录系统或在终端窗口启动Shell。Shell显示提示符,等待用户输入命令。


  • 读取输入:Shell从终端读取用户输入的命令。用户可以输入单个命令或多个命令的组合。


  • 解析命令:Shell对用户输入的命令进行解析,识别命令、参数、选项以及输入输出重定向符号。


  • 查找命令:Shell查找并确定命令的位置。内部命令(如cd、echo)直接执行,外部命令则在指定的路径(由PATH情况变量界说)中查找对应的可执行文件。


  • 执行命令:

内部命令:Shell直接执行内部命令。
外部命令:Shell创建一个子进程,通过fork和exec系统调用执行外部命令。子进程运行完成后,返回控制权给父进程(Shell)。

  • 处理输入输出:根据用户的输入输出重定向指示,Shell将命令的标准输入、标准输出或标准错误重定向到指定的文件或装备。


  • 等待和返回效果:Shell等待命令执行完成,获取命令的退出状态,并将效果显示给用户。如果命令在后台运行,Shell立即返回提示符而不等待命令完成。


  • 处理脚本:如果输入的是脚本文件,Shell按照脚本中的命令顺序逐行读取并执行,直到脚本执行完毕。
6.3 Hello的fork进程创建过程


图42.hello执行效果展示


       首先对输入命令进行解析,发现命令第一个参数并不是内置命令,则找到hello步伐并将其存入内存中,之后执行fork()函数创建一个子进程,二者信息几乎完全雷同,区别在于两个进程的pid不同。睁开新进程后,调用execve函数在当前进程的上下文加载并运行hello步伐,最后hello内的main函数被调用并执行。
6.4 Hello的execve过程

1.调用execve:
当一个进程调用execve系统调用时,它提供要执行的步伐路径、参数和情况变量。比如,执行一个名为hello的步伐,路径是/usr/bin/hello,参数列表包罗步伐名和其他参数(如["hello"]),情况变量列表可以为空或包含键值对。

2. 内核检查和加载:
内核先检查给定的步伐路径,确保文件存在且可执行,再检查调用进程是否有执行该文件的权限,最后确认文件格式(如ELF),以确保它是可执行文件。

3. 清算当前进程状态:
根据文件形貌符的close-on-exec标志,内核关闭相应的文件形貌符,再开释当前进程的用户空间内存,清算堆、栈、数据段、代码段等。

4. 加载新步伐:
内核将新步伐的代码段、数据段等映射到进程的地址空间中,再为新步伐设置堆栈,并将参数和情况变量复制到新堆栈中。

5. 更新进程状态:
内核将步伐计数器设置为新步伐的入口地址,并重置CPU寄存器,使其符合新步伐的运行要求。进程的标识保持不变,但进程的命令行参数和情况变量更新为新步伐的。

6. 执行新步伐:
内核将控制权交给新步伐,从其入口地址开始执行。
6.5 Hello的进程执行

1. 进程创建:
(1)用户在命令行输入/usr/bin/hello并按下回车键。
(2)Shell(如Bash)调用fork()创建一个子进程,子进程是当前Shell进程的副本。
(3)子进程调用execve("/usr/bin/hello", args, env),用hello步伐替换自身的内存空间。

2. execve系统调用:
(1)子进程进入焦点态,内核执行execve系统调用。
(2)内核检查文件路径、权限和格式。
(3)内核清算子进程的当前内存空间,并加载hello步伐的代码和数据。
(4)初始化新步伐的堆栈、设置步伐计数器、寄存器,并准备将控制权交还给新步伐。

3. 调度器分配时间片:
(1)hello步伐开始执行后,利用系统调度器分配一个时间片给该进程。
(2)时间片是利用系统为每个进程分配的一段CPU执行时间,确保多任务系统中各进程公平分享CPU资源。

4. 用户态执行:
(1)hello步伐在用户态下执行,运行其main函数。
(2)步伐调用printf函数,这是一个标准库函数,会将输出请求发送到标准  输出(通常是终端)。

5. 系统调用:printf:
(1)printf函数内部调用write系统调用,将数据写入标准输出。
(2)这触发用户态到焦点态的转换,进入内核空间。
(3)内核执行实际的输出利用,将“Hello, World!”写到终端装备。
(4)完成后,内核返回用户态,继续执行hello步伐。

6. 步伐完成执行:
(1)hello步伐执行完main函数,返回退出状态(通常是0)。
(2)调用exit系统调用,通知内核进程已完成。
(3)再次触发用户态到焦点态转换,内核进行清算工作。

7. 进程停止与资源开释:
(1)内核开释进程的资源(如内存、文件形貌符等)。
(2)内核将该进程标志为停止状态,并准备调度下一个进程。

8.上下文切换:
(1)调度器选择下一个准备好运行的进程(可能是另一个用户进程或内核进程)。
(2)保存当前进程的上下文信息(寄存器状态、步伐计数器等)。
(3)恢复下一个进程的上下文信息。
(4)如果选择的进程是用户进程,内核从焦点态切换回用户态,执行新进程的代码。
6.6 hello的非常与信号处理

1. 正常运行

图43. 正常运行效果展示


       进行10次循环输出,每次间隔两秒。输出完后按恣意符号返回命令行
2. Ctrl+Z挂起


图44.Ctrl+Z挂起

       步伐处于挂起状态,这是因为ctrl+z向shell壳传递SIGTSTP信号,使得步伐被挂起。

3. fg恢复运行


图45. 输入fg恢复挂起步伐运行


      输入fg后可将后台步伐放回前台继续运行

4. Ctrl+C停止步伐运行


图46.Ctrl+C停止步伐运行效果展示


      按Ctrl+C可使步伐运行直接停止并回到命令行模式。这是因为Ctrl+C向shell壳传递了SIGINT信号,使步伐被停止,并让父进程利用Waitpid()函数等待子进程结束后,接纳子进程。

5. jobs命令


图47.jobs命令效果展示


      jobs命令可以列出目前在后台挂起的步伐,可以看到ctrl+c直接停止步伐,并没有挂在后台,而ctrl+z将步伐停止并挂在后台。

6. kill指令


图48.kill命令效果展示


      执行过程如上图所示,说明kill指令仅会向父进程传递SIGINT信号使子进程停止,而不会使得父进程利用waitpid函数等待子进程自行停止并接纳。

7.pstree指令





图49.pstree指令效果展示


      先将步伐挂起后输入pstree指令即可看到进程树。


  • 乱按

图50.乱按效果展示


乱按的文本会直接输出,但并不会对步伐本身的运行与输出造成影响。
6.7本章小结

       本章重要简述了进程的概念及作用,并简述壳的作用与处理流程,同时分析了fork函数与execve函数,给出了hello进程执行的过程并对各种非常情况可能导致的效果进行展示。

第7章 hello的存储管理

7.1 hello的存储器地址空间

1.逻辑地址
       逻辑地址是步伐员在编写步伐时利用的地址。它是指步伐内部利用的变量、函数和指令地址。逻辑地址是相对于某个基地址的偏移量,也被称为假造地址的一部门。对于一个正在运行的步伐,这些地址是在编译和链接过程中生成的。

2.线性地址
       线性地址是由逻辑地址通过段地址转换后的地址。在现代计算机系统中,段机制已经不常利用,但在保护模式下,逻辑地址首先被转换为段内偏移,然后通过段寄存器的基址加上这个偏移量,形成线性地址。

3.假造地址
       假造地址通常被用作逻辑地址的同义词。它是步伐运行时看到的地址空间,是一个连续的地址空间,由利用系统提供。每个进程有本身独立的假造地址空间,使得进程之间互不干扰。

4.物理地址
       物理地址是实际存在于计算机内存中的地址。它是由内存控制器和硬件直接利用的地址。假造地址通过页表映射到物理地址,这个映射由利用系统管理。
7.2 Intel逻辑地址到线性地址的变动-段式管理


在Intel的段式内存管理模型中,逻辑地址到线性地址的转换是通过段机制实现的。这种机制在x86架构的保护模式下被广泛利用。
段式管理将内存分为若干段,每个段有一个基地址和一个限制(长度)。每个段都形貌了一个连续的地址空间范围,段寄存器用于保存段选择符,而段选择符用于索引段形貌符表(GDT或LDT),段形貌符包含了段的基地址、段的限制和访问权限等信息。
7.3 Hello的线性地址到物理地址的变动-页式管理

在现代计算机系统中,页式管理是常用的内存管理方式,用于将线性地址转换为物理地址。这种机制使得利用系统可以高效地管理内存,并提供假造内存的支持。
在页式管理中,内存被划分为固定巨细的页和页框。线性地址通过页表映射到物理地址。每个进程都有本身的页表,由利用系统维护和管理。
7.4 TLB与四级页表支持下的VA到PA的变动

在现代利用系统中,为了更高效地管理内存和提高地址转换的速度,利用了多级页表和转换后备缓冲(TLB)。在四级页表支持下,假造地址到物理地址的转换涉及多级页表查找。通过TLB缓存最近利用的地址映射,可以大幅提高转换速度,减少多级页表查找的开销。这种机制使得利用系统能够高效地管理内存,提供假造内存的支持,同时确保系统的安全性和稳定性。
7.5 三级Cache支持下的物理内存访问

在现代计算机系统中,为了提高处理器访问内存的速度,采用了多级缓存(Cache)架构。通常包罗L1、L2和L3三级缓存。这些缓存层次结构在处理器和物理内存之间提供了一个快速的数据访问路径。
以下格式自行编排,编辑时删除
7.6 hello进程fork时的内存映射

在 Unix 系统中,当一个进程调用 fork 函数时,利用系统会创建一个新的进程(子进程),它是调用进程(父进程)的一个拷贝。这个拷贝包罗父进程的所有内存,包罗代码段、数据段、堆和栈。然而,现代利用系统通过一种称为写时复制的技能来优化这一过程。
当 fork 被调用时,利用系统会执行以下步骤:


  • 创建新的进程控制块(PCB): 利用系统为子进程创建一个新的进程控制块,此中包含子进程的 PID 和其他进程管理信息。


  • 复制父进程的假造内存空间: 子进程得到与父进程雷同的假造内存空间布局,包罗代码段、数据段、堆和栈。但是,这些假造地址映射到雷同的物理页面。


  • 设置页面为只读(共享): 利用系统将共享的物理页面标志为只读。如果父进程和子进程实验写入这些页面,将触发页面错误。

4.  处理写时复制: 当页面错误发生时,利用系统会复制该物理页面,并将写利用重定向到新的副本。这一过程确保父进程和子进程在写利用时拥有独立的页面。
7.7 hello进程execve时的内存映射

在 Unix 系统中,当一个进程调用 execve 时,利用系统会用一个新步伐替换当前进程的执行内容,而这个过程会涉及到内存映射的重新设置。execve 调用是系统调用的一部门,用于执行一个新步伐。
当一个进程调用 execve 时,利用系统会进行以下步骤来重新映射内存:


  • 卸载旧的内存映射:
当前进程的内存映射会被开释,包罗代码段、数据段、堆和栈。也就是说,旧的步伐代码和数据不再保存在内存中。


  • 加载新步伐的可执行文件:
利用系统从文件系统中加载新步伐的可执行文件,这通常是一个 ELF(Executable and Linkable Format)文件或其他可执行格式的文件。


  • 创建新的内存映射:
根据新步伐的可执行文件的格式和内容,利用系统会重新建立内存映射。详细包罗以下几个部门:
代码段(text segment):这是新步伐的呆板指令地点的内存地区,通常是只读的。
数据段(data segment):包含已初始化的全局变量和静态变量。
BSS段(Block Started by Symbol):包含未初始化的全局变量和静态变量,通常被初始化为零。
堆(heap):用于动态分配内存。
栈(stack):用于函数调用和局部变量。


  • 设置步伐入口点:
利用系统会将步伐计数器(步伐的入口点)设置为新步伐的入口地址,通常是步伐的 main 函数的起始位置。


  • 传递参数和情况变量:
利用系统会将调用 execve 时提供的参数和情况变量复制到新步伐的栈上,以便新步伐可以访问这些信息。
7.8 缺页故障与缺页中断处理

缺页故障和缺页中断处理是利用系统内存管理中的紧张概念。缺页故障发生在进程试图访问不在物理内存中的假造内存页面时。利用系统通过缺页中断处理机制来解决这个问题,将所需页面加载到物理内存中。
缺页故障可能是因为页面不存在于物理内存中、页面在交换空间中、非法访问。当 CPU 实验访问一个假造内存地址时,如果地址未被映射到物理内存页面,内存管理单元(MMU)会生成一个缺页故障。MMU 将这个非常通知利用系统,触发缺页中断处理机制。
缺页中断处理是利用系统对缺页故障的响应过程,首先利用系统保存当前进程的 CPU 状态,以便在处理完缺页中断后能够恢复进程继续执行。随后检查缺页的原因,确定所需页面是否在交换空间中,大概是非法访问。如果页面在交换空间中,利用系统找到该页面在磁盘上的位置并从磁盘读取页面数据并加载到物理内存中。如果页面从未分配,利用系统为该页面分配一个新的物理内存页面并初始化新的页面。更新页表,将假造页面映射到新分配的物理页面,同时设置得当的访问权限。最后恢复进程的 CPU 状态,并继续执行被中断的指令。
7.9动态存储分配管理

以下格式自行编排,编辑时删除

  • 基本方法
(1)堆内存分配:
malloc/free:在C语言中,malloc用于分配指定巨细的内存块,返回指向该内存块的指针。free用于开释之前分配的内存块,以便利用系统可以重用这块内存。
new/delete:在C++中,new运算符用于分配内存并调用构造函数,delete运算符用于销毁对象并开释内存。

(2)内存池(Memory Pool):
内存池是一种预先分配一大块内存,然后按需分配和开释小块内存的方法。它减少了频繁的系统调用开销,并可以通过会合管理内存来提高性能和减少碎片。


  • 动态内存管理策略
(1)初次适配:
在空闲链表中找到第一个巨细充足的空闲块进行分配。这种方法简单高效,但可能会导致空闲内存碎片化。
(2)最佳适配:
在空闲链表中找到最接近所需巨细的空闲块进行分配。这种方法可以减少内存碎片,但查找过程可能较慢。
(3)最差适配:
在空闲链表中找到最大的空闲块进行分配。这种方法旨在克制产生太多的小碎片,但实际效果可能因详细情况而异。
(4)次适配:
雷同于初次适配,但从上次分配结束的位置开始查找。它试图分散内存碎片,但可能会在链表末端产生较大的碎片。
7.10本章小结

       本章重要概述了hello的存储管理,包罗存储器的地址空间,段式管理与页式管理,以及cache的内存访问规则,并报告了应用fork和execve函数时系统的内存映射,给出缺页故障的概念并概括相识决方案——缺页中断处理。

第8章 hello的IO管理

8.1 Linux的IO装备管理方法

装备的模型化:文件
在 Linux 系统中,装备被模型化为文件。这种设计理念称为“万物皆文件”。这种方法的焦点思想是将装备抽象为文件系统中的文件,利用户和应用步伐能够通过标准的文件利用接口对装备进行利用。这些文件可以是用于顺序读写利用的装备,比方键盘、串口、终端等。也可以是用于随机读写利用的装备,比方硬盘、光驱等。
这些装备文件通常位于 /dev 目录下,比方/dev/sda表示一个硬盘装备。/dev/ttyS0:表示一个串口装备。
装备管理:unix io接口
Unix I/O 接口是 Unix 利用系统提供的一套用于文件和装备利用的标准接口。这些接口通过一组系统调用利用户步伐能够对文件、装备以及其他 I/O 资源进行读写和控制利用。
8.2 简述Unix IO接口及其函数

Linux 提供了同一的 Unix I/O 接口,使得对装备的利用雷同于对文件的利用。重要的 Unix I/O 接口函数包罗:

  • open:打开文件或装备。
  • read:从文件或装备读取数据。
  • write:向文件或装备写入数据。
  • close:关闭文件或装备。
  • ioctl:对装备进行控制利用,通常用于装备特定的利用。
通过这些接口,Linux 将装备利用同一抽象为文件利用,简化了装备管理的复杂性。应用步伐不需要关心底层硬件的实现细节,只需利用标准的文件利用接口即可完成对装备的读写和控制。

以下格式自行编排,编辑时删除
8.3 printf的实现分析


图51.printf函数

va_list是一个字符指针的重界说,即:typedef char* va_list,(char*)((&fmt) + 4 )作为第一个参数与栈的结构精密相关,&fmt存放在栈中,后续的字符型指针存于栈中,由于指针巨细位四个字节,以是+4可得到第一个参数。(32位系统指针巨细4个字节,64位系统指针巨细8个字节)

图52.vsprintf函数


      vsprintf函数将所有参数信息格式化后,返回格式化数组的长度,write函数将第i个参数信息写入终端。然后执行字符显示驱动子步伐:从ASCII到字模库到显示vram(存储每一个点的RGB颜色信息)。最后显示芯片按照刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)
8.4 getchar的实现分析


       Getchar原型代码如下:
int getchar(void)

{

static char buf[BUFSIZ];

static char* bb=buf;

static int n=0;

if(n==0)

{

n=read(0,buf,BUFSIZ);

bb=buf;

}

return (–n>=0)?(unsigned char)*bb++:EOF;

}
它可以读取缓冲区内的单个字符,在输入了大量字符后,存放于缓冲区,利用getchar函数后会从缓冲区中读取一个字符并读入。
异步非常-键盘中断的处理:键盘中断处理子步伐。接受按键扫描码转成ascii码,保存到系统的键盘缓冲区。
getchar等调用read系统函数,通过系统调用读取按键ascii码,直到接受到回车键才返回。
8.5本章小结

本章总体先容了I/O的相关内容,并分析了其管理方法,常用接口与函数,并对printf与getchar函数进行了细致的分析。



结论

       至此分析完了hello在系统由一个初始的c语言文件逐步酿成了一个可执行文件,最后运行完成的一个总体过程,下面临整个过程进行一个总结。

  • 编写c语言源代码,生成.c文件
  • 通过预处理将头文件与部门源代码结构进行替换得到.i文件
  • 将.i文件进行汇编处理得到汇编语言文件.s
  • 进一步通过汇编处理得到可重定向文件.o
  • 通过链接处理得到可执行文件hello,至此可以被运行
  • 调用fork函数创建一个子进程,为步伐的运行加载提供假造内存等须要信息。
  • 调用execve函数启动加载器映射假造内存,之后继续载入物理内存并进入main函数
  • 通过TLB等工具实现假造内存和物理内存之间的翻译,进而访问内存
  • 通过IO装备实现输入输出,与外界进行交互
  • 最终hello被其父进程接纳,内核收回为其创建的所有信息

附件

列出所有的中间产物的文件名,并予以说明起作用。

1.  hello.c: 源步伐
2. hello.i :预处理后的步伐

  • hello.s: 编译后的汇编步伐

  • hello.o:汇编后的可重定位目标文件

  • elf.txt:hello.o的ELF文件

  • dump_hello.txt:hello.o的反汇编代码

  • hello:hello.o链接后的可执行目标文件(不包含可调试选项)

  • hello1:hello.o链接后的可执行目标文件(包含可调试选项)

  • hello_objdump.s:hello的反汇编代码


参考文献

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

[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 立即注册

本版积分规则

悠扬随风

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表