第十一章 运行库
1. 环境变量和参数数组
---栈的增长方向--->
。。。0 env n 。。。 env 0 0 arg n 。。。 arg 0 argc
esp指向arg 0;old esp指向argc
2. 程序开始时分配内存用alloca,因为在程序的一开始堆还没有被初始化,而alloca是唯一可以不使用堆的动态分配机制。alloca可以再栈上分配任意大小的空间(只要栈的大小允许),并且在函数返回的时候会自动释放,就好像局部变量一样。函数退出时的退栈操作是直接将ESP的值赋为EBP的值。
3. mainCRTStartup总体流程
初始化和OS版本有关的全局变量
初始化堆
初始化I/O
获取命令行参数和环境变量
初始化C库的一些数据
调用main并记录返回值
检查错误并将main的返回值返回
main/wmain/WinMain/wWinMain等都不是程序的实际入口
4. FILE在Linux下叫文件描述符,windows下叫句柄,总是和内核的文件对象相关联
0,1,2代表标准输入stdin、标准输出stdout、标准错误输出stderr
MSVC的I/O初始化工作:
建立打开文件表
如果能够继承自父进程,那么从父进程获取继承的句柄
初始化标准输入输出
5. CRT的大致功能:
启动和退出:包括入口函数及入口函数所依赖的其他函数等
标准函数:有C语言标准规定的C语言标准库所拥有的函数实现
I/O:I/O功能的封装和实现
堆:堆的封装和实现
语言实现:语言中一些特殊功能实现
调试:实现调试功能的代码
6. C语言标准库
stdio.h :标准的输入输出,文件操作
ctype.h :字符操作
string.h :字符串操作
math.h :数学函数
stdlib.h :资源管理、格式转换
time.h :时间/日期
assert.h :断言
limits.h & float.h :各种类型上常数
stdarg.h :变长参数
setjmp : 非局部跳转
变长参数宏:
linux: #define printf(args...) fprintf(stdout, ##args)
windows: #define printf(...) fprintf(stdout, __VA_ARGS__)
例如:printf("%d%s",123, "hello") 被扩展成fprintf(stdout, "%d%s", 123, "hello")
非局部跳转:
#include <setjmp.h>
#include <stdio.h>
jmp_buf b;
void f()
{
longjmp(b, 1);
}
int main()
{
if (setjmp(b))
{
printf("World!");
}else
{
printf("Hello ");
f();
}
return 0;
}
打印:Hello World!
7. 运行库与多线程
线程私有:局部变量,函数的参数,TLS(线程局部存储)数据
线程之间共享(进程所有):全局变量,堆上数据,函数的静态变量,程序代码,打开文件
8.fread实现
size_t fread(void *buffer, size_t elementSize, size_t count, FILE *stream);
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
size_t fread(void *buffer, size_t elementSize, size_t count, FILE *stream)
{
DWORD bytesRead=0;
BOOL ret=ReadFile(stream->_file, buffer, elementSize*count, &bytesRead, NULL);
if (ret)
return bytesRead;
else
return -1;
}
int fflush(FILE *stream) flush指定文件的缓冲,若参数为NULL,则flush所有文件的缓冲
int setvbuf(FILE *stream, char *buf, int mode, size_t size)
无缓冲模式:_IONBF 该文件不使用任何缓冲
行缓冲模式:_IOLBF 仅对文本模式打开的文件有效,所谓行,即是指每收到一个换行符(\n或\r\n),就将缓冲flush掉
全缓冲模式:_IOFBF 仅当缓冲满时才进行flush
void setbuf(FILE *stream, char *buf) 等价于 (void)setvbuf(stream, buf, _IOFBF, BUFSIZE)