CRT 是什么?
🔍 什么是 CRT?—— C Runtime Library(C运行时库)
CRT 是 C Runtime Library 的缩写,中文叫“C 运行时库”,它是 C 程序在运行过程中所依赖的一组标准函数和初始化逻辑。
🎯 学习目标
- 理解 CRT 的定义与作用
- 明白为什么即使你只写了
main(),程序也能正常运行 - 掌握 CRT 如何初始化程序环境、调用
main()并退出 - 了解 CRT 在不同平台(Windows / Linux)下的差异
✅ 一、CRT 是什么?
定义:
CRT 是 C 程序运行前必须完成的准备工作 + 提供的标准函数集合。
它不是你写的代码的一部分,而是由编译器自动链接到你的程序中的一段支持代码。
✅ 二、CRT 的核心功能
1. 初始化程序环境
- 设置堆栈(Stack)
- 初始化堆(Heap)
- 解析命令行参数(
argc,argv) - 初始化标准输入输出(stdin/stdout/stderr)
- 调用全局构造函数(C++)
2. 调用你的 main() 函数
- 在准备好一切之后,CRT 才会跳转到你写的
main()函数。
3. 处理程序退出
- 捕获异常或错误
- 调用
exit()清理资源 - 返回操作系统
✅ 三、从 CRT 到 main():一个完整的流程图
操作系统加载 exe → 入口点 _start(CRT 启动代码)
↓
初始化堆栈、堆、IO等
↓
解析命令行参数 argc/argv
↓
调用 __tmainCRTStartup(CRT 主启动函数)
↓
调用 main()
↓
main() 返回,执行 exit()
↓
CRT 清理并返回操作系统
📌 你的 main() 只是这个流程中的一小部分。
✅ 四、CRT 在 Windows 下的典型实现(以 MinGW-w64 为例)
CRT 包括以下几个关键函数(都在 .text 段中):
| 函数名 | 功能 |
|---|---|
_start 或 mainCRTStartup |
程序入口点 |
__tmainCRTStartup |
CRT 主启动函数,调用 main |
pre_c_init / pre_cpp_init |
初始化 C/C++ 支持 |
exit() |
退出处理 |
malloc() / free() |
内存管理 |
printf() / scanf() |
标准 IO 函数 |
你可以通过反汇编看到这些函数的机器码。
✅ 五、CRT 在 Linux 下的典型实现(glibc)
Linux 上的 CRT 更加标准化:
- 启动函数为
_start - 位于
/usr/lib/x86_64-linux-gnu/crt1.o - 最终调用
__libc_start_main(),再调用main()
gcc -v hello.c
你会看到类似这样的链接过程:
/usr/bin/ld ... crt1.o crti.o crtbegin.o ... your_code.o ... crtend.o crtn.o
📌 这些 .o 文件就是 CRT 的组成部分。
✅ 六、动手实验:禁用 CRT,看看会发生什么
你可以尝试不使用 CRT 来编译程序,观察程序行为:
示例代码:hello.S
.global _start
_start:
mov $1, %rax # sys_write
mov $1, %rdi # fd=stdout
lea msg(%rip), %rsi # buffer address
mov $13, %rdx # length
syscall
xor %rdi, %rdi # exit code 0
mov $60, %rax # sys_exit
syscall
msg:
.asciz "Hello World\n"
编译命令:
as hello.S -o hello.o
ld hello.o -o hello
./hello
📌 这个程序没有 main(),也没有任何 CRT 初始化逻辑,但它依然可以运行!
✅ 七、CRT 和标准库的区别
| 名称 | 全称 | 内容 | 特点 |
|---|---|---|---|
| CRT | C Runtime | 初始化逻辑 + 标准库一部分 | 编译器自动链接 |
| C Standard Library | C 标准库 | <stdio.h>, <stdlib.h> 等函数 |
需要手动包含头文件 |
| STL(C++) | Standard Template Library | vector、map、algorithm 等 | C++ 特有 |
📌 CRT 是标准库的一部分,但更底层。
✅ 八、CRT 的静态链接 vs 动态链接
| 类型 | 描述 | 使用方式 |
|---|---|---|
| 静态链接 CRT | CRT 代码直接打包进可执行文件 | -static 编译选项 |
| 动态链接 CRT | CRT 作为 DLL 加载(如 msvcrt.dll) | 默认方式 |
📌 静态链接体积大,但独立性强;动态链接体积小,但依赖系统 DLL。
✅ 九、总结:CRT 的本质是什么?
CRT = 程序运行前的准备 + main() 的调用者 + 程序结束的清理者
你可以把它想象成:
“一个看不见的助手,在你写 main() 之前就已经开始工作了。”
✅ 十、延伸思考:如果你不用 CRT,你能做什么?
- 写最小可执行文件(如上例)
- 实现自己的运行时逻辑
- 开发操作系统内核
- 研究逆向工程、病毒分析、安全加固等领域
📌 下一步建议:
如果你想继续深入:
- 👉《如何从零构建一个 CRT》
- 👉《ELF/PE 文件格式详解》
- 👉《函数调用栈与堆栈平衡》
- 👉《JVM / Python 虚拟机的 CRT 对应机制》
或者我也可以为你生成一份《CRT 源码解析指南》,帮助你阅读 GCC 或 MSVC 的 CRT 实现源码。
是否需要?欢迎告诉我你的兴趣方向!🚀

浙公网安备 33010602011771号