计算机体系
大作业
题 目 步调人生-Hello’s P2P
专 业
学 号
班 级
学 生
指 导 教 师
计算机科学与技术学院
2025年5月
摘 要
本文深入探索了“hello”步调背后复杂而精妙的计算机体系运作机制。从步调员借助文本编辑器完成源代码编写,到预处理器解析宏定义、处理文件包含等指令天生预处理后的文件;从编译器将预处理文件转化为汇编代码,再到汇编器将其进一步转换为呆板语言的目的文件,每个步骤都环环相扣。链接器在此中扮演着关键角色,它将目的文件与库文件举行链接,天生终极可实行文件。
当我们在shell中运行该可实行文件时,操作体系通过fork函数创建新进程,并借助execve函数加载并实行步调。在此过程中,虚拟地址空间被巧妙的映射,步调得以在内存中顺利运行,期间涉及的函数调用与指令实行皆与体系精密协作。运行时,步调依据调度算法分配 CPU 时间片,访问内存,处理 I/O 操作,甚至应对用户通过键盘输入的各类信号,如Ctrl+C、Ctrl+Z等。直至步调实行完毕,子进程停止,父进程负责回收资源,内核清算相关数据结构,宣告“hello”步调生命的终结。
这一完整的生命进程,让我们清楚见证了计算机体系从软件到硬件各层面怎样协同工作,充分显现了编译器、操作体系和硬件架构的巧妙计划,也为我们深入理解计算机体系的计划与实现提供了极具价值的实践案例。
关键词:预处理、编译、汇编、链接、内存管理、信号处理
(择要0分,缺失-1分,根据内容精彩称都酌情加分0-1分)
目 录
第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简介
(1)P2P简介
源步调是hello.c;预处理:编译器的预处理器以#开头的预处理指令如#include、#define等对hello.c举行预处理操作得到修改后的源步调hello.i;编译:在编译阶段编译器将预处理后的源代转换为汇编语言代码hello.s;汇编:汇编器将汇编指令翻译成二进制情势的呆板指令,并天生目的文件hello.o,包含可重定位的呆板代码和符号表信息;链接:链接器将目的文件与所需的库文件(如标准C库)举行链接,天生可实行文件hello,可以直接在操作体系上运行;运行:在Shell中运行可实行文件hello,操作体系通过fork函数调用创建一个新的进程,为Hello步调分配独立的进程空间。
(2)O2O简介
在Shell环境下,使用相应指令来调用fork函数,从而天生一个新的子进程。随后借助execve函数实现步调的加载与运行,将其映射到对应的虚拟内存地区,分配所需的物理内存,进而运行hello步调。等hello步调实行完成之后,父进程会回收hello子进程,内核则清除与之相关的数据信息。
1.2 环境与工具
处理器:13th Gen Intel(R) Core(TM) i9-13900HX 2.20 GHz
机带RAM:16.0 GB
体系范例:64 位操作体系, 基于 x64 的处理器
软件环境:Windows 11 家庭中文版,VMware® Workstation 16 Pro,Ubuntu 20.04.4 LTS
开发与调试:vim、gdb、objump、gcc、readelf等
1.3 中间结果
附件1:hello.c
作用:源步调
附件2:hello.i
作用:预处理后天生的.i文件
附件3:hello.s
作用:经过编译器编译天生的汇编语言文件
附件4:hello.o
作用:汇编天生的可重定位的目的文件
附件5:hello.elf
作用:hello.o的elf格式,用于展示可重定位的elf文件格式
附件6:hello.asm
作用:hello.o的反汇编格式,用汇编语言的格式来观察目的文件
附件7:hello
作用:链接后天生的可实行的目的文件
附件8:hello_exe.elf
作用:hello的elf格式,用于展示可实行的elf文件格式
附件9:hello_exe.asm
作用:hello的反汇编格式,用汇编语言的格式来观察可实行的目的文件
1.4 本章小结
本章第一部门对"hello"步调举行了相对全面的概述,阐释了P2P和O2O这两个概念的意义及运作过程。第二部门详细描述了完成作业的过程中所使用的硬件环境、软件环境以及开发工具。第三部门简朴概括了从.c源文件到天生可实行文件所经历的重要步骤和流程。
(第1章0.5分)
第2章 预处理
2.1 预处理的概念与作用
预处理是指在C语言步调正式编译之前,由预处理器对源代码举行处理的过程。
预处理的作用:
- 宏定义的处理:宏定义是通过#define指令实现的,它允许用户定义一个标识符,并将其与一段代码或值关联起来。预处理器会将源代码中所有出现的宏名更换为对应的宏体。宏的本质是更换。
- 头文件包含:使用#include等指令可以将指定的头文件内容插入到当前源文件中。头文件通常包含函数声明、宏定义、数据范例定义等内容,这些内容在编译时需要被包含到源文件中,以便编译器可以或许精确地辨认和处理。
- 条件编译:根据预定义的宏或条件表达式的值来决定是否编译某段代码。
2.2在Ubuntu下预处理的下令
gcc -m64 -no-pie -fno-PIC -E hello.c -o hello.i
图 1 在Ubuntu下预处理的下令
2.3 Hello的预处理结果解析
发现经过处理之后的文件变成了3061行,3075行之前均为头文件。main函数中的代码没有被改变,而开头的头文件#include <stdio.h>#include <unistd.h> #include <stdlib.h>被扩展了许多行,除此之外原本所有的解释全部都被删除掉了
图 2 Hello的预处理结果1
图 3 Hello的预处理结果2
2.4 本章小结
本章介绍了预处理的概念和作用、Ubuntu下的预处理指令,此外还包括了hello.c文件的预处理结果hello.i的文本文件解析,详细描述了预处理的内涵。
(第2章0.5分)
第3章 编译
3.1 编译的概念与作用
编译是指编译器将预处理后的源代码转换为汇编语言代码hello.s。编译过程可以分为多个阶段,包括词法分析、语法分析、语义分析等。
编译的作用:
- 查抄语法和语义错误:如果源代码中存在语法错误或语义错误等,编译器会报错并指出错误的位置和原因。
- 代码优化:优化的目的是进步步调的运行服从和减小步调的体积。
- 天生汇编代码
3.2 在Ubuntu下编译的下令
gcc -S hello.i -o hello.s -fno-PIC -no-pie -m64
图 4 在Ubuntu下编译的下令
3.3 Hello的编译结果解析
3.3.1字符串常量
图 5 源代码中的字符串常量
储存在只读字符串中,通过标签.LC0和.LC1引用。
图 6 .LC0等引用图示
此外可以发现使用字符串常量时都是直接使用标号:
图 7 直接使用标号图示
这样做便于在后续计算地址后换为对应地址。
3.3.2局部变量
图 8 源代码中的局部变量
循环变量的i,存储在栈中,偏移量为-4(%rbp)
图 9 局部变量图示
3.3.3赋值
图 10 源代码中的赋值行为
在循环开始时对局部变量i赋值为0作为计数器。
图 11 赋值图示
3.3.4关系操作
图 12 源代码中的关系操作
本段代码共有两个关系操作,分别为判定argc是否等于5以及局部变量i是否小于10,其在汇编语言中如图:
图 13 汇编语言中的关系操作图示
即关系操作在汇编语言中均由cmp和条件跳转实现。
3.3.5范例转换
通过调用atoi函数将argv[4]的字符串转换为整数
图 14 范例转换图示
3.3.6算术操作
算术操作中的add在汇编语言中使用add举行实现,减法指令使用sub举行实现。
图 15 算术操作图示
3.3.7数组和指针操作
图 16 源代码中的数组和指针操作
在源代码中使用了argv这个数组的变量值。
图 17 汇编代码的数组和指针操作图示
可以观察到汇编代码中使用首地址加偏移量访问数组,同时指针的解引用通过movq (%rax),rax实现。
3.3.8控制转移
(1)分支结构
图 18 源代码中的分支结构
源代码中存在这样一个分支结构,其在汇编语言中的表现如下:
图 19 分支结构图示
实行流程:如果-20(%rbp)存储的argc等于5就跳过中间的语句,否则就次序实行到exit函数竣事。
(2)循环结构
图 20 源代码中的循环结构
源代码中存在这样一个循环结构,其在汇编语言中的表现如下:
图 21 循环结构图示
L4是每次循环会实行的操作。先初始化i为1,跳转到L3来举行判定,若小于等于就跳转进L4,再在L4里面实行i++的操作。次序实行到L3位置再次举行判定是否跳转,直到i>9不再跳转,次序实行退出循环。
3.3.9函数操作
(1)参数通报
printf 中的参数通过寄存器来举行通报:
图 22 参数通报图示
(2)函数调用
puts、exit、sleep的函数调用如图:
图 23 函数调用图示
printf、atoi函数调用先前已经提过,在此不再赘述
(3)函数返回
图 24 函数返回图示
恢复应由被调用者保存的寄存器的值,恢复旧的栈顶指针%rbp,跳转回原控制流地址。
3.4 本章小结
本章着重介绍了编译器将hello.i文件转换为hello.s文件的过程,起首解释了编译的寄义及其作用,然后展示了本次实验中编译所用的指令,最后分析了天生的hello.s文件中怎样举行赋值、关系操作、范例转换等操作。
(第3章2分)
第4章 汇编
4.1 汇编的概念与作用
汇编是步调开发过程中的一个重要步骤,位于编译和链接之间。汇编的重要任务是将汇编语言源代码(hello.s)转换为目的文件(hello.o)。目的文件是二进制格式的中间文件,包含了呆板语言指令和符号信息,但尚未完全预备好直接运行。
汇编的作用:
- 将汇编语言转换为呆板语言并天生.o文件
- 举行符号解析、天生重定位信息便于链接器解析
4.2 在Ubuntu下汇编的下令
gcc -m64 -no-pie -fno-PIC -c hello.s -o hello.o
图 25 在Ubuntu下汇编的下令
4.3 可重定位目的elf格式
在shell中输入readelf -a hello.o > hello.elf 指令获得 hello.o 文件的 ELF 格式。
-
- 标识字段:此字段长度为 16 字节,用于确定文件范例及结构,涵盖了文件的魔数、种别、字节次序以及 ELF 版本等相关信息。
- 文件范例:明白 ELF 文件的种类,像可实行文件、共享对象文件、目的文件等均属于此种别。
- 呆板范例:确定 ELF 文件所适配的目的呆板架构,常见的有 x86、ARM、PowerPC 等架构范例。
- 版本:给出 ELF 文件的版本编号。
- 入口地址:在可实行文件中,标明步调开始实行的入口地址。
- 步调头起点:指出步调头表在文件中的偏移位置,步调头表内包含对 ELF 文件中各段举行描述的信息。
- 节头表偏移量:确定节头表在文件中的偏移位置,节头表包含对 ELF 文件中各节举行描述的信息。
- 标志:囊括了一些用于论述文件特性的标志位。
- ELF头的巨细:明白 ELF 文件头所占的巨细。
- 步调头表中每个条目的巨细:确定步调头表中每个条目所占的巨细。
- 步调头表中条目的数目:给出步调头表中包含的条目总数。
- 节头表中每个条目的巨细:明白节头表中每个条目所占的巨细。
- 节头表中条目的数目:给出节头表中包含的条目总数。
- 字符串表的节头索引:确定节头表中字符串表节对应的索引,字符串表重要用于存储节名以及步调头表中的段名。
图 26 elf头
4.3.2节头表
记录各节名称、范例、地址、偏移量、巨细、全体巨细、旗标、链接、信息、对齐。
图 27 节头表
4.3.3重定位节
图 28 重定位节
.rel.text节是一个.text节中位置的列表。当链接器把这个目的文件和其他文件组合时,需要修改这些位置。一样平常而言,任何调用外部函数或者引用全局变量的指令都需要修改,而调用本地函数的指令不需修改。
4.3.4符号表
图 29 符号表
.symtab节中包含ELF符号表。这张符号表包含一个条目的数组,存放一个步调定义和引用的全局变量和函数的信息。
4.4 Hello.o的结果解析
4.4.1增长了指令呆板码
图 30 增长指令呆板码图示
每一条指令前面都有了该指令的呆板语言对应的16进制表示。
4.4.2标号被更换为具体地址
图 31 标号被更换为具体地址图示
可以观察到标号被更换为具体地址,即跳转的位置被表示为与类似主函数+段内偏移量的确定的地址,包括跳转、常量和函数调用。
4.4.3有重定位条目
图 32 重定位条目图示
如图所示,反汇编代码中添加了重定位条目。
本章介绍汇编的概念、作用及常用下令。深入剖析了.o文件在ELF格式下各部门的内容与格式,同时将其反汇编后的代码与.s文件举行对比,通过这样的比较可以更清楚地了解汇编语言与呆板语言的差别,从而更好地掌握汇编过程的作用。
(第4章1分)
第5章 链接
5.1 链接的概念与作用
链接位于汇编之后和步调终极天生可实行文件之前。链接的重要任务是将目的文件(hello.o)以及所需的库文件组合在一起,解析符号引用,天生终极的可实行文件(hello)。
链接的作用:
- 符号解析与地址分配: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
图 33 在Ubuntu下链接的下令
5.3 可实行目的文件hello的格式
5.3.1 elf头
观察可以发现其elf头与可重定位文件的elf头类似,但范例变为了EXEC范例,即可实行的。
图 34 elf头
5.3.2节头表
图 35 节头表
每一节的巨细偏移量和其他属性如图所示
5.3.3步调头
图 36 步调头
步调头是一个结构数组,描述了体系预备步调实行所需的段等信息。
5.3.4 Dynamic section
Dynamic section重要用于支持动态链接和共享库的使用。
图 37 Dynamic section
5.3.5重定位节
重定位节重要作用是存储重定位信息,以便在链接过程中精确地调整和转换步调中的地址和符号引用,确保步调在内存中精确运行。
图 38 重定位节
5.3.6 符号表
符号表用于存储步调中各种符号的信息,这些符号可以是函数、全局变量、静态变量等,在步调的编译、链接和调试过程中起着关键作用。
图 39 符号表
5.4 hello的虚拟地址空间
使用gdb/edb加载hello,查察本进程的虚拟地址空间各段信息,并与5.3对照分析说明。
使用gdb加载hello。
可以在hello.elf的步调头表中举行一一对应。步调头表在步调实行时使用,它可以或许告诉链接器运行时需要加载的内容,并提供动态链接信息。
图 40 info files查察
图 41 info proc mappings查察
5.5 链接的重定位过程分析
图 42 重定位过程分析
对比之后可以发现,hello和hello.o反汇编天生的代码部门完全雷同,二者的区别在于:
- 因为动态毗连器将共享库hello.c用到的函数加入到了elf中,所以链接后的反汇编文件hello1.asm中,多了.plt等函数的代码。
- 调用指令的call函数在动态链接后,可以直接找到puts@plt表举行跳转,因为在链接过程中,链接器解析了重定位条目,并计算相对间隔,修改了对应位置的字节代码为PLT 中相应函数与下条指令的相对地址。
5.6 hello的实行流程
图 43 使用的函数
从开始加载到完成实行,这些过程构成了步调的完整进程:动态链接器起首在_start中设置运行环境并调用__libc_csu_init函数,再跳转进入main函数;在main函数内部通过各自的PLT条目调用相关的标准库函数;最后依次实行__libc_csu_fini函数、_fini函数并通过exit返回操作体系。
5.7 Hello的动态链接分析
5.7.1 ELF .dynamic段关键表项
图 44 ELF .dynamic段关键表项
5.7.2未解析出息序入口处GOT条目
图 45 未解析出息序入口处GOT条目
5.7.3第一次调用printf后GOT条目(已解析)
图 46 第一次调用printf后GOT条目(已解析)
5.8 本章小结
在本章,起首论述了链接的概念和作用,展示了怎样使用下令链接并天生hello可实行文件,同时观察了hello.ELF文件,使用gdb了解了虚拟地址空间的使用,最后通过gdb论述了重定位和动态链接的过程。
(第5章1分)
第6章 hello进程管理
6.1 进程的概念与作用
进程是步调的一次动态实行实例,是操作体系举行资源分配和调度的基本单位。
进程的作用:
- 资源隔离:每个进程拥有独立的虚拟地址空间,避免相互干扰
- 并发实行的基础:在多任务操作体系中,多个进程可以并发运行,从而进步体系的资源使用率和运行服从。
- 资源管理:操作体系通过进程为单位分配CPU时间、内存等资源。
6.2 简述壳Shell-bash的作用与处理流程
作用:作为用户与内核的中介来吸收用户输入的下令,解析并调用体系功能或应用步调。
处理流程:
- 读取从键盘输入的下令
- 判定下令是否精确,且将下令行的参数改造为体系调用execve() 内部处理所要求的情势
- 终端进程调用fork() 来创建子进程,自身则用体系调用wait() 来等候子进程完成
- 当子进程运行时,它调用execve() 根据下令的名字指定的文件到目录中查找可行性文件,调入内存并实行这个下令
- 如果用户没要求后台运行(下令末端没有&号),则shell使用waitpid(或wait)等候作业停止后返回
- 如果用户要求后台运行(下令末端有&号),则shell返回
6.3 Hello的fork进程创建过程
当输入下令后,Shell会调用fork()函数创建一个子进程。子进程会获得与父进程雷同的用户级虚拟空间副本,包括数据段、代码段、共享库等,这些副本在逻辑上完全独立。此外,子进程可以访问与读写父进程打开的文件。fork()函数调用一次但返回两次:在父进程中返回子进程的PID,而在子进程中返回0。
6.4 Hello的execve过程
操作体系起首解析可实行文件的格式,将代码段和数据段加载到子进程的内存空间中,更换掉部门从父进程继续的内容。随后,它初始化步调的运行环境,设置步调的入口点,并将下令行参数和环境变量通报给步调。最后,操作体系将控制权交给步调的入口点,步调从入口函数开始实行,终极调用main()函数,从而启动hello步调的运行。
6.5 Hello的进程实行
当hello步调被加载到内存并预备实行时,操作体系会将其加入进程调度队列。根据调度算法,hello进程被分配到CPU时间片后,操作体系会保存当前运行进程的上下文信息,并切换到hello进程的上下文,恢复其寄存器状态,开始实行步调代码。
在实行过程中,hello进程可能在用户态运行用户代码,也可能因体系调用切换到核心态请求操作体系服务。
如果时间片用完或因壅闭条件停息,操作体系会将hello进程的状态设置为就绪或壅闭,并切换到其他进程运行。
hello步调实行完成,操作体系会清算其占用的资源,父进程通过wait()获取子进程的退出状态后,hello进程的生命周期竣事。
6.6 hello的异常与信号处理
图 47 正常实行
图 48 乱按、回车
屏幕上会显示按下的内容,但不影响步调的输出和实行。在实行后按下的内容会被当成指令实行。
图 49 Ctrl-C
Ctrl-C发送SIGINT信号,当父进程收到信号时竣事前台进程hello并回收。
图 50 Ctrl-Z
按下Ctrl+Z, shell父进程收到SIGSTP信号,信号处理函数的逻辑是打印屏幕回显、将hello进程挂起,通过ps下令我们可以看出hello进程没有被回收。此时可以通过fg把它挂回前台,可以看到hello进程又正常运行。
图 51 KILL
使用kill之后再输入fg发现继续实行 kill杀死了进程。
6.7本章小结
本章介绍了进程的定义与作用和shell的一样平常处理流程,较详细的分析了hello实行过程中的进程管理,以及调用fork创建新进程、调用execve实行hello、进程实行,异常与信号处理的过程。
(第6章2分)
第7章 hello的存储管理
7.1 hello的存储器地址空间
(1)逻辑地址:在Hello步调中,逻辑地址是步调中的指令和数据在编译后的地址表示,通常与步调中的变量、函数等相对位置相关。例如,在hello.c中定义的变量char *argv,其在步调中的逻辑地址可能是相对于步调起始地址的一个偏移量。
(2)线性地址:对于Hello步调来说,线性地址是经过段式管理后得到的地址,它是一个在段内的偏移量,并且该段已通过段描述符定义了基地址等信息。例如,当Hello步调的代码段被加载到内存中的某个位置后,线性地址就是从该段的基地址开始计算的偏移地址。
(3)虚拟地址:在Hello步调运行时,虚拟地址是步调所使用的地址空间中的地址,它由线性地址经过页式管理后映射到物理地址。例如,当Hello步调访问一个变量时,所使用的虚拟地址是步调中该变量对应的地址,而操作体系会负责将其映射到现实的物理地址。
(4)物理地址:物理地址是Hello步调现实在内存中的存储位置。当操作体系将Hello步调的虚拟地址映射到物理地址后,Hello步调的数据和指令就会被存储在物理内存的相应位置。
7.2 Intel逻辑地址到线性地址的变动-段式管理
在Intel的段式管理中,逻辑地址由段选择符和段内偏移量构成。段选择符用于选择相应的段描述符,该描述符包含段的基地址等信息。当Hello步调的指令通过逻辑地址访问时,CPU会根据段选择符找到段描述符,将段内偏移量加上基地址,从而得到线性地址。转换时,线性地址=段基址+偏移量。
7.3 Hello的线性地址到物理地址的变动-页式管理
在页式管理中,线性地址会被分别成页目录项、页表项和页内偏移量等部门。以x86架构为例,线性地址通常分为页目录索引、页表索引和页内偏移量。操作体系会维护页目录和页表,页目录项指向页表的物理地址,页表项指向物理页框的物理地址。当Hello步调的线性地址需要转换为物理地址时,CPU起首根据页目录索引找到对应的页目录项,从中获取页表的物理地址;然后根据页表索引找到页表项,得到物理页框的地址;最后将物理页框地址与页内偏移量组合,得到物理地址。
7.4 TLB与四级页表支持下的VA到PA的变动
在Hello步调运行过程中,TLB用于缓存虚拟地址到物理地址的映射关系。当CPU需要将虚拟地址转换为物理地址时,起首会在TLB中查找对应的映射条目。如果命中(即找到对应的映射关系),则直接使用TLB中的物理地址举行内存访问,加快了地址转换的速度。四级页表可以更高效地管理虚拟地址到物理地址的映射。以Hello步调为例,当VA需要转换为PA时,CPU会依次访问四级页表中的各个表项。从根页表开始,根据虚拟地址的不同部门渐渐定位到叶页表项,终极得到物理地址。这个过程涉及到多次内存访问,而TLB的存在就是为了减少这种访问次数,进步地址转换服从。
7.5 三级Cache支持下的物理内存访问
当代处理器通常配备了L1、L2和L3三级Cache。在Hello步调运行时,处理器起首会实验从L1 Cache中获取所需的数据或指令。如果L1 Cache未命中,则依次访问L2和L3 Cache,直至找到所需数据或从物理内存中读取。当Hello步调的物理地址确定后,处理器会根据该地址在物理内存中查找相应的数据或指令。为了加快访问速度,操作体系和硬件会将频繁访问的数据或指令存储在Cache中。例如,当Hello步调中的一个循环频繁访问某个变量时,该变量地点的物理内存块可能会被加载到L1 Cache中,以便下次访问时可以快速获取。
7.6 hello进程fork时的内存映射
父进程实行fork函数天生hello子进程时,内核先给新进程安排独立PID,同时复制父进程的虚拟内存结构。共享的物理页面先设为只读模式,地区属性定义为私有且开启写时复制功能。此时,父子进程的虚拟地址空间完全一样,共享所有物理页面。后续只要有一个进程想改写内存,比如改全局变量,CPU就会因只读页面被写而触发异常。内核接管后,会开发新物理页面,把原页面内容拷贝已往,更新当进步程页表指向新页面,并取消只读限制,允许写入操作。
7.7 hello进程execve时的内存映射
当实行execve()体系调用时,Hello进程会用新的步调(如另一个可实行文件)更换当进步程的地址空间。此时,操作体系会根据新步调的可实行文件重新映射内存。操作体系会将新步调的代码段、数据段等加载到Hello进程的虚拟地址空间中。同时,操作体系会设置相应的页表等结构,以便将虚拟地址转换为物理地址。新的物理内存页面会被分配给这些段,以便步调可以或许正常运行。
7.8 缺页故障与缺页中断处理
在Hello步调运行过程中,当访问的虚拟地址对应的物理页面不在内存中时,就会发生缺页故障。发生缺页故障时,CPU会停息当前指令的实行,并触发缺页中断。操作体系会处理这个中断,起首确定是否是一个有效的页面引用。如果是有效的,则操作体系会从磁盘或其他存储设备中将相应的页面调入物理内存。如果内存已满,可能需要使用页面置换算法(如LRU)来选择一个页面举行更换。处理完成后,CPU会恢复被中断的指令,继续实行Hello步调。
7.9动态存储分配管理
Printf会调用malloc,请简述动态内存管理的基本方法与策略。(此节课堂没有讲授,选做,不算分)
7.10本章小结
本章详细介绍了计算机体系的存储管理机制。起首论述了逻辑地址、线性地址、虚拟地址和物理地址的概念与相互转换过程。接着讲解了Intel段式管理和页式管理下地址变动的原理,以及TLB和四级页表在进步地址转换服从中的作用。然后介绍了三级Cache怎样加快物理内存访问。在进程管理方面,解释了fork和execve体系调用的内存映射机制,以及写时复制策略的高效性。最后探讨了缺页故障处理过程。团体上,本章全面展示了Hello步调从编译到运行的存储管理全过程,揭示了计算机体系存储机制的高效与复杂。
(第7章 2分)
第8章 hello的IO管理
8.1 Linux的IO设备管理方法
(以下格式自行编排,编辑时删除)
设备的模型化:文件
设备管理:unix io接口
8.2 简述Unix IO接口及其函数
(以下格式自行编排,编辑时删除)
8.3 printf的实现分析
(以下格式自行编排,编辑时删除)
[转]printf 函数实现的深入剖析 - Pianistx - 博客园
从vsprintf天生显示信息,到write体系函数,到陷阱-体系调用 int 0x80或syscall等.
字符显示驱动子步调:从ASCII到字模库到显示vram(存储每一个点的RGB颜色信息)。
显示芯片按照刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)。
8.4 getchar的实现分析
(以下格式自行编排,编辑时删除)
异步异常-键盘中断的处理:键盘中断处理子步调。继承按键扫描码转成ascii码,保存到体系的键盘缓冲区。
getchar等调用read体系函数,通过体系调用读取按键ascii码,直到继承到回车键才返回。
8.5本章小结
(第8章选做 0分)
结论
hello步调的一生回顾:
- 源代码编写:使用文本编辑器编写 C 源代码文件 hello.c。
- 预处理:编译器的预处理器解析 hello.c 文件中的宏定义、文件包含指令(如 #include)和条件编译指令,天生预处理后的文件 hello.i。
- 编译:编译器将 hello.i 文件编译成汇编语言文件 hello.s。在此阶段,编译器举行词法、语法和语义分析,并天生中间代码。
- 汇编:汇编器将 hello.s 文件转换成呆板语言的目的文件 hello.o。该文件包含步调的二进制表示,但尚未链接。
- 链接:链接器将 hello.o 文件与体系库和其他目的文件链接,天生可实行文件 hello。链接器办理符号引用,举行重定位和动态解析。
- 运行预备:用户在 shell 中输入下令 ./hello 来运行步调。shell 查抄下令是否为内置指令,若不是,则调用 fork 函数创建新进程。
- 进程创建与步调加载:新创建的子进程调用 execve 函数加载并实行 hello 步调。execve 更换当进步程的内存映像,加载步调到内存并预备实行。
- 步调实行:操作体系调度器分配 CPU 时间片给进程。步调在 CPU 上实行,访问内存,并举行 I/O 操作。
- 信号处理:步调运行期间,用户可通过键盘输入发送信号,操作体系会调用相应的信号处理函数来停息、制止或挂起进程。
- 步调停止:步调实行完毕后,子进程停止。父进程通过 wait 体系调用回收子进程的资源,内核清算为该进程分配的所有数据结构。
感想:
hello 步调的一生从源代码的编写开始,经历预处理、编译、汇编、链接等阶段天生可实行文件,随后在操作体系中被加载、实行、调度,直至终极停止和资源回收。这一过程展示了计算机体系从软件到硬件各层面的协同工作,体现了编译器、操作体系和硬件架构的计划精妙。
计算机体系巨大而复杂,即使是一个看似简朴的hello步调,当我们在IDE中运行,计算机后台也是发生了许多未曾想象想象的过程。通过学习这门课,我开端了解了计算机体系,但是仍旧需要在以后的学习中加深对其的理解和感悟。
(结论0分,缺失-1分)
附件
附件1:hello.c — C语言源步调
附件2:hello.i — 预处理输出(扩展宏、睁开头文件后天生的.i文件)
附件3:hello.s — 编译器天生的汇编代码
附件4:hello.o — 汇编后天生的可重定位目的文件
附件5:hello.elf — 展示可重定位的elf文件格式
附件6:hello.asm — 用汇编语言的格式来观察可重定位的目的文件
附件7:hello — 终极链接天生的可实行文件
附件8:hello1.elf — 可实行文件的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企服之家,中国第一个企服评测及商务社交产业平台。
|