程序是怎样跑起来的(2)

《程序是怎样跑起来的》读书笔记

主要参考文章:https://blog.csdn.net/u014222687/article/category/6295175

第6章:亲自尝试压缩数据

1:文件存储的基本单位是什么?

1字节(=8位),文件是字节数据的集合体。

2:文件内容用“数据的值*循环次数”来表示的压缩方法是RLE算法还是哈夫曼算法?

RLE算法,例如:AAABB这个数据压缩后是A3B2。像这样,把文件内容用“数据*重复次数”的形式来表示的压缩方法称为RLE(Run Length Encoding,行程长度编码)算法,如发送传真图像时多使用此算法。

3:BMP(BITMAP)格式的图像文件,是压缩过的吗?

没有压缩过,因为BMP格式的图像文件是没有压缩的,因此要比JPEG格式等压缩过的图像文件大不少。

4:可逆压缩和非可逆压缩]的不同点是什么?

压缩后的数据能复原的是可逆压缩,无法复原的是非可逆压缩。像JPEG格式这样的图片,之所以压缩后会让人感到不自然,就是因为使用了非可逆压缩。

文件是将数据存储在磁盘等存储媒介中的一种形式。程序文件中存储数据的单位是字节。文件的大小之所以用XXKB,XXMB等来表示,就是因为文件是以字节(B=Byte)为单位来存储的。

文件就是字节数据的集合。用1字节(=8位)表示的字节数据有256种,用二进制数来表示的话,其范围就是00000000-11111111。

从物理上对磁盘进行读写时是以¥[扇区的整数倍(簇)(如512字节)为单位的,但另一方面,程序则可以在逻辑上以字节为单位对文件的内容进行读写。

在任何情况下,文件中的字节数据都是连续存储的。

RLE算法:通过数据的重复次数来实现压缩

可逆压缩和非可逆压缩:Windows的标准图像数据形式为BMP,是完全未压缩的。由于与显示器以及打印机输出的bit(点)是可以直接¥[映射](mapping)的,因此便有了BMP(bitmap)这一名称。

常用的图片格式还有:BMP、JPEG、TIFF、GIF格式等。

对于图像来说通常使用非可逆压缩。因为对于图像来说,即使有时无法还原到压缩前那样鲜明的图像状态,只要肉眼看不出也没关系。例如JPEG格式使用的就是非可逆压缩。

第7章:程序是在何种环境中运行的

1:应用的运行环境,指的是什么?

指操作系统和计算机本身(硬件)的种类。应用的运行环境通常使用类似于Windows(OS)和AT兼容机(硬件)这样的OS和硬件的种类来表示的。AT兼容机是指,可以和IBM开发的PC/AT在硬件上相互兼容的计算机的总称。称为“PC/AT兼容机”。

2:Macintosh用的操作系统(MacOS),在AT兼容机上能运行呢?

无法运行,不同的硬件种类需要不同的操作系统。

3:Windows上的应用,在MacOS上能运行么?

无法运行,应用是为了在特定操作系统上运行而做成的。

4:Java虚拟机的功能是什么?

运行Java应用的字节代码。只要分别为各个环境安装专用的Java虚拟机,同样的字节代码就能在各种环境下运行了。

运行环境 = 操作系统+硬件,程序中包含着运行环境这一内容。操作系统和硬件决定了程序的运行环境。同一类型的硬件可以选择安装多种操作系统。CPU只能解释器本身固有的机器语言。不同的CPU能解释的机器语言的种类也是不同的。

程序员用C语言等编写的程序,在编写阶段仅仅是文本文件。文本文件在任何环境下都能显示和编辑。我们称之为源代码。通过对源代码进行编译,就可以得到本地代码。

CPU负责解析并运行从源代码编译而来的本地代码。CPU只能解释其自身固有的机器语言。

Windows之前,MS-DOS时代,不同机型的内存和I/O地址的构成等都是不同的,因此每个机型都需要专门的应用。因为这些应用软件中存在着直接操作计算机硬件的部分。这是因为一是当时MS-DOS的功能尚不完善,二是为了提高程序的运行速度。

在Windows的应用软件中,键盘输入,显示器输出等并不是直接向硬件发送指令,而是通过向Windows发送指令来间接实现。因此,程序员就不用注意内存和I/O地址的不同构成了。

程序是怎样跑起来的(2)_第1张图片

MS-DOS应用大多数都是不经过操作系统而直接控制硬件的,而Windows应用则基本上都由Windows来完成对硬件的控制。(也就是之前是应用直接控制硬件,Windows通过应用控制Windows操作系统,然后操作系统控制硬件)。

Windows中存在着著名的BIOS(Basic Input/Output System)的系统,BIOS存储在ROM中,是预先内置在计算机主机内部的程序。BIOS有“引导程序”的功能,引导程序是存储在启动驱动器起始区域的小程序。引导程序能够把OS加载到内存中运行。虽然启动应用是OS的功能,但是OS并不能启动自己,而是通过引导程序来启动。

第8章:从源文件到可执行文件

1:CPU可以解析和运行的程序形式称为什么代码?

本地代码(机器语言代码),通过编译源代码得到本地代码。

2:将多个目标文件结合生成EXE文件的工具称为什么?

连接器,通过编译和连接,得到EXE文件。

3:扩展名为.obj的目标文件的内容,是源代码还是本地代码?

本地代码,通过对源文件进行编译,得到目标文件。例如,C语言中,将Samplel.c这个源文件编译后,就会得到Samplel.obj这个目标文件。目标文件的内容就是本地代码。

4:把多个目标文件收录在一起的文件称为什么?

库文件,连接器会从库文件中抽取出必要的目标文件并将其结合到EXE文件中。此外,还存在一种程序运行时结合的DLL形式的库文件。

5:仅包含Windows的DLL文件中存储的函数信息的文件称为什么?

导入库,把导入库信息结合到EXE文件中,这样程序在运行时就可以利用DLL内的函数了。

6:在程序运行时,用来动态申请分配(数据和对象)的内存区域形式称为什么?

堆,堆的内存空间会根据程序的命令进行申请及释放。

即使是使用不同编程语言编写的代码,转换成本地代码后,也就变成同一种语言(机器语言)来表示了。

计算机把所有的信息作为字节的集合来处理的,计算机指令也是字节的结合。

仅靠编译是无法得到可执行文件的。

编译器把源代码转换成本地文件后,此本地文件也是无法直接运行的,因为它还处于未完成状态。为了得到可执行文件,编译之后还需要进行“链接”处理。

通过C编译器对C源文件进行编译后生成扩展名为”.obj”的目标文件。

#include
#include

char *title = “示例程序”;

double Average(double a,double b) {
    return (a+b)/2;
 }

int WINAPI WinMain(….){

    double ave;
    char buff[80];
    ave = Average(123,456);
    sprintf(buff,”平均值=%f”,ave);
    MessageBox(NULL,buff,titlemMB_OK);

    return 0;
}

仅仅通过编译是无法生成可执行文件的,如上代码,MessageBox、sprintf等方法都不是我们实现的,我们的源代码中并没有记录这些函数的处理内容。我们必须将存储着MessageBox、sprintf等方法的目标文件同上面的代码生成的目标文件结合起来,否则处理就不完整。

把多个目标文件结合起来,生成一个可执行文件的处理就是链接,运行链接的程序就称为链接器(linkage editor或连接器)。

程序是怎样跑起来的(2)_第2张图片

但是针对目标文件比较多的情况下,就出现了库文件,库文件就是把多个目标文件集成保存到一个文件中的形式。链接器指定库文件后,就会从中把需要的目标文件抽取出来,并同其他目标文件结合生成EXE文件。

例如sprintf()等函数,不是通过源代码形式而是通过库文件形式和编译器一起提供的。这样的函数称为标准函数。之所以使用库文件,是为了简化链接器的参数指定多个目标文件这一过程。

同时通过目标文件的形式或集合多个目标文件的库文件形式来提供函数,就可以不用公开标准函数的源代码内容。

Windows以函数的形式为应用提供了各种功能。这种形式的函数称为API(Application Programming Interface,应用程序接口)。

Windows中,API的目标文件,并不是存储在通常的库文件中,而是存储在名为DLL(Dynamic Link Library)文件的特殊库文件中。DLL文件是程序运行时动态结合的文件。

以MessageBox()为例,MessageBox的信息存储在import.lib(假设)库文件中,实际上import.lib仅存储两个信息,一是MessageBox在user.dll(假设)这个DLL文件中。另一个是存储着DLL文件的文件夹信息,import.lib中MessageBox的目标文件的实体实际上并不存在。我们把import.lib这样的库文件称为导入库。

与此相反,存储着目标文件的实体,并直接和可执行文件结合的库文件形式称为静态链接库。

Windows中的编译和链接机制:
程序是怎样跑起来的(2)_第3张图片

再配置信息:
本地代码在对程序中记述的变量进行读写时,是参照数据存储的内存地址来进行命令的。在调用函数是,程序的处理流程就会跳转到存储着程序处理内容的内存地址上。可执行文件作为本地代码的程序,并没有指定变量以及函数的实际内存地址。

类似于Windows操作系统这样的可以加在多个可执行程序的运行环境中,每次运行时,程序内的变量以及函数被分配的地址都是不同的,那么,在可制行文件中,变量和函数的内存地址的值,是如何来表示的呢?

可执行未见中给变量以及函数分配了虚拟的内存地址。在程序运行时,虚拟的内存地址会转换成实际的内存地址。连接器会在可执行文件的开头,追加转换内存地址所需要的必要信息,这些信息称为再配置信息。

可执行文件的再配置信息,就成为了变量和函数的相对地址。相对地址表示的是相对于基点地址的偏移量,也就是相对距离。

在源代码中,虽然变量以及函数是在不同位置分散记述的,但是在链接后的可执行文件中,变量及函数就会变成一个连续排列的组。这样,各变量的内存地址就可以用相对于变量组起始位置这一基点的偏移量来表示,各函数的内存地址也可以用相对于函数组起始位置这一基点的偏移量来表示。而各组基点的内存地址则是在程序运行时被分配的。

链接后的EXE文件的构造:
程序是怎样跑起来的(2)_第4张图片

可执行文件的内容分为再配置信息,变量组和函数组,当程序加载到内存后,除此之外还会额外生成两个组,那就是栈和堆。栈是用来存储函数内部临时使用的变量(局部变量),以及函数调用时所用的参数的内存区域。堆是用来存储程序运行时的任意数据及对象的内存领域。

加载到内存的程序由4部分构成:
程序是怎样跑起来的(2)_第5张图片

栈中对数据进行存储和舍弃的代码,是由编译器自动生成的。堆中的内存空间,则要根据程序猿编写的程序,来明确进行申请分配或释放。

编译器和解释器有什么不同?
编译器是在运行前对所有源代码进行解释处理的。而解释器则是在运行时对源代码的内容一行一行地进行解释处理的。

使用DLL文件的好处是什么?
DLL文件中的函数可以被多个程序公用。因此,借助该功能可以节约内存和磁盘。此外,在对函数的内容进行修正是,还不需要重新链接使用这个函数的程序。

第9章:操作系统和应用的关系

1:监控程序的主要功能是什么?

程序的加载和运行。监控程序也可以说是操作系统的原型。

2:在操作系统上运行的程序称为什么?

应用或应用程序。

3:调用操作系统功能称为什么?

系统调用(system call)。应用通过系统调用(system call)间接控制硬件。

4:GUI是什么的缩写?

Graphical User Interface(图形用户界面)。显示器中显示的窗口及图标等通过鼠标点击可以直接操作的用户界面。

5:WYSIWYG是什么的缩写?

What You See Is What Your Get(所见即所得),WYSIWYG是指可以直接将显示器中显示的内容在打印机上打印出来。这是Windows的特征之一。

监控程序:主要是程序的加载和运行,可以说是操作系统的原型。

通过事先启动监控程序,程序猿可以根据需要将各种程序加载到内存中运行。

随着时代的发展,人们发现很多程序有很多共同的部分,人们把这些程序追加到监控程序中。初期的操作系统就这样诞生了。操作系统本身不是单独的程序,而是多个程序的集合体。

初级的操作系统 = 监控程序 + 基本的输入输出程序

程序是怎样跑起来的(2)_第6张图片

操作系统是多个程序的集合体:

程序是怎样跑起来的(2)_第7张图片

在操作系统这个运行环境下,应用并不是直接控制硬件,而是通过操作系统来间接控制硬件。操作系统收到应用发出的指令后,首先会对该指令进行解释,然后会对时钟IC(实时时钟)和显示器用的I/O进行控制。

操作系统的硬件控制功能,通常是通过一些小的函数集合体的形式来提供的。这些函数以及调用函数的行为称为系统调用(system call),也就是应用对操作系统(system)的功能进行调用(call)的意思。

操作系统和高级编程语言能够使硬件抽象化。例如:文件是操作系统对磁盘媒介空间的抽象化。

Windows操作系统的特征:
(1)32/64位操作系统。
对于16位操作系统,操作一个32位的数据,需要处理两次16位的数据。而32位操作系统的话,只需要1次就可以完成32位的数据处理。

(2)通过API(Application Programming Interface)函数集来提供系统调用。

(3)提供采用了GUI的用户界面。
需要注意的是GUI中用户按照怎样的顺序操作是无法确定的。程序员必须制作出在任何操作顺序下都能正常运行的应用。

(4)通过WYSIWYG实现打印输出
WYSIWYG是What You See Is What You Get的略写。意思是,显示器上显示的文本及图形等(What You See),是(Is)可以原样输出到打印机上打印(What You Get)的。

(5)提供多任务功能。
多任务指的是同时运行多个程序的功能。WIndows是通过时钟分割技术来实现多任务功能的。
时钟分割指的是在短时间间隔内,多个程序切换运行的方式。在用户看来,就是多个程序在同时运行。
也就是说,WIndows会自动切换多个程序的运行。
此外,Windows中还具有一程序中的函数为单位来进行时钟分割的多线程功能。

(6)提供网络功能及数据库功能
网络功能和数据库功能虽然不是操作系统本身不可缺少的功能, 但是他们和操作系统很接近,所以被通称为中间件而不是应用。操作系统和中间件合在一起,也称为系统软件。应用不仅仅可以利用操作系统,也可以利用中间件的功能。

(7)通过即插即用实现设备驱动的自动设定。
即插即用(Plug-and-Play)指的是新的设备连接(Plug)后立即就可以使用(Play)的机制。新的设备连接到计算机后,系统会自动安装和设定用来控制该设备的设备驱动程序。

第10章:通过汇编语言理解程序的实际构成

大部分C语言编译器,都可以把利用C语言编写的源代码转换成汇编语言的源代码,而不是本地代码。利用该功能就可以得到汇编语言的源代码。

main函数是程序运行的起始位置,程序运行的起始位置也称为“入口点”。

汇编语言的源代码,是由转换操作码的指令和针对汇编器的伪指令构成的。
伪指令负责把程序的构造以及汇编的方法指示给汇编器。不过伪指令本身是无法汇编转换成本地代码的。

由伪指令segment和ends围起来的部分,是给构成程序的命令和数据的集合加上一个名字而得到的,称为段定义。段定义的英文表达segment具有“区域”的意思。在程序中,段定义指的是命令和数据等程序的集合体的意思。一个程序有多个段定义构成。

汇编语言指令的语法结构是操作码+操作数(也存在着只有操作码没有操作数的指令),操作码(opcode)表示指令动作,操作数表示指令对象。

第11章:硬件控制方法

1.在汇编语言中,是用什么指令来同外围设备进行输出操作的?

IN指令和OUT指令。在x86系列CPU用的汇编语言中,通过IN指令来实现I/O输入,OUT指令来实现I/O输出。

2.I/O是什么的缩写?

Input/Output。用来实现计算机主机和外围设备输入输出交互的IC称为I/O控制器或简称I/O。

3.用来识别外围设备的编号称为什么?

I/O地址或I/O端口号。所有链接到计算机的外围设备都会分配一个I/O地址编号。

4.IRQ是什么的缩写?

Interrupt Request。IRQ指的是用来执行硬件中断请求的编号。

5.DMA是什么的缩写?

Direct Memory Access。DMA指的是,不经过CPU中介处理,外围设备直接同计算机的主内存进行数据传输。

6.用来识别具有DMA功能的外围设备的编号称为什么?

DMA通道。像磁盘这样用来处理大量数据的外围设备都具有DMA功能。

如何用程序来控制CPU和内存以外的硬件呢?(通过OUT指令和IN指令)

程序是怎样跑起来的(2)_第8张图片

在用C语言等高级编程语言开发的Windows应用中,大家很少能接触到直接控制硬件的指令。这是因为硬件的控制是由Windows全权负责的。

Windows提供了间接控制硬件的方法。利用操作系统提供的系统调用功能就可以实现对硬件的控制。

在Windows中,系统调用称为API。各API就是应用调用的函数。这些函数实体被存储在DLL文件中。

Window控制硬件时借助的是输入输出指令。其中具有代表性的两个输入输出指令是IN和OUT。这些指令也是汇编语言的助记符。

IN指令通过指定端口号的端口输入数据,并将其存储在CPU内部的寄存器中。

OUT指令则是把CPU寄存器中存储的数据,输出到指定端口号的端口。

什么是端口号和端口呢?

计算机主机中,附带了用来连接显示器及键盘等外围设备的连接器。而连接器的内部,都有用来交换计算机主机同外围设备之间电流特性的IC。这些IC,统称为I/O控制器。由于电压不同,数字信号以及模拟信号的电流特性不同,计算机主机和外围设备之间无法直接连接。I/O控制器就可以解决这个问题。

I/O是Input/Output的缩写。显示器、键盘等外围设备都有各自专用的I/O控制器。I/O控制器中有用于临时保存输入输出数据的内存。这个内存就是端口。端口(port)的字面意思是“港口”。I/O控制器内部的内存,也称为寄存器。虽然都是寄存器,主要用来临时存储数据的。

在实现I/O控制器功能的I/C中,会有多个端口。由于计算机中连接着很多外围设备,所以就会有多个I/O控制器,当然会有多个端口。

一个I/O控制器及可以控制一个外围设备,也可以控制多个外围设备。端口之间通过端口号进行区分。端口号也称为I/O地址。

IRQ(Interrupt Request)是中断请求的意思。IRQ是用来暂停当前正在运行的程序,并跳转到其他程序运行的必要机制。该机制称为中断处理。中断处理在硬件控制中担当着重要角色。因为如果没有中断处理,就有可能出现处理无法顺畅进行的情况。

从中断处理开始到请求中断的程序运行结束之前,被中断的程序(主程序)的处理是停止的。中断处理程序运行结束后,处理也会返回到主程序中继续。

实施中断请求的是连接外围设备的I/O控制器,负责实施中断处理程序的是CPU。为了进行区分,外围设备中断请求会使用不同于I/O端口的其他编号,该编号称为中断编号。

假如同时有多个外围设备进行中断请求的话,CPU也会为难。为此,我们可以在I/O控制器和CPU中间加入名为中断控制器的IC来进行缓冲。中断控制器会把从多个外围设备发出的中断请求有序地传递给CPU。

CPU接收到来自中断控制器的请求后,会把当前中在运行的主程序中断,并切换到中断处理程序。中断处理程序的第一步处理,就是把CPU所有寄存器的值保存到内存的栈中。在中断处理程序中完成外围设备的输入输出后,把栈中保存的数据还原到CPU寄存器中,然后再继续进行对主程序的处理。加入CPU寄存器的数值没有还原的话,就会影响主程序运行,甚至崩溃。

DMA(Direct Memory Access)是指不通过CPU的情况下,外围设备直接和主内存进行数据传送。磁盘等都用到了这个DMA机制。通过利用DMA,大量数据就可以在短时间内转送到主内存。因为CPU作为中介的时间被节省了。

每个使用DMA的外围设备都有一个编号,称为DMA通道,CPU借助DMA通道,来识别是哪一个外围设备使用了DMA。

I/O端口号、IRQ、DMA通道可以说是识别外围设备的3点组合。不过,IRQ和DMA通道并不是所有的外围设备都是必须具备的。计算机主机通过软件控制硬件时所需要的信息的最低限,是外围设备的I/O端口号。IRQ只对需要中断处理的外围设备是必须的,DMA通道则只对需要DMA机制的外围设备来说是必须的。

第12章:让计算机“思考”

1:用计算机进行的模拟试验称为什么?

计算机模拟。计算机模拟指的是用软件来进行实验。

2.伪随机数指的是什么?

指的是通过公式产生的¥[伪随机数]。伪随机数同真正的随机数不同,具有¥[周期性]。

3:随机数的种子指的是什么?

生成伪随机数的公式中使用的参数。随机数的¥[种子]不同,产生的随机数也是不同。

5:计算机有记忆功能吗?

可以说有,内存及磁盘等有记忆功能。

6:AI是什么的缩写?

Artificial(人造的)Intelligence(智力)是“人工智能”的意思。

你可能感兴趣的:(程序是怎样跑起来的(2))