谢邀
语言运行有两大类:解释器,编译器。
编译
需要编译的语言,以 c、c++ 为代表,你写的高级语言先经过一个编译器转为汇编语言,再用汇编器转为机器语言。常见的汇编语言有 Intel 和 AT&T 两种主流风格汇编语言。
C语言:
int add_a_and_b(int a, int b) {
return a + b;
}
int main() {
return add_a_and_b(2, 3);
}
汇编语言:
_add_a_and_b:
push %ebx
mov %eax, [%esp+8]
mov %ebx, [%esp+12]
add %eax, %ebx
pop %ebx
ret
_main:
push 3
push 2
call _add_a_and_b
add %esp, 8
ret
这里汇编语言直接操作寄存器。
建议手写:编译器,写了编译器才能理解高级语言怎么转化为AST,AST怎么转化为IR,IR怎么转化为汇编语言。寄存器分配、内存分配,还有各种优化都是值得试一试的。初学者必备的龙书虎书鲸书,助力你早日开编译器‘动物园’。优化到 GCC O1 的程度的工作量是可以接受的,适合作为大二学生的编译原理单人大作业。你可以自己随便造一个 benchmark,优化跑分。
机器码:
对以上的汇编语言进行简单翻译,机器码就是芯片直接可以运行的二进制。机器码可以参考“RiscV”这个教学版本的指令集。以上是如果没有操作系统单机运行一个程序的情况。
建议手写:Verilog的加法器、减法器(小作业)
建议手写:Verilog的RiscV简易实现。为什么RiscV?因为精简,还有toolchain帮你debug。可以作为大二学生的体系结构单人大作业。理解TLB的技术细节(虽然教学板子RAM不够OS,但是你可以理性愉悦),理解多核Cache Line一致性问题,理解多发射的Tomasulo。实现多核是可选非必须的。
如果有操作系统
操作系统的功能是:操作系统(英语:Operating System,缩写:OS)是一组主管并控制计算机操作、运用和运行硬件、软件资源和提供公共服务来组织用户交互的相互关联的系统软件程序,同时也是计算机系统的内核与基石。操作系统需要处理如管理与配置内存、决定系统资源供需的优先次序、控制输入与输出设备、操作网络与管理文件系统等基本事务。操作系统也提供一个让用户与系统交互的操作界面。
操作系统的类型非常多样,不同机器安装的操作系统可从简单到复杂,可从移动电话的嵌入式系统到超级电脑的大型操作系统。许多操作系统制造者对它涵盖范畴的定义也不尽一致,例如有些操作系统集成了图形用户界面,而有些仅使用命令行界面,而将图形用户界面视为一种非必要的应用程序。
操作系统里面运行一个程序,其实运算部分的机器码不需要改变,只有系统调用需要改。
操作系统里面,你运行的程序会遭遇“时钟中断”,然后从‘专注于’运行一个程序切换到‘专注于’运行另一个程序。你的程序会使用虚拟地址,也就是说你的程序除了调用一些系统调用的时候外,和没有操作系统的时候运行几乎一样。建议学习:中断向量。
为什么没有感觉程序断了呢?答:“时钟中断”足够短,比如(我瞎扯一个时间)1ms 就切换一下,你不会觉得没有正在运行的程序断了。
建议手写: PintOS Project。填空啦,一个操作系统内核。工作量不太大,可以作为大二学生的操作系统单人大作业。这个有很详细的guide,看不懂可以多看看,或者看开一些。
解释器
以 python 为代表
一个二进制程序把你写的高级语言的代码作为文本读入并按照运算流程进行模拟,就是解释器的大致工作方式。运行方式类似于 NOIP 的“读程序写结果”人体解释器,就是傻傻地模拟一下。解释器运行比编译运行通常慢。
编译后用虚拟机运行
以java代表
这里的虚拟机指的是java虚拟机之类的,并不是 CS 里面的对于 OS 的 VM 的意思。javac是编译器,把一个高级语言的代码编译为一个并不是机器码的class二进制码。这个class二进制码可以由另一个机器码的程序java(JVM)来解释运行。