第一章 计算机系统漫游(1.1-1.4)

1.1信息就是位(bit)+上下文

hello world程序:

#include <stdio.h>

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

通过文本编辑器保存的hello world程序代码文件称为源程序,扩展名为.c。文件中所有字符都是由0和1组成的位(bit)(1byte=8bit)表示,每个英文字母和标点符号都用一个字节表示(ASCII编码)。具体如下图所示。
在这里插入图片描述
源程序以字节序列的方式储存在文件中,每个字节表示一个整数值,对应特定字符。

据此程序我们可以引申一下——计算机世界的所有信息都是用0、1表示的bit序列。根据上下文的不同,一个同样的字节可能表示一个整数、浮点数、字符串或者是机器指令。

1.2 程序被其他程序翻译成不同的格式

系统只能运行打包成可执行目标程序格式的二进制磁盘文件。
在Unix系统上,由编译器驱动程序(GCC)完成从源程序到可执行目标文件(可执行目标程序)转换。这一转换可分为四个阶段,分由四个程序完成(预处理器、编译器、汇编器、连接器),它们共同组成编译系统。如下图:
在这里插入图片描述

  • 预处理阶段:根据hello程序中的#开头指令插入特定的内容。#include<stdio.h>命令告诉预处理器读取系统头文件的stdio.h的内容,并插入到源程序中。
  • 编译阶段:翻译成汇编语言。汇编语言是低级机器语言,为不同高级语言的不同编译器提供通用的输出语言。
  • 汇编阶段:翻译成机器语言指令(二进制),指令被打包成可重定位目标程序。
  • 链接阶段:调用一个名为printf.o的单独预编译好的目标文件,以满足源程序调用printf函数的需要。合并二者。得到最终的可执行目标文件。

1.4 处理器读取并解释可执行目标文件。

执行命令:

linux> ./hello
hello,world

./是指当前目录。上述执行的操作在shell程序中,shell是一个命令行解释器。如果该命令行的第一个单词不是一个内置的shell命令,shell就会把它当做可执行文件,加载并运行。
1.4.1系统的硬件组成
典型的系统硬件组成图:
在这里插入图片描述

  • 总线:贯穿整个系统的一组电子导管。携带字节信息在各个部件间传递。机器字长(32位,64位)即是总线传送定长字节块的字节数。
  • I/O设备:示例中包含四个I/O设备:键盘、鼠标、显示器、磁盘。它们都通过控制器或者适配器与I/O总线相连。控制器与适配器的主要是封装方式不同:控制器是I/O设备本身或者是主板上的芯片组。适配器是插在主板上的卡;它们负责将信息传递到I/O总线。
  • 主存:临时储存设备。处理器执行程序时,用来存放程序和程序处理的数据。物理上:主存是一组动态随机存取储存器(DRAM)芯片组成。逻辑上:是一个线性字节数组,每个字节都有数组索引(称为地址)。
  • 中央处理器(CPU),简称处理器。解释或执行主存里的指令引擎。核心是程序计数器(PC),CPU中最重要的寄存器,指向主存的某条机器语言指令的地址。寄存器文件包含一些单字长(字长取决于总线的设计)的寄存器组成。
  • 相关操作:
    ☆ 加载:从主存复制一个字节或者一个字(汉字在大部分编码格式中占两个字节)到寄存器,覆盖寄器原来的内容。
    ☆ 储存:从寄存器复制一个字节或者一个字到主存,覆盖某个位置的内容。与加载互逆。
    ☆ 操作:两个寄存器的内容被复制到ALU(算数/逻辑单元),ALU对两者做算数运算,把结果存放于一个寄存器中,覆盖原来内容。
    ☆ 跳转:从指令本身中抽取一个字,并复制到程序计数器中,覆盖原来的值。
    1.4.2运行hello程序
  • 输入字符串时“./hello”时,shell程序将字符逐一读入寄存器文件中的寄存器,再搬运到内存。如图:在这里插入图片描述
  • 按下回车键时,shell程序执行一系列指令加载可执行目标文件——hello程序。这些指令将hello目标文件中的代码和数据从磁盘复制到主存。利用直接存储器存取(DMA)技术,数据可以不通过处理器从磁盘直达内存。一旦目标文件被加载至主存,处理器就开始执行main程序中的机器语言指令。这些指令将“hello,world\n"字符串的字节从主存复制到寄存器文件(加载),再从寄存器文件中复制到显示设备,最终显示在屏幕上。如图:在这里插入图片描述
    至此,hello程序从编译到执行的生命周期结束。

猜你喜欢

转载自blog.csdn.net/ao__ao/article/details/82789905