ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

202行代码写出一个C运行时?极简C运行时rt0完全入门指南

202行代码写出一个C运行时?极简C运行时rt0完全入门指南 202行代码写出一个C运行时极简C运行时rt0完全入门指南【免费下载链接】rt0A minimal C runtime for Linux i386 x86_64项目地址: https://gitcode.com/gh_mirrors/rt/rt0rt0 是一个面向 Linux i386 / x86_64 平台的极简 C 运行时C runtime库——它仅用202 行 C 代码外加 6~9 行 GCC 内联汇编就实现了程序启动、系统调用、堆内存管理等核心能力让你的 Hello World 程序小得惊人。本文是一份面向新手的 rt0 完全入门指南带你快速理解 C 运行时是什么、rt0 由哪些部分组成、以及如何从零构建并运行第一个 rt0 程序。什么是 C 运行时rt0 到底有多小每个 C 程序从main()执行之前都有一小段幕后英雄代码在工作解析命令行参数、对齐栈、处理退出、提供系统调用入口——这段代码加上基础库就是所谓的C 运行时。通常它由 glibc 等庞大的标准库承担体积动辄几 MB。rt0 的思路是只做最少的事✅ 整个库只有202 行 C 源码✅ i386 架构仅需9 行内联汇编x86_64 仅需6 行✅ Hello World 程序仅需608 字节i386/792 字节x86_64✅ 可与 Google 的 gold 链接器搭配使用进一步缩小体积与 glibc 对比数据来自 STATS.md程序架构rt0 版本glibc 版本缩小比例Hello Worldi386608 B2988 B约 5 倍Hello Worldx86_64792 B4200 B约 5 倍空 maini386552 B2888 B约 5 倍空 mainx86_64752 B2988 B约 4 倍rt0 提供哪些功能别小看 202 行代码它提供了编写无标准库程序所需的全部地基程序启动_start入口解析argc、argv、envp并对齐栈系统调用封装syscall0~syscall60~6 个参数的任意系统调用常用全局变量__environ环境变量、errno、_end、_edata、_etext、__executable_start程序退出_exit堆内存示例sys_brk、brk、sbrk的完整示例实现核心功能定义在头文件 rt0.h 与 syscall.h 中。项目结构快速导览整个项目非常轻量核心代码只有 3 个 C 文件 2 个头文件 include/rt0/ —— 对外头文件rt0.h全局变量与_exit、syscall.hSYS_*宏与syscall0~6 src/lib/ —— 运行时实现00_start.c —— 启动代码_start函数所在syscall.c —— 系统调用核心32 位用int $0x80、64 位用syscall指令_exit.c —— 退出处理 t/ —— 测试与示例程序如 hello.c、sbrk.c、threads.c、test.c Makefile —— 构建、测试、安装一体化脚本三步上手构建并运行 rt0第一步获取源码git clone https://gitcode.com/gh_mirrors/rt/rt0 cd rt0第二步编译测试make # 构建 librt0.a 静态库 make test # 编译全部测试程序 make runtest # 运行全部测试官方推荐加上WITH_FAST_SYSCALL1参数例如make WITH_FAST_SYSCALL1可启用针对每个参数数量的专用系统调用函数执行更快、体积更小。第三步编写第一个 rt0 程序rt0 的 Hello World参考 t/hello.c极其简洁#include rt0/syscall.h int main( int argc, char **argv, char **envp ) { syscall3( SYS_write, 1, ( long )( Hello World!\n ), 13 ); return( 0 ); }编译链接时加上-nostdlib不链接标准库和-lrt0cc -c hello.c -nostdlib -Iinclude -o hello.o cc hello.o -nostdlib -Iinclude -Llib -lrt0 -o hello ./hello # 输出 Hello World!需要全局安装时执行make DESTDIR/usr/local install之后即可在任意目录#include rt0/rt0.h使用。工作原理_start 如何接管程序入口理解 rt0 最有趣的地方在 00_start.c 中的_start函数。Linux 加载 ELF 程序后直接跳转到_start此时栈上整齐地摆放着argc—— 命令行参数个数argv—— 参数指针数组envp—— 环境变量指针数组启动汇编做的事只有三件从栈中取出argc/argv/envp64 位平台放入rdi/rsi/rdx寄存器符合 System V 调用约定、将栈对齐到 16 字节、然后call main。程序返回后由 _exit.c 中的_exit调用SYS_exit系统调用干净利落地结束进程。系统调用则封装在 syscall.c把系统调用号和参数放进约定寄存器执行syscallx86_64或int $0x80i386指令返回值若为负数会自动写入errno。这套机制让SYS_write、SYS_brk、SYS_mmap等所有 Linux 系统调用都能直接用。进阶玩法堆内存与纯系统调用线程t/ 目录下的示例程序是绝佳的学习材料堆内存分配sbrk.c 演示了如何通过brk/sbrk系统调用向内核申请堆空间是理解malloc底层的绝佳起点无 pthread 线程threads.c 仅靠mmapclone两个系统调用就实现了线程创建展示了 C 运行时与操作系统内核之间的直接对话系统调用参数测试sys0.c、sys1.c 等分别验证 0~3 个参数的系统调用这些示例配合 STATS.md 中的编译链接参数可以让你深入研究如何榨干每一个字节。常见问题 FAQQrt0 支持哪些系统ALinux 的 i386 与 x86_64 架构官方在 RHEL 7 与 Ubuntu 14.04 上验证过FreeBSD 下通过附加-Wl,-u_start链接参数也可使用。Q需要 root 权限吗A日常编译运行不需要只有执行make install安装到系统目录时才需要。Q没有 printf 和 malloc 怎么办A这正是 rt0 的设计哲学——它只提供最小内核接口write、strlen等函数由你自己几十行代码实现参考 test.c。想省事可以了解 Linux 内核自带的 nolibc 方案。Q后续计划有哪些A查看 TODO.md包括 JIT 编译器演示、64 位返回值/参数系统调用、rt0-cc 驱动脚本等。总结为什么值得学习 rt0代码量极小202 行 C 代码一小时就能通读全部实现理解本质看清 C 运行时、系统调用、程序加载的完整链路极致瘦身嵌入式、极简工具、性能敏感场景的直接生产力即插即用make install后就能作为-lrt0库嵌入自己的项目如果你想彻底搞懂一条 C 语句是如何变成可执行程序的rt0 就是最短的那条路径。【免费下载链接】rt0A minimal C runtime for Linux i386 x86_64项目地址: https://gitcode.com/gh_mirrors/rt/rt0创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表