execve函数在hello中加载并运行包含在可执行目标文件hello中的程序,加载并运行hello需要以下几个步骤:
节头:记录各节名称、类型、地址、偏移量、大小、全体大小、旗标、链接、信息、对齐。每个节都从0开始,用于重*。
hello反汇编的代码有确定的虚拟地址,也就是说已经完成了重*,而hello.o反汇编代码中代码的虚拟地址均为0,未完成可重*的过程。示例中,hello链接过程将函数确定了下来,指令后接的是函数名。
c程序中是用return返回函数,而在汇编语言中,采用的是ret指令,将返回地址弹出,从该地址开始执行。
终端程序通过调用fork()函数创建一个子进程,子进程得到与父进程完全相同但是*的一个副本,包括代码段、段、数据段、共享库以及用户栈。子进程还获得与父进程任何打开文件描述符相同的副本,父进程和子进程最大的不同时他们的PID是不同的。父进程与子进程是并发运行的*进程,内核能够以任意方式交替执行它们的逻辑控制流的指令。在子进程执行期间,父进程默认选项是显示等待子进程的完成。
对于高速缓存,高速缓存的组数S,每组的行数E,以及每块的大小B。那么我们就可以计算出S=2^s,B=2^b,由此计算出s和b。我们把物理地址划分为三部分,b位为块内偏移地址,紧接着s位为组索引位,剩下的就是t标记位。
编译的概念:编译器将文本文件hello.i翻译成文本文件hello.s,它包含一个汇编语言程序。以高级程序设计语言书写的源程序作为输入,而以汇编语言或机器语言表示的目标程序作为输出。
在本章中主要介绍了链接,详细阐述了hello.o是怎么链接成为一个可执行目标文件的过程,详细介绍了hello.o的ELF格式和各个节的含义,并且分析了hello的虚拟地址空间、重*过程、执行流程、动态链接过程。
callsave是为了保存中断前进程的状态。syscall将字符串中的字节从寄存器复制到显卡的显存中,显存中存储字符的ASCII码。字符显示驱动子程序将通过ASCII码在字模库中找到点阵信息将点阵信息存储到vram中。显示芯片会按照一定的刷新频率逐行读取vram,并通过信号线向液晶显示器传输每一个点(RGB分量)。打印字符串显示在了屏幕上。
(1)打开文件。一个应用程序通过要求内核打开相应的文件,来宣告它想要访问一个I/O设备,内核返回一个小的非负整数,叫做描述符,它在后续对此文件的所有操作中标识这个文件,内核记录有关这个打开文件的所有信息。
本章对hello.s进行了汇编,生成了hello.o可重*目标文件。分析了可重*文件的ELF头、节头部表、符号表和可重*节,比较了hello.s和hello.o反汇编代码的不同之处。
重*节和符号定义:链接器将所有类型相同的节合并在一起后,这个节就作为可执行目标文件的节。然后链接器把运行时的内存地址赋给新的聚合节,赋给输入模块定义的每个节,以及赋给输入模块定义的每个符号,当这一步完成时,程序中每条指令和全局变量都有唯一运行时的地址。
所有的I/O设备都被模型化为文件,而所有的输入和输出都被当作相应文件的读和写来执行。这种将设备映射为文件的方式,允许Linux内核引出一个简单,低级的应用接口,称为UnixI/O,这使得所有的输入和输出都能以一种统一且一致的方式来执行
有话要说...