内核在执行每个程序时都会为其提供4G的内存空间(32位系统下)。4G内存空间中0-3G属于用户内存空间,3G以上属于内核内存空间。如图一。内核内存空间保存着内核的代码与数据。其中包括了系统调用对应的内核函数。这些函数使用户可以执行各种系统调用——内核内存空间为用户提供了系统调用。那么用户内存空间又为用户提供了什么呢?
用户内存空间为用户提供了各种不同的库函数。
0-3G的用户内存空间犹如一张白纸。在上面编写程序犹如在纸上作画。你可以编写任意的代码,但所有代码都必须从0开始。这显然是一个费时又费力的过程。聪明的开发者想到了一个方法——库函数。开发者首先确定要完成的函数的功能,然后编码实现函数。将源码编译成.o文件,打包到.a文件中。将.a文件提供给用户。用户拥有了.a文件便拥有了.a文件中所有函数。用户可以直接调用.a文件中的库函数。只要连接程序时连接.a文件即可。用户内存空间不再是一张白纸,它上面包含了许许多多不同功能的函数。我们可以调用其中的函数,完成不同的功能。如图二。
我们可以观察基本静态库libc.a文件,了解相关的基本库函数。
ar -vt /usr/lib/libc.a
输出:
...
init-start.o
...
read.o
...
iofread,o
...
init-start.o文件包含了进程初始化代码。进程执行的第一条指令就是该代码的第一条指令。
read.o文件包含了read.o函数,它是read系统调用的封装函数。
iofread.o文件包含了fread.o函数。
库函数使用户不必从0开始编码。库函数就像一个小部件,使我们可以使用这些小部件去搭建更复杂的程序。