{"id":19602317,"url":"https://github.com/acodercat/function-call-principle","last_synced_at":"2025-02-26T15:41:34.283Z","repository":{"id":143870984,"uuid":"324281300","full_name":"acodercat/function-call-principle","owner":"acodercat","description":"一篇关于函数调用原理的文章，通过大量的示意图由浅入深分析了函数完整的生命周期。","archived":false,"fork":false,"pushed_at":"2024-07-17T02:25:48.000Z","size":1068,"stargazers_count":194,"open_issues_count":1,"forks_count":14,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-01-09T08:23:46.354Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/acodercat.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-25T03:37:55.000Z","updated_at":"2024-08-29T13:12:26.000Z","dependencies_parsed_at":null,"dependency_job_id":"4f1c1d1b-06c7-40ea-92d8-976d7cac4c71","html_url":"https://github.com/acodercat/function-call-principle","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acodercat%2Ffunction-call-principle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acodercat%2Ffunction-call-principle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acodercat%2Ffunction-call-principle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acodercat%2Ffunction-call-principle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/acodercat","download_url":"https://codeload.github.com/acodercat/function-call-principle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240885119,"owners_count":19873470,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T09:23:32.339Z","updated_at":"2025-02-26T15:41:34.262Z","avatar_url":"https://github.com/acodercat.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# 函数调用原理\n\n\n\n这是一篇讲述函数调用原理的文章，通过大量的示意图从比较基础的概念开始阐述函数调用时堆栈的完整变化过程，同时还会通过具体例子来分析在X-64平台上函数调用在汇编级的表示，从而深刻理解函数调用原理。最后会提供几个例子来发现C语言函数栈帧的一些有意思的行为。\n\n全文将带领你领略函数与栈的魅力，文章提供了[gitbook](https://acodercat.github.io/function-call-principle/)的阅读方式。\n\n\n\n## 目录\n\n* [前置知识](https://acodercat.github.io/function-call-principle/content/pre-knowledge.html)\n* [内存中的栈](https://acodercat.github.io/function-call-principle/content/stack-in-memory.html)\n* [控制转移](https://acodercat.github.io/function-call-principle/content/control-transfer.html)\n* [数据传递](https://acodercat.github.io/function-call-principle/content/data-transfer.html)\n* [寄存器的保存与恢复](https://acodercat.github.io/function-call-principle/content/save-and-restore-of-registers.html)\n* [局部变量的存储](https://acodercat.github.io/function-call-principle/content/storage-of-local-variables.html)\n* [函数栈帧](https://acodercat.github.io/function-call-principle/content/function-stack-frame.html)\n* [C语言函数栈帧实例](https://acodercat.github.io/function-call-principle/content/c-stack-frame-example.html)\n* [一个有趣的例子](https://acodercat.github.io/function-call-principle/content/interesting-example.html)\n* [手动修改栈帧数据](https://acodercat.github.io/function-call-principle/content/modify-stack-frame-data.html)\n* [总结](https://acodercat.github.io/function-call-principle/content/summary.html)\n\n\n\n## 本文可以收获什么？\n\n* 函数间如何转移控制\n* 函数间如何传递数据\n* 栈帧的初始化与销毁\n* C/C++数组越界的危害\n* 为什么内联（inline）函数效率高\n* 为什么尽量用循环来代替递归调用\n* 为什么静态变量在函数返回后不会被释放\n* 什么是栈溢出攻击\n\n\n\n## 其他\n\n文中有一个重要的概念`内存对齐`没有提及，它不属于函数调用范畴之内。我在构造示例时避免了编译器为了`内存对齐`而生成一些额外的指令，所以文中见不到它的影子。如果你有兴趣可以通过网络去了解与它相关的内容。\n\n\n\n## 相关资源\n\n* 书籍：\n  * 《深入理解计算机系统》（第三版）\n  * 《汇编语言》（王爽第三版）\n  \n* 公开课：\n  * 《编程范式》（斯坦福公开课）\n\n  \n\n## 绘图工具\n\n文中所有图片都使用了[excalidraw](https://excalidraw.com/)作为绘图工具，这是一款非常棒的在线绘图工具，它提供了不同风格的绘制模式。\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facodercat%2Ffunction-call-principle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Facodercat%2Ffunction-call-principle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facodercat%2Ffunction-call-principle/lists"}