恭喜!我们已经坚定地将“你”置于CPU中。希望你玩得开心。

我将强调一遍,你刚刚获得的所有知识都是真实且活跃的。下次当你想到你的计算机如何运行多个应用程序时,希望你能想象到定时器芯片和硬件中断。当你用某种高级编程语言编写程序并遇到链接器错误时,希望你能思考一下那个链接器试图做什么。

如果你对本文中的任何内容有疑问(或者修正意见),请发送电子邮件至lexi@hackclub.com,或者在GitHub上提交问题或PR

奖励:翻译 C 语言概念

如果你自己进行过一些低级编程,你可能知道栈和堆是什么,并且可能使用过 malloc。也许你没有深入思考它们是如何实现的!

首先,线程的栈是一定量的内存,映射到虚拟内存的高地址处。在大多数体系结构上(虽然不是所有),栈指针从栈内存的顶部开始,并随着增加而向下移动。物理内存并不是一开始就为整个映射的栈空间分配的;而是使用需求分页来延迟分配内存,当达到栈的帧时才进行分配。

也许令人惊讶的是,像 malloc 这样的堆分配函数并不是系统调用。相反,堆内存管理由libc实现提供!mallocfree 等等是复杂的过程,libc自己管理内存映射的细节。在底层,用户空间的堆分配器使用包括 mmap(可以映射不仅仅是文件)和 sbrk 的系统调用。

奖励:小知识点

我找不到一个合适的地方放置这些内容,但我觉得它们很有趣,所以给你看看。

大多数Linux用户可能有足够有趣的生活,以至于他们很少花时间想象页表在内核中是如何表示的。

Jonathan Corbet, LWN

对硬件中断的另一种视觉化:

有些系统调用使用称为vDSO的技术,而不是跳转到内核空间。我没有时间详细讨论这个,但它非常有趣,我建议你阅读 相关资料 了解

最后,关于Unix的指责:我确实感到遗憾,很多与执行特定相关的内容非常依赖Unix。如果你是macOS或Linux用户,这没问题,但它不会让你更接近Windows如何执行程序或处理系统调用,尽管CPU架构都是相同的。将来我很愿意写一篇涵盖Windows世界的文章。

致谢

在撰写本文期间,我与GPT-3.5和GPT-4进行了大量交流。虽然它们经常对我说谎,大部分信息都是无用的,但在解决问题时有时候它们确实很有帮助。如果你意识到它们的局限性并对它们说的每一件事都持怀疑态度,语言模型的帮助可能是积极的。话虽如此,它们写作能力很差,不要让它们替你写作。

更重要的是,感谢所有校对过我的人,鼓励过我的人,以及帮助我进行头脑风暴的人 — 尤其是Ani、B、Ben、Caleb、Kara、polypixeldev、Pradyun、Spencer、Nicky(在第四章画了美妙的精灵)、以及我可爱的父母。

如果你是青少年,喜欢计算机,而且还没有加入Hack Club的Slack,你应该立刻加入。如果没有这群了不起的人分享我的想法和进展,我可能不会写这篇文章。如果你不是青少年,你应该给我们捐款,这样我们可以继续做一些酷炫的事情。

本文中所有平庸的艺术作品都是用Figma绘制的。我使用Obsidian进行编辑,有时候用Vale进行检查。本文的Markdown源代码可以在GitHub上获取,欢迎未来提出细微修正,所有艺术作品都发布在Figma社区页面上。