CSAPP-深入理解计算机系统-task01计算机系统漫游

计算机系统漫游(上)

1.hello world程序的创建-运行-退出的流程

hello world程序从编写到最终执行结束需要经过下面这4个步骤:
-创建/create
-编译/compile
-运行/run
-退出/exit
创建的代码如下,保存为hello.c的文件:

#include<stdio.h>

int main(void) {
    printf("hello, world");
    return 0;
}

编译部分:通过gcc -o hello hello.c命令完成对源代码的编译,生成可执行程序hello
运行部分:在shell命令行终端中输如 ./hello,就可以执行程序

2.编译部分具体内容

通过gcc -o hello hello.c命令完成对源代码的编译,生成可执行程序hello,这个过程中编译系统的处理大致可以分为四个阶段,分别为:预处理、编译、汇编以及链接。

2.1预处理

预处理器会在以#开头的代码处进行修改,例如hello程序中引入了头文件 stdio.h ,预处理器会读取该头文件中的内容,将其中的内容直接插入到源程序中,结果就得到了另外一个 C 程序,这个经过预处理器处理后得到的文件通常以 .i 结尾. hello.c 经过预处理器后得到 hello.i,这个 hello.i 仍旧是一个文本文件。

2.2编译

编译器将hello.i文件翻译成hello.s文件。这一阶段包括词法分析、语法分析、语义分析、中间代码生成以及优化等等一系列的中间操作。感兴趣的可以了解一下《编译原理》。

2.3汇编

汇编器根据指令集将汇编程序 hello.s 翻译成机器指令,并且把这一系列的机器指令按照固定的规则进行打包,得到可重定位目标文件 hello.o 。此时 hello.o 虽然是一个二进制的文件,但是还不能执行。

2.4链接

在 hello.c 这个程序中,我们调用了printf 函数,printf 函数在是在名为 printf.o 的文件中,这个文件是一个提前编译好的目标文件,链接器(ld)负责把 hello.o 和 printf.o 进行合并。因为链接器要遵循一定规则对 hello.o 和 printf.o 的进行调整,所以 hello.o 才会被称之为可重定位目标文件。最终,hello.o经过链接阶段可以得到可执行目标文件 hello。此时,得到的 hello 就可以被加载到内存中执行了。

2.系统的硬件组成

在这里插入图片描述

2.1CPU

中央处理单元(Central Processing Unit , CPU) ,也称处理器,包含 PC ( 程序计数器:Program Count ) 、寄存器堆(Register file) 、ALU(算数/逻辑计算单元:Arithmatic/logic Unit)三个部分.

  • 程序计数器 PC:是一个 4 字节或是 8 字节的存储空间,里面存放的是某一条指令的地址。从系统上电的那一瞬间,直到系统断电,处理器就不断地在执行PC 指向的指令,然后更新 PC,使其指向下一条要执行的指令(注意:这个下一条指令与刚刚执行的指令不一定是相邻的)
  • 寄存器:可以理解为一个临时存放数据的空间。例如计算两个变量 a+b 的和,处理器从内存中读取 a 的值暂存在寄存器 X 中,读取 B 的值暂存在寄存器 Y中,这个操作会覆盖寄存器中原来的数值,处理器完成加载的操作后,ALU(Arithmatic/logic Unit)会从复制寄存器 X 和 Y 中保存的数值,然后进行算术运算,得到的结果会保存到寄存器 X 或者寄存器 Y 中,此时寄存器中原来的数值会被新的数值覆盖。
  • 算数/逻辑计算单元 ALU:计算速度极快,且专攻算数与逻辑的计算,计算机核心部分。

2.2主存(内存)

主存(Main Memory) ,也称为内存、运行内存,处理器在执行程序时,内存主要存放程序指令以及数据。从物理上讲,内存是由随机动态存储器芯片组成;从逻辑上讲,内存可以看成一个从零开始的大数组,每个字节都有相应地址.

2.3总线

内存和处理器之间通过总线来进行数据传递。实际上,总线贯穿了整个计算机系统,它负责将信息从一个部件传递到另外一个部件。通常总线被设计成传送固定长度的字节块,也就是字(word) ,至于这个字到底是多少个字节,各个系统中是不一样的,32 位的机器,一个字长是 4 个字节;而 64 位的机器,一个字长是 8 个字节.

2.4输入输出设备(I/O)

除了处理器,内存以及总线,计算机系统还包含了各种输入输出设备,例如键盘、鼠标、显示器以及磁盘等等。每一个输入输出设备都通过一个控制器或者适配器与IO 总线相连.
区别:控制器与适配器主要区别是在于它们的封装方式,无论是控制器还是适配器,它们的功能都是在 IO 设备与 IO 总线之间传递数据.

3.程序执行

3.1操作过程

hello.c 经过编译系统得到可执行目标文件 hello,此时可执行目标文件 hello 已经存放在系统的磁盘上,那么,如何运行这个可执行文件呢?
在 linux 系统上运行可执行程序:打开一个 shell 程序,然后在 shell 中输入相应可执行程序的文件名:
linux>./hello

shell 是什么?
shell 是一个命令解释程序,如果命令行的第一个单词不是内置的 shell 命令,shell就会对这个文件进行加载并运行. 此处,shell 加载并且运行 hello 程序,屏幕上显示hello,world 内容,hello 程序运行结束并退出,shell 继续等待下一个命令的输入.

3.2程序执行流程

(1)首先我们通过键盘输入” ./hello” 的字符串,shell 程序会将输入的字符逐一读入寄存器,处理器会把 hello 这个字符串放入内存中。
(2)当我们完成输入,按下回车键时,shell 程序就知道我们已经完成了命令的输入,然后执行一系列的指令来来加载可执行文件 hello。
(3)这些指令将 hello 中的数据和代码从磁盘复制到内存。数据就是我们要显示输出的”hello , world\n” ,这个复制的过程将利用 DMA(Direct Memory Access)技术,数据可以不经过处理器,从磁盘直接到达内存。
(4)当可执行文件 hello 中的代码和数据被加载到内存中,处理器就开始执行 main函数中的代码,main 函数非常简单,只有一个打印功能。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4.设备容量

通常情况下,大容量的存储设备的存取速度要比小容量的慢,运行速度更快的设备的价格相对于低速设备要更贵。例如:在一个系统上,磁盘的容量一般为 TB 级,内存的容量一般为 GB 级,磁盘的容量大概是内存的 1000 倍。
在这里插入图片描述

4.1高速缓存(Cache)

对于处理器而言,从磁盘上读取一个字所花费的时间开销比从内存中读取的开销大1000 万倍。寄存器文件的只能存储几百个字节的信息,而内存的可以存放几十亿的字节信息(GB 级) ,从寄存器文件读取数据比从内存读取差不多要快 100 倍。
随着半导体技术的发展,处理器与内存之间的差距还在持续增大,针对处理器和内
存之间的差异,系统设计人员在寄存器文件和内存之间引入了高速缓存(cache) ,比较新的,处理能力比较强的处理器,一般有三级高速缓存,分别为 L1 cache ,L2cache 以及 L3 cache。
L1 cache 的访问速度与访问寄存器文件几乎一样快,容量大小为数万字节(KB 级别) ;L2 cache 的访问速度是 L1 cache 的五分之一,容量大小为数十万到数百万字节之间;L3 cache 的容量更大,同样访问速度与 L2 cache 相比也更慢。

4.2存储设备的层次结构

整个计算机系统的信息存储可以用一个层次结构来表示,通常而言,存储容量越小,速度越快,价格越高,上一层存储设备是下一层存储设备的高速缓存.
在这里插入图片描述

计算机系统漫游(下)

1.操作系统的作用

无论是 shell 程序还是 hello 程序都没有直接访问键盘、显示器、磁盘这些硬件设备,真正操挫硬件的是操作系统,我们可以把操作系统看成是应用程序和硬件之间的中间层,所有的应用程序对硬件的操作必须通过操作系统来完成。
在这里插入图片描述
这样设计的目的主要有两个:
1 防止硬件被失控的应用程序滥用;
2 操作系统提供统一的机制来控制这些复杂的底层硬件.

为了实现上述的功能,操作系统引入了几个抽象的概念。例如:文件是对 IO 设备的抽象;虚拟内存是对内存和磁盘 IO 的抽象;进程是对处理器、内存以及 IO 设备的抽象。
在这里插入图片描述

2.进程

假设示例场景中只有两个并发的进程:shell 进程和 hello 进程
1 最开始的时候,只有 shell 进程在运行,即 shell 在等待命合行的输入。
2 当我们通过 shell 进程加载 hello 进程时,shell 进程通过系统调用来执行我们的请求,系统调用会将控制权从 shell 进程传递给操作系统,操作系统保存 shell进程的上下文,然后创建一个新的 hello 进程及其上下文,然后将控制权转交给新的 hello 进程。
3 hello 进程执行完之后,操作系统就会恢复 shell 进程的上下文,并将控制权交给 shell 进程,之后 shell 进程继续等待下一个命令的输入。
4 操作系统会跟踪进程运行所需要的所有状态信息,这种状态,称为上下文(Context) 。例如当前 PC 和寄存器的值,以及内存中的内容等等。
在这里插入图片描述
在这里插入图片描述

3.虚拟内存

操作系统为每个进程提供了一个假象,就是每个进程都在独自占用整个内存空间,每个进程看到的内存都是一样的,我们称之为虚拟地址空间
在这里插入图片描述
1.第一个区域是用来存放程序的代码和数据的,这个区域的内容是从可执行目标文件中加载而来的,例如我们多次提到的 hello 程序。对所有的进程来讲,代码是从固定的地址开始。至于这个读写数据区域放的是什么数据呢?例如在 C语言中,全局变量就是存放在这个区域.
2.顺着地址增大的方向,继续往上看就是堆(heap) ,学过 C 语言的同学应该用过malloc 函数,程序中 malloc 所申请的内存空间就在这个堆中。程序的代码和数据区在程序一开始的时候就被指定了大小,但是堆可以在运行时动态的扩展和收缩.
3.接下来,就是共享库的存放区域。这个区域主要存放像 C 语言的标准库和数学库这种共享库的代码和数据,例如 hello 程序中的 printf 函数就是存放在这里.
4.继续往上看,这个区域称为用户栈(user stack) ,我们在写程序的时候都使用过函数调用,实际上函数调用的本质就是压栈。这句话的意思是:每一次当程序进行函数调用的时候,栈就会增长,函数执行完毕返回时,栈就会收缩。需要注意的是栈的增长方向是从高地址到低地址.
5.最后,我们看一下地址空间的最顶部的区域,这个区域是为内核保留的区域,应用程序代码不能读写这个区域的数据,也不能直接调用内核中定义的函数,也就是说,这个区域对应用程序是不可见的.

4.文件

Linux 系统的哲学思想是:一切皆为文件。
在这里插入图片描述
所有的 IO 设备,包括键盘,磁盘,显示器,甚至网络,这些都可以看成文件,系统中所有的输入和输出都可以通过读写文件来完成.
虽然文件的概念非常简单,但却非常强大。例如︰当程序员需要处理读写磁盘上的文件时,他们不需要了解具体的磁盘技术,同一个程序,可以在不同磁盘技术上的不同系统上运行.

5.系统之间利用网络通信

随着互联网的发展,从一台计算机发送消息到另外一台计算机已经成为非常普遍的应用。 《深入理解计算机系统》中讲述了如何使用本地计算机上的 telnet 客户端连接远程主机上的 telnet 服务器。
由于 telnet 的安全性问题,目前 ssh 的连接方式的更加普遍。当我们在 ssh 的客户端中输入 hello 字符串并且敲下回车之后,客户端的软件就会通过网络将字符串发送到 ssh 服务端,ssh 服务端从网络端接收到这个字符串以后,会将这个字符串传递给远程主机上的 shell 程序,然后 shell 负责 hello 程序的加载,运行结果返回给 ssh 的服务端,最后 ssh 的服务端通过网络将程序的运行结果发送给 ssh 的客户端,ssh 客户端在屏幕上显示运行结果。
在这里插入图片描述

参考:Datawhale开源社区

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 深入理解计算机系统(CSAPP)是由Randal E. Bryant和David R. O'Hallaron编写的经典计算机科学教材。该教材通过涵盖计算机体系结构、机器级别表示和程序执行的概念,帮助学生深入理解计算机系统的底层工作原理和运行机制。 深入理解计算机系统的练习题对于学生巩固并应用所学知识非常有帮助。这些练习题涵盖了计算机硬件、操作系统和编译器等多个领域,旨在培养学生解决实际问题和设计高性能软件的能力。 对于深入理解计算机系统的练习题,关键是通过实践进行学习。在解答练习题时,应根据课本提供的相关知识和工具,仔细阅读问题描述,并根据实际需求设计相应的解决方案。 在解答练习题时,需要多角度思考问题。首先,应准确理解题目要求,并设计合适的算法或代码来解决问题。其次,应考虑代码的正确性和效率,以及对系统性能的影响。此外,还要注意处理一些特殊情况和异常情况,避免出现潜在的错误或安全漏洞。 解答练习题的过程中,应注重查阅相关资料和参考优秀的解答。这可以帮助我们扩展对问题的理解,并学习他人的思路和解决方法。同时,还可以通过与同学和老师的讨论,共同探讨问题和学习经验。 总之,通过解答深入理解计算机系统的练习题,可以帮助学生巩固所学知识,同时培养解决实际问题和设计高性能软件的能力。这是一个学以致用的过程,可以加深对计算机系统运行机制和底层工作原理的理解。 ### 回答2: 理解计算机系统(CSAPP)是一本经典的计算机科学教材,通过深入研究计算机系统的各个方面,包括硬件、操作系统和编程环境,对于提高计算机科学专业知识与能力具有很大帮助。 练习题是CSAPP中的重要部分,通过练习题的完成,可以加深对计算机系统的理解,并将理论知识转化为实践能力。练习题的数量、难度逐渐递增,从简单的概念与基础问题到复杂的系统设计与实现。 在解答练习题时,首先需要对题目进行仔细阅读和理解,明确题目的要求和限制条件。然后,可以利用课堂讲解、教材内容、网络资源等进行查阅和学习相应的知识。同时,还可以参考课后习题解答等资料,了解一些常见的解题方法和思路。 在解答练习题时,可以利用计算机系统的工具和环境进行实际测试和验证。例如,可以使用调试器、编译器和模拟器等工具对程序或系统进行分析和测试。这样可以更加深入地理解问题的本质,并找到恰当的解决方法。 另外,解答练习题时还可以与同学、教师和网上社区进行交流和讨论。这样可以互相学习和交流解题思路,共同解决问题。还可以了解不同的解题方法和技巧,提高解题效率和质量。 练习题的解答过程可能会遇到一些困难和挑战,例如理论知识的不足、复杂问题的分析与解决。但是通过不断地思考和实践,相信可以逐渐提高解题能力,更好地理解计算机系统。 总之,深入理解计算机系统(CSAPP)练习题是提高计算机科学专业知识和能力的重要途径。通过仔细阅读和理解题目,查阅相关知识,利用计算机系统工具和环境进行实践,与他人进行交流和讨论,相信可以更好地理解计算机系统的各个方面,并将知识转化为实际能力。 ### 回答3: 《深入理解计算机系统(CSAPP)》是计算机科学领域的经典教材之一,对于深入理解计算机系统的原理、设计和实现起到了极大的帮助。在阅读这本书的过程中,书中的习题也是非常重要的一部分,通过做习题,我们可以更好地理解书中所讲的概念和思想。 CSAPP的习题涵盖了课本中各个章节的内容,从基础的数据表示和处理、程序的机器级表示、优化技术、程序的并发与并行等方面进行了深入探讨。通过解答习题,我们可以对这些知识进行实践应用,巩固自己的理解,并培养自己的解决问题的思维方式。 在解答习题时,我们需要充分理解题目要求和条件,并从知识的角度进行分析。有些习题可能需要进行一些编程实践,我们可以通过编程实现来验证和测试我们的思路和解决方案。在解答问题时,我们还可以查阅一些参考资料和网上资源,充分利用互联网的学习资源。 在解答习题时,我们需要保持积极的思维和态度。可能会遇到一些困难和挑战,但是通过坚持和努力,我们可以克服这些困难,提高我们的解决问题的能力。同时,我们还可以通过与同学或者其他人进行讨论,相互分享解题经验和思路,从而更好地理解问题。 综上所述,通过深入理解计算机系统(CSAPP)的习题,我们可以进一步巩固和深化对计算机系统的理解。掌握这些知识,不仅可以提高我们在计算机领域的能力,还可以为我们未来的学习和职业发展奠定重要的基础。因此,认真对待CSAPP的习题,是我们在学习计算机系统知识中不可或缺的一部分。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值