Datawhale 硅基生物进化论 202602第3次笔记

作业:

从github上下载老师的资料

https://github.com/embedded-idea/AJourneyFrom0and1

1. 准备文件(关键!路径不能错)
  • 在compiler这个文件下:
  • ✅ compiler.py:课本里给的编译器源码(核心文件,实现编译逻辑);
  • ✅ program.asm:你要编译的汇编源文件(自己写的汇编代码,比如之前提到的main相关指令)。
2. 执行编译器(运行 Python 代码)
  • 打开电脑的 "命令提示符(CMD)" 或 "终端";
  • 先切换到这个文件夹的路径(cd /d "E:\Datawhale 2026\从零入门计算机系统202602\compiler");
  • 输入运行命令:python compiler.py;
  • 回车执行,编译器会自动读取同目录的program.asm,编译后生成program.bin(目标机器码文件)。

记事本打开.bin 文件显示乱码 → 正常现象,是文本编辑器解析二进制数据的必然结果。

用 Hex 编辑器或命令行查看十六进制机器码:在文件所在目录执行以下命令(Windows 系统):

复制代码
certutil -dump program.bin

输出文件的十六进制内容如下:

作业完成!

笔记:

编译器的定义、作用与工作流程,通过 C 编译器实例建立感性认知,掌握简易 Python 编译器的实现逻辑,抓住编译器 "高级表示转低级表示" 的核心本质。

一、编译器基础定义与核心作用

  1. 定义 :将人类编写的高级语言源代码 翻译为机器可执行的机器码目标程序的软件工具,不仅完成翻译,还会做错误检查和程序优化。
  2. 核心作用(为何需要编译器)
    • 硬件适配:CPU 仅能识别机器码,高级语言必须经编译器转为指令序列才能运行;
    • 提前检错:在程序运行前发现类型不匹配、变量未定义等语法 / 语义错误;
    • 性能优化:通过循环优化、内联、寄存器分配等让程序运行更快;
    • 跨平台特性:同一份源码可针对不同 CPU / 系统编译出对应的可执行文件 / 库。

二、编译器的形象类比与常见 C 编译器

  1. 类比 :编译器是高级语言(中文) 与机器语言(英文,0 和 1) 之间的 "翻译官",让计算机理解人类编写的代码;
  2. 常见 C 编译器:GCC(GNU Compiler Collection)、Clang(LLVM 的 C 语言前端)、MSVC(Microsoft Visual C++)。

三、C 语言编译器的翻译全流程

C 编译器将.c 源码转为可执行文件分为4 个核心阶段,最终 Windows 生成.exe 文件,Linux 生成.elf 文件:

  1. 预处理 :处理#include(头文件包含)、#define(宏定义)等预处理指令;
  2. 编译:把 C 语言源代码翻译为汇编语言;
  3. 汇编:把汇编语言进一步翻译为机器码;
  4. 链接:将多个目标文件、库函数组合,生成最终的可执行文件。

四、C 代码编译为汇编语言的实操解析

以int main(){int a=9;int b=19;return a+b;}为例

以 GCC 编译器、x86 架构 64 位处理器为环境,核心分为 3 步:

1. 词法 / 语义分析 + 中间表示(IR)

编译器将代码转为抽象语法树,生成中间表示,明确代码执行逻辑:

  • 分配变量 a,赋值 9;分配变量 b,赋值 19;
  • 执行 a+b 运算,返回运算结果。

2. 生成汇编语言(简化版,带核心注释)

asm

复制代码
main:
push    rbp         ; 保存旧的栈帧指针
mov     rbp,rsp     ; 设置新的栈帧
mov     DWORD PTR [rbp-4],9  ; 给int a赋值9,存储在栈中
mov     DWORD PTR [rbp-8],19 ; 给int b赋值19,存储在栈中
mov     eax,DWORD PTR [rbp-4] ; 把a的值加载到返回值寄存器eax
add     eax,DWORD PTR [rbp-8] ; 把b的值加到eax,完成a+b
pop     rbp         ; 恢复旧的栈帧
ret                 ; 返回eax中的结果(a+b),作为程序退出码

3. 机器运行时的核心细节

  • rbp/rsp:栈帧管理寄存器,负责保存 / 设置栈指针,处理函数调用;
  • eax:约定俗成的返回值寄存器,用于存储函数的返回结果;
  • 局部变量 a、b:存储在栈中,对应 rbp 的偏移量位置;
  • 真正的运算:由add指令执行,最终通过ret指令将结果返回操作系统。

五、简易 Python 编译器的实现(核心:不到 200 行代码,覆盖编译器最小闭环)

1. 整体结构

分为入口函数 和核心函数两部分,实现 "读源文件→预处理→译机器码→写目标文件" 的最小闭环:

表格

函数部分 核心职责
入口函数 调用核心编译函数,捕捉语法错误并提示,编译结束后输出compiling completed
核心函数compile_program() 编译器的核心,承担所有实质性编译工作

2. 核心函数compile_program()的执行步骤

  1. 读取源文件:打开同目录下的program.asm汇编源文件,逐行读取并去除注释、多余空白;
  2. 构造指令对象:为每条有效汇编指令构造Code类对象,拆解操作码(OPcode) 和操作数(寄存器、立即数等);
  3. 翻译机器码:调用compile_code()方法,将汇编指令转为二进制机器码;
  4. 写入目标文件:将机器码按顺序写入program.bin文件,生成可在虚拟机 / 自制 CPU 上运行的可执行代码。

3. 运行与扩展说明

  • 运行条件:机器安装 Python 环境,直接执行编译器脚本compiler.py;
  • 文件要求:汇编源文件必须命名为program.asm,且与编译器脚本在同一目录;
  • 扩展方向:可自行修改代码,实现动态指定源文件名、增加更多编译功能等。

六、总结

  1. 编译器的本质:高级表示(源代码 / 汇编)向低级表示(机器码)的转化工具,伴随检错、优化、链接等附加功能;
  2. 编译的核心逻辑:无论工业级还是简易编译器,都遵循 "读取源文件→预处理→翻译→生成目标文件" 的核心流程;
  3. 简易编译器的价值:覆盖编译器的最小闭环,是初学者入门编译原理的最佳实操范例,理解其逻辑即可抓住编译器的核心思想。
  4. 编译器是一款运行在电脑上的翻译软件,专门把程序员写的、人能看懂的高级语言代码,翻译成 CPU 能执行的机器码,同时还会检查代码错误、优化程序性能,它和 CPU 一个是软件、一个是硬件,没有从属关系。
相关推荐
蒸蒸yyyyzwd6 小时前
AI应用相关可能的面试问题
笔记
叼烟扛炮7 小时前
[Git 实战] 学习笔记:从生成 SSH 密钥到解决 TortoiseGit 推送报错全指南
linux·运维·笔记·git·学习
蒸蒸yyyyzwd8 小时前
学习笔记 八股手撕
笔记·学习
揣一尾游鱼yu9 小时前
Spring上(IOC)笔记
java·笔记·spring·ioc
小李不想当小白11 小时前
BKP备份寄存器与RTC实时时钟(STM32标准库学习笔记)
笔记·stm32·单片机·嵌入式硬件·学习·嵌入式
瑞码空间13 小时前
JSP与Servlet核心开发与CRUD实战笔记
java·笔记·servlet·jsp
La Pulga13 小时前
【FreeRTOS源码学习笔记】链表的实现
数据结构·笔记·stm32·mcu·链表·嵌入式·freertos
wuyoutrans16 小时前
以色列专利OA答复翻译,重点要避开哪些坑?
笔记
宝绿特塑业再生科技16 小时前
HDPE再生颗粒户外家具表面粉化机理与改性技术全解析
笔记·户外家具·再生塑料·塑木桌椅
凉、介17 小时前
深入理解 ARMv7-A | Generic Timer
笔记·学习·嵌入式·arm