这节讲的主要是程序的入口函数及初始化
程序从main开始吗?
显然为NO. 例如函数atexit(&foo), 在程序结束的时候还可以让程序调用foo函数.
入口函数如何实现
1. glibc的入口函数
glibc大概是这样的:
2. MSVC CRT入口函数
3. I/O的初始化
在linux中, 值为0.1.2的fd分别代表标准输入(stdin),标准输出(stdout),标准错误输出(stderr), 以使进入main函数就可以使用printf等函数.有fd=0,fd=1,fd=2,对应于进程管理的打开文件表, 而打开文件表又对应于一个文件的内核对
这些fd对应于C语言的FILE.
如果有其他的文件(使用FILE的fopen函数)就会有一个fd=3, 对应于进程管理的打开文件表, 而打开文件表又对应于一个文件的内核对象.
4. MSVC CRT I/O的初始化
FILE对应的结构如下:
已打开的文件句柄的信息使用如下表示:
有一个数组:
_file是一个整数, 通过它可以访问到内部文件句柄表中的某一项.类似于fd,它是打开文件表的下标.
通过一个FILE*可以通过宏_oshnd,它获得__pinfo二维数组中的一项来获得一个文件信息,再通过ioinfo的osfhnd,从而得到内部句柄.
I/O初始化主要进行了如下工作:
1. 建立打开文件表
2. 如果能够继承自父进程, 那么从父进程获取继承的句柄
3. 初始化标准输入输出
这是所有的IO函数就可以自由使用了.