第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的结果解析
通过objdump指令可以看到hello.o文件的.text段的具体情况,此时的.text段只是一串
③全局变量的引用对比
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进程创建过程
Hello的执行是通过在终端中输入./Hello来完成的。接下来shell会执行fork函数。for
6.4 Hello的execve过程
在父进程fork后,父进程重拾自己的老本行,继续运行shell的程序,而子进程将通过execve加载
对于正在运行的Hello来说,除了自己的父进程是Shell之外,其它的一切都与调度运行没有区别。
6.5 Hello的进程执行
在Hello进程执行的时候,操作系统为其维持着上下文。Hello进程就是在其上下文中稳定运行的。
上下文是内核重新启动一个被抢占的进程所需的状态,它由一些对象的值组成,这些对象包括通用目的寄存器、浮
Hello进程在内存中执行的过程中,并不是一直占用着cpu的资源。因为当内核代表用户执行系统调用时,
6.6 hello的异常与信号处理
当程序正常执行直到结束时,显示如下:
如果在程序运行时按下ctrl+z,会产生如下情况:
由于键盘输入的ctrl+z给程序传入了一个SIGSTP信号,这个信号使程序暂时挂起。此时可以输入p
6.7本章小结
第7章 hello的存储管理
7.1 hello的存储器地址空间
逻辑地址:包含在机器语言中用来指定一个操作数或一条指令的地址。每一个逻辑地址都由一个段(segmen
Linux中逻辑地址等于线性地址。因为Linux所有的段(用户代码段、用户数据段、内核代码段、内核数
虚拟地址将贮存看成是一个存储在磁盘上的地址空间的高速缓存,再主存中只保存活动区域,并根据需要再磁盘和
而物理地址则是对应于主存的真实地址,是能够用来直接在主存上进行寻址的地址。几乎无法直接用物理地址直接
7.2 Intel逻辑地址到线性地址的变换-段式管理
在多段模式下,每个程序都有自己的局部段描述符表,而每个段都有独立的地址空间在80386 的段机制中,
(1)段的基地址(Base Address):在线性地址空间中段的起始地址。
(2)段的界限(Limit):表示在逻辑地址中,段内可以使用的最大偏移量。
(3)段的属性(Attribute):表示段的特性。例如,该段是否可被读出或写入,或者该段是否作为一
7.3 Hello的线性地址到物理地址的变换-页式管理
虚拟内存被组织为一个由存放在磁盘上的N个连续的字节大小的单元组成的数组。每字节都有一个唯一的虚拟地址
7.4 TLB与四级页表支持下的VA到PA的变换
7.5 三级Cache支持下的物理内存访问
不同存储技术的访问时间差异很大,速度较快的计数每字节的成本要比速度较慢的计数高,而且容量较小。计算的
三级Cache的核心思想就是每次访问数据的时候都将一个数据块存放到更高一层的存储器中,根据计算的局部
7.6 hello进程fork时的内存映射
当fork函数被当前进程调用的时候,内核会为新进程创建各种数据结构,并分配给它一个唯一的PID。为了
7.7 hello进程execve时的内存映射
这个过程有以下几个步骤:
2.映射私有区域:为新程序的代码、数据、bss和栈区域创建新的区域结构。所有这些新的区域
7.8 缺页故障与缺页中断处理
当CPU想要读取虚拟内存中的某个数据,而这一片数据恰好存放在主存当中时,就称为页命中。相对的,如果D
7.9动态存储分配管理
7.10本章小结
第8章 hello的IO管理
8.1 Linux的IO设备管理方法
8.2 简述Unix IO接口及其函数
1.打开文件。一个应用程序通过要求内核打开相应的文件,来宣告它想要访问一个I/O设备。内核返回一个小
2.Linux创建的每个进程开始时都有三个打开的文件:标准输入(描述符为0)、标准输出(描述符为1)
3.改变当前的文件位置。对于每个打开的文件内核保持着一个文件位置k,初始为0.这个文件位置是从文件开
4.读写文件。一个读操作就是从文件复制n>0个字节到内存,从当前文件位置k开始,然后将k增加到k+n
5.关闭文件。当应用完成了对文件的访问之后,它就通知内核关闭这个文件。作为响应,内核释放文件打开时创
unix io 函数(需要包含头文件
int open(char *filename, int flags, mode_t mode);
open函数将filename转换为一个文件描述符,并且返回描述符数字,返回的描述符总是在进程中当前
O_RDONLY 只读
O_WRONLY 只写
O_RDWR 可读可写
O_CREAT 如果文件不存在,就创建它的一个截断的文件
O_TRUNC 如果文件已存在,就截断它
O_APPEND 在每次写操作前,设置文件位置到文件的结尾处
int close(int fd) 关闭一个打开的文件
ssize_t read(int fd, const void *buf, size_t n)
从描述符为fd的当前文件位置复制最多n个字节到内存位置buf。返回值-1表示一个错误,而返回值0表示
ssize_t write(int fd, const void *buf, size_t n) 从
8.3 printf的实现分析
需要注意,这里的系统调用试运行在内核模式中的。
接下来,系统已经确定了所要显示在屏幕上的符号。根据每个符号所对应的ascii码,系统会从字模库中提取
显卡使用的内存分为两部分,一部分是显卡自带的显存称为VRAM内存,另外一部分是系统主存称为GTT内存
translation table和后面的GART含义相同,都是指显卡的页表,GTT
内存可以就理解为需要建立GPU页表的显存)。在嵌入式系统或者集成显卡上,显卡通常是不自带显存的,而是
显示芯片按照刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)。
8.4 getchar的实现分析
8.5本章小结
结论
附件
参考文献