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 一个是软件、一个是硬件,没有从属关系
相关推荐
winfreedoms2 小时前
ROS2坐标转换,正解反解——黑马程序员ROS2课程上课笔记(5)
人工智能·笔记
EmbedLinX4 小时前
C语言标准库stdlib.h
c语言·开发语言·笔记
蒸蒸yyyyzwd7 小时前
os八股学习笔记
笔记·学习
Yeh2020587 小时前
2月14日笔记
笔记
不想看见4047 小时前
House Robber 基本动态规划:一维--力扣101算法题解笔记
笔记·算法·leetcode·代理模式
日光倾8 小时前
【Vue.js 入门笔记】Git入门
笔记·git
菩提小狗8 小时前
第16天:信息打点-CDN绕过&业务部署&漏洞回链&接口探针&全网扫描&反向邮件_笔记|小迪安全2023-2024|web安全|渗透测试|
笔记·安全·web安全
山岚的运维笔记8 小时前
SQL Server笔记 -- 第69章:时态表
数据库·笔记·后端·sql·microsoft·sqlserver
就叫飞六吧8 小时前
“赛博大佛” Cloudflare(简称 CF)
笔记