csapp 第一章 初始计算机

CS APP

Chapter1 初识计算机

  • 系统中的所有信息——包括磁盘文件、内存中的存放的用户数据以及网络上传送的数据,都是由一串比特表示的。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。
  • hello.c的编译过程
    • 预处理阶段:把头文件的内容插入到原C程序中,通常以.o作为文件扩展名。
    • 编译阶段:编译器(ccl)将文本文件hello.i翻译成hello.s,它包含一个汇编语言程序。这个程序包含了函数main的定义。
    • 汇编阶段:汇编器(as)把hello.s翻译成机器语言指令,把这些指令打包成一种叫做“可重定位目标程序(relocatable object program)”的格式,并将结果保存再目标文件hello.o中。hello.o文件是一个二进制文件,它包含的17个字节是main函数的指令编码。如果我们在文本编辑器中打开hello.o文件,将看到一堆乱码。
    • 链接阶段:hello程序掉哟个了printf函数,它是每个C编译器都提供的标准C库中的函数。printf函数存在一个名为printf.o的单独的预编译好了的目标文件,而这个文件必须以某种方式合并到我们的hello.o中。链接器(ld)就负责处理这种合并。结果就得到hello文件,它是一个可执行目标文件,可以加载到内存中,由系统执行。
  • 理解编译器如何工作的作用:
    • 优化程序性能
    • 理解链接时出现的错误
    • 避免安全漏洞
  • 系统的硬件组成:
    • 总线:贯穿整个系统的是一组电子管道,称作总线,它携带信息字节并负责各个部分间的信息传递。通常总线被设计成传送定长字节块,也叫做字。32位:字长4个字节,64位:字长8个字节。
    • I/O设备:是系统与外部世界连接的通道。每个I/O设备都与总线相连。控制器和适配器的区别在于它们的封装方式不同。控制器是I/O设备本身或者系统的主印制电路板(即主板)上的晶体组。而适配器则是一块插在主板插槽上的卡。
    • 主存:主存是一个临时的存储设备,在处理器执行程序时,用来存放程序和程序处理的数据。
    • 处理器:
      • 加载:从主存复制一个字或者字节到寄存器,以覆盖寄存器原来的内容。
      • 存储:从寄存器复制一个字或者字节到主存的某一位置,以覆盖这个位置原来的内容。
      • 操作:把两个寄存器的内容复制到ALU,ALU对这两个字做算术运算,并将结果存放到一个寄存器中,以覆盖这个寄存器原来的内容。
      • 跳转:从指令本身中抽取一个字,并将这个字复制到程序计数器PC中,以覆盖PC原来的值。
    • 高速缓存器(cache memory,简称cache或高速缓存):作为暂时的集结区域,存放处理器近期可能会需要的信息。
  • 操作系统管理硬件

    • 操作系统的两个基本功能:
      • 防止硬件失控的应用程序滥用
      • 向应用程序提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备。
    • 几个基本的抽象概念:进程、虚拟内存、文件
    • 进程:进程是操作系统对一个正在运行的程序的一种抽象。并发运行:指的是一个进程的指令与另一个进程的指令是交错运行的。操作系统保存跟踪进程运行所需的所有状态信息。这种状态,也就是上下文,包括许多信息,比如PC和寄存器的当前值,以及主存的内容。在任何一个时刻,但处理器系统都只能执行一个进程的代码。当操作系统决定把控制全从当前进程转移到某一个新进程时,就会进行上下文的切换,即保存当前进程的上下文和切换新进程的上下文,然后将控制权给新进程。新进程就会从上次停止的地方开始。
    • 线程:一个进程实际上是由多个称为线程的执行单元组成的,每个线程都运行在进程的上下文中,并共享同样的代码和全局变量。
    • 虚拟内存:虚拟内存是一个抽象的概念,它伪每个进程提供了一个假象,即每个进程都在独占地使用主存。每个进程看到的内存都是一致的,称为虚拟地址空间。

      进程的虚拟内存空间

      • 程序代码和数据:所有的程序,代码是从同一固定的地址开始,紧接着的是和C全局变量相对应的数据位置。代码和数据区是直接按照可执行目标文件的内容初始化的。
      • 堆:代码和数据区后紧接着运行时堆,代码和数据区在进程一开始运行时就被指定了大小,堆与之不同,当调用像malloc和free这样的函数时,堆可以在运行时动态地扩展和收缩。
      • 共享库:在地址空间地中间部分是一块用来存放C标准库和数学库这样地共享库的代码和数据区。
      • 栈:位于用户虚拟地址顶部的是用户栈,编译器用它来实现函数调用。和堆一样,用户栈在程序执行期间间可以动态地扩展和收缩。特别地,每次我们调用一个函数时,栈就会增长;从一个函数返回时,栈就会收缩。
      • 内核虚拟内存:地址空间顶部的区域是为内核保留的。不允许应用程序读取这个区域的内容或者直接调用内核代码定义的函数。相反,它们必须调用内核来执行这些操作。
  • 文件:文件就是字节序列,仅此而已。
Hello World
You need to set install_url to use ShareThis. Please set it in _config.yml.

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×