程序是怎样跑起来的
PS:超级感谢师兄把这本书借给我,因为我的硬件基础实在是太差,这本书让我对硬件、操作系统有了个基本的概念。
这篇博就是记录读书笔记,有些章节我比较熟悉,就跳过了
一、CPU
1.CPU内部结构
- 寄存器:暂存指令、数据
- 控制器:将内存中的指令、数据读入寄存器,根据运算结果控制计算机(如显示器的输入输出)
- 运算器:计算寄存器里的数据
- 时钟:发出CPU开始计时的时钟信号,CPU运行速度
对于程序员而言,CPU的关注点在各种功能的寄存器
2.程序计数器
程序计数器是CPU寄存器的一种,CPU每执行一条指令,程序计数器的值加1,若执行指令占据多个内存地址,增加相应的数值,即程序计数器存储的是指令地址。
3.条件分支和循环机制
程序流程:顺序执行、条件分支、循环
4.函数调用机制
(1)CALL指令:将调用函数后面的指令地址放到内存的栈里
(2)程序计数器被设定为要调用的函数的入口地址
(3)RETURN指令:调用函数执行完后,把栈里的地址取出,将程序计数器设定为该地址
5.内存地址的查看
内存地址通过基址寄存器+变址寄存器来查看更方便,相当于二维数组的索引。
6. CPU能直接识别和执行的只有机器语言
二、计算机信息用二进制数表示
1.内存和磁盘都是用字节单位来存储和读写数据,所以字节是信息的基本单位,位是最小单位
2.计算机中的小数计算错误:是因为有些十进制的小数无法转换为二进制数
举个例子:十进制0.1转为二进制会变成0.00011001100……(1100循环) 。实际上,计算机不会这样处理小数。
3.计算机中小数的表示:定点数和浮点数
- 定点数:小数点需要固定到某个位置,可以自己在程序中指定,前面的是整数,后面的是小数。
- 浮点数:由符号、尾数、基数、指数四部分组成
双精度浮点数64位(double),单精度浮点数32位(float)
最高位是符号,接着是指数E,剩下的是尾数M,其中基数为2
4.正则表达式
尾数:用的是将小数点前面的值固定为1的正则表达式
因为浮点数可以用不同的数值表示同一数值,所以需要制定统一的规则
1 | 1011.0011 |
5.EXCESS系统
指数:用的是EXCESS系统表,为的是表示负数时不使用符号位(通过将指数部分表示范围的中间值设为0)
举个例子:ABCDEFG D表示0,那么E表示1,C表示-1
三、内存
1.内存的物理机制
内存IC中有电源、地址信号、数据信号、控制信号 (读写操作)。
内存,包括随机存储器(RAM),只读存储器(ROM),以及高速缓存(CACHE)。 只不过因为RAM是其中最重要的存储器。 通常所说的内即指电脑系统中的RAM。
2.数据在内存中的存储
数据类型在内存中看就是,占据内存的大小(当然符号位先不管)
字节序
- Big endian :按照从低地址到高地址的顺序存放数据的高位字节到低位字节
- Little endian:按照从低地址到高地址的顺序存放据的低位字节到高位字节
3.指针
存储数据的内存地址
char *d
char 表示一次能从地址中读取一个字节的数据
long *l
long 表示一次能从地址中读取四个字节的数据
4.数组
数组和内存的物理构造是一样的,数组使编程工作更高效
5.栈、队列、环形缓冲区(不需要指定地址和索引)
栈:数据只能在栈顶插入(push)或删除(pop) ,对内存中的数据读写 LIFO (last in first out)
队列:队尾插入数据,队头删除数据 ,对内存中的数据读写 FIFO (first in first out)
队列一般是以环状缓冲区的形式实现,使数据的写入和读出循环起来
6.链表
使元素插入、删除更容易,不像数组那样需要一部分数据整体都移动
7.二叉查找树(数据搜索)
在链表的基础上插入、删除元素,考虑数据大小,将其分成左右两个方向
四、磁盘
1.内存和磁盘
都可以用来存储程序命令和数据。
- 内存:用电流来实现存储,高速小容量
- 磁盘:用磁效应来实现存储,低速高容量
内存主要是指主内存 (存储CPU中运行的程序指令和数据),磁盘主要是指硬盘
2.存储程序方式 (程序内置方式)
磁盘中存储的程序,必须要加载到内存才能运行,因为CPU运行和解析程序的时候要通过程序计数器指定内存地址来读取程序
3.磁盘缓存 (假想的磁盘)
磁盘缓存:从磁盘中读取数据到内存中存储的方式,从而加快访问速度。
这种将低速设备中的数据保存到高速设备中的缓存方式,其它情况也会用到。Web浏览器通过远程Web服务器获取数据,在显示较大的图片或视频时,其实先将文件缓存在硬盘里,等到需要时从硬盘读取。(应该就是视频已经缓存到硬盘里,等你点开播放键,再从硬盘读取,这样读取速度会快)
4.虚拟内存(假想的内存)
将磁盘的一部分作为内存使用,在内存不足时也能运行程序,其实是将实际内存与磁盘虚拟内存中的内容置换得以运行程序。
虚拟内存有分段式和分页式。分页式是指不考虑程序构造,将程序按照页(page)的大小进行分割,然后按照页大小在磁盘的虚拟内存和内存之间进行置换。
page file 1920MB
5.节约内存的编程方法
(1) DLL(Dynamic Link Library) 多个应用可以共用同一个DLL文件,从而节约了内存
(2) C语言编程可以通过调用_stdcall
C语言在调用函数后需要进行栈清理处理
- 在调用方处理:多次进行相同的栈清理处理
- 在被调用方处理:只进行一次栈清理
6. 磁盘划分
磁盘的划分有扇区和可变长
- 扇区是硬盘上最小的读写单位
- 簇是文件系统的最小读写单位,是扇区的倍数,簇可以保证里面的扇区是连续的
文件系统:是操作系统在存储设备上组织文件的方法。Windows 98 以前所使用的是文件系统是 FAT,Windows 2000 以后的版本有所谓的 NTFS 。
7.驱动
驱动程序就是运行在操作系统和硬件之间,用来协助操作系统控制硬件的程序
操作系统只与输入输出设备的驱动打交道,比如显卡、声卡,与硬件直接打交道的是驱动程序
五、程序的运行环境
1. 操作系统和硬件共同决定了程序的运行环境
2.机器语言
机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集合。这种指令集称为机器码或原生码。不同种类的计算机其机器语言是不相通的,按某种计算机的机器指令编制的程序不能在另一种计算机上执行。
对于源代码进行编译后得到本地代码,即机器语言的程序。
3. 不同操作系统API不同
应用软件需要根据不同的操作系统来开发,应用程序向操作系统传递指令的途径叫API,像鼠标输入、显示器输出等
4. 利用虚拟机软件运行其它操作系统下才能运行的应用
5. Java虚拟机
Java编译后生成的不是特定CPU使用的本地代码,而是字节代码,Java虚拟机为字节代码的运行提供了运行环境,即一边编译为本地代码一边运行。
Java虚拟机看作是不依赖于特定硬件及操作系统的运行环境
6. BIOS
BIOS放在内存中的ROM里 ,掉电不丢失
BIOS (Basic Input Output System ) 记录了控制外围设备的程序和数据。开机后,BIOS首先确认硬件是否正常运行,没有问题后,会启动硬盘里的引导程序。
六、源文件到可执行文件
1.计算机只能运行本地代码
2.编译器
由于硬件的不同,不同平台的编译器不同,编译结果不同,所以编译型语言的可移植性差
编译器将源文件编译生成的目标文件 .obj ,转换为本地代码
交叉编译器:在一种计算机环境中运行的编译程序,能编译出另外一种环境下运行的代码
3.链接器
编译后生成的目标文件无法直接运行,需要用链接器将多个目标文件结合,才能生成课执行文件.exe
4.库文件
库文件:将多个目标文件集中保存到一个文件中的形式,链接时将指定的目标文件抽取出。静态数据库(.lib文件)和动态数据库(.dll文件)。
静态链接:lib 即包括函数位置信息的索引,也包括实现,在编译时直接将代码加入程序当中
动态链接:需要用到两个文件,一个是 lib文件,包含 dll 中的函数名称和位置。另一个是dll文件,包含实际的函数和数据,应用程序通过 lib 文件链接到 dll 文件
5.可执行文件的运行
1)可执行文件是放在硬盘中的,需要将程序加载进内存后运行
2)本地代码处理变量或函数时,跳转到的是变量或函数在内存中的地址,但是可执行文件中并没有指定变量或函数的实际内存地址。可执行文件中变量或函数的实际地址如何表示?
可执行文件中给变量或函数分配的是虚拟内存的地址,程序运行时,会将虚拟内存的地址转为实际内存的地址,这需要再配置信息(为这种地址转换提供的信息)
6.程序加载生成堆和栈
可执行文件中包括再配置信息、函数、数据,不存在堆和栈
堆和栈需要的内存空间是在可执行文件运行时分配的
7.栈
存储函数内部的局部变量和方法调用所用参数的内存区域
自动申请和分配
8.堆
通过malloc和new等动态申请内存的语句使用,也需要用户手动释放
七、操作系统和应用
1.监控程序
监控程序:操作系统的原型,具有加载和运行的功能,即将各种应用程序加载到内存中运行
初期的操作系统:任何程序的输入输出部分都是一样的,所以将这一部分加入到监控程序中形成初期操作系统
2.系统调用
系统调用:操作系统的硬件控制功能
高级语言的可移植性:高级语言程序编译后生成相应操作系统的系统调用,即生成利用系统调用的本地代码
3.Windows操作系统的特征
(1)API
API:应用程序接口,将应用程序和操作系统相连接,由多个DLL文件提供
(2)GUI 图形用户界面
(3) WYSIWYG
what you see is what you get 所见即所得 :显示器和打印机作为同等的输出设备处理
(4)多任务
通过时钟切割,使得多个程序同时运行,即在短时间内让多个程序切换运行,看起来就像多个程序同时运行
(5)网络功能和数据库功能
叫作中间件,操作系统和中间件合起来叫系统软件,应用可以利用操作系统,也可以利用中间件的功能
(6)即插即用 PNP(plug and play)
新的设备连接到计算机,系统会自动安装和设定设备的驱动程序
基本的驱动装系统的时候都是自动安装的,但是大部分的硬件驱动是要自己安装的,比如升级的显卡、声卡
八、汇编语言
汇编语言使用助记符
汇编语言编译为本地代码的过程叫汇编,反之,叫反汇编
汇编语言与本地代码一一对应,高级语言反编译是无法做到完全还原
九、硬件
1.系统调用
系统调用实现对硬件的控制,而API则是调用的函数,函数实体存储在DLL文件中
2.IN、OUT
向外围设备进行输入输出操作的指令
IN:将指定端口号的端口数据输入到CPU寄存器
OUT:将CPU寄存器中的数据输出到指定端口号的端口
3.I/O 控制器
主机附带了连接外围设备的连接器,连接器内部有I/O控制器,I/O控制器是用来交换主机与外围设备电流特性的IC,因为电压不同、数字信号与模拟信号的电流特性不同,主机与外围设备无法直接连接
I/O控制器可以控制多个外围设备
4.端口 port
端口是I/O控制器中用于临时保存数据的内存,也叫寄存器(CPU内部的寄存器主要用于数据运算,I/O寄存器主要用于临时存储数据)
端口号又叫I/O地址,用于区分端口
IN OUT指令在指定了端口号的端口和CPU之间进行数据的输入输出,和通过内存地址的内存与CPU进行数据交换其实是一样的
5.中断请求 IRQ(Interrupt Request)
外围设备向CPU请求中断,使用中断编号对不同设备区分
操作系统和BIOS提供响应中断编号的中断处理程序
中断控制器将多个设备发出的中断请求有序的发给CPU
利用中断可以实现对数据的实时处理
6.直接内存存取 DMA(Direct Memory Access)
外围设备直接与主内存进行数据传输,不需要通过CPU,节约了时间
PS:I/O端口号、中断号、DMA通道用于识别外围设备
7.显示机制
与主内存相独立的VRAM中存储显示器显示的信息,通过中断实现数据的显示
十、随机数
1.随机数:用程序来表示人类的直觉的一种方法
2.伪随机数:借助公式产生具有一定规律性的随机数
3.随机数的种子
通过一个例子理解:有一种获取伪随机数的方法叫线性同余 R`=(a*R+b) mod c
R是当前随机数 R`是下一个出现的随机数
R、a、b、c的数值与当前系统时间有关,并且都有默认值,但是不调用获取当前系统时间的函数,R、a、b、c的数值使用的就是默认值,这里R、a、b、c就是随机数的种子