高级语言,汇编语言,机器语言
本文最后更新于5 天前,其中的信息可能已经过时,如有错误请发送邮件到184874483@qq.com

一、先建立一条主线:CPU 最终只能执行机器指令

计算机里这些概念可以先按一条主线理解:

高级语言源程序
    ↓ 预处理
预处理后的源程序
    ↓ 编译
汇编语言源程序
    ↓ 汇编
可重定位目标文件
    ↓ 链接
可执行目标文件
    ↓ 操作系统装入内存并创建进程
正在运行的程序
    ↓ CPU 执行
机器指令

最底层的硬件 CPU 并不认识 C、C++、Java、Python,也不认识“for 循环”“函数”“对象”这些高级概念。CPU 只认识某种指令集体系结构规定的机器指令,例如 x86、ARM、RISC-V 等。

所以从考研角度看,最核心的一句话是:

高级语言程序要想运行,最终必须转换成某种机器指令,或者由某个已经是机器指令实现的解释器 / 虚拟机来间接执行。

二、高级语言、汇编语言、机器语言怎么区分

1. 机器语言:CPU 真正能直接执行的二进制指令

机器语言就是机器指令的二进制编码。比如某条指令在汇编里写成:

add eax, ebx

在机器里可能对应一串二进制编码。CPU 取指令、译码、执行时,真正看到的是二进制机器码,而不是 add eax, ebx 这种文本。

机器语言和具体 CPU 指令集强相关。x86 的机器码不能直接拿到 ARM CPU 上执行,ARM 的机器码也不能直接拿到 x86 CPU 上执行。这就是为什么同一个 C 程序在不同平台上需要重新编译。

2. 汇编语言:机器指令的符号化表示

汇编语言可以理解为机器语言的“助记符版本”。它把难以阅读的二进制机器码,用人相对容易读的符号表示出来。

例如:

mov eax, 1
add eax, 2

这比直接写二进制机器码容易得多。

在考研中常说:

汇编语言与机器语言基本是一一对应的。

但这里要稍微严谨一点。真实汇编中有伪指令、宏、汇编指示语等内容,它们不一定直接对应一条机器指令。例如 .data.text.globl main 这类内容主要是给汇编器和链接器看的,不是 CPU 直接执行的机器指令。

所以更准确的表达是:

汇编语言中的真正机器指令助记符通常与机器指令基本一一对应,但汇编源程序中还可能包含伪指令、标号、段声明、重定位信息等辅助内容。

3. 高级语言:更接近人的问题表达

高级语言包括 C、C++、Java、Python 等。它们使用变量、函数、循环、结构体、类、对象等抽象,离机器指令更远。

例如 C 语言中的:

for (int i = 0; i < n; i++) {
    sum += a[i];
}

它不会对应一条机器指令,而是会被翻译成很多条机器指令,包括循环控制、地址计算、数组访问、加法、跳转等。

所以可以这样比较:

层次典型形式和硬件关系特点
机器语言二进制机器码CPU 直接执行最底层,平台相关
汇编语言movaddjmp基本对应机器指令仍然强烈依赖指令集
高级语言C、Java、Python需要翻译或解释更接近人的逻辑表达

三、指令集是什么:软件和硬件之间的接口

这里还要单独理解“指令集”。

指令集体系结构,简称 ISA,本质上是 CPU 对外提供的一套指令规范。

它规定了 CPU 支持哪些指令、有哪些寄存器、指令格式是什么、寻址方式有哪些、内存访问规则是什么。

比如:

x86
ARM
RISC-V
MIPS

这些就是不同的指令集体系结构。

高级语言程序最终编译成什么机器码,取决于目标机器的指令集。编译器生成代码时,必须面向某个目标平台。例如:

C 源程序
    ↓ x86 编译器
x86 机器码

C 源程序
    ↓ ARM 编译器
ARM 机器码

同一份 C 源代码可以跨平台,但编译后的机器码通常不能跨平台。所谓“高级语言可移植”,主要是指源程序层面的可移植,不是可执行文件层面的可移植。

四、操作系统在中间起什么作用

操作系统不是把高级语言翻译成机器语言的工具。这个工作主要由编译器、汇编器、链接器或解释器、虚拟机完成。

操作系统的主要作用是:

管理硬件资源
提供程序运行环境
提供系统调用接口
负责程序装入和进程管理
提供文件、内存、I/O、网络等抽象

一个可执行文件生成以后,并不是它自己“跳进 CPU”运行,而是由操作系统装入内存,创建进程,分配虚拟地址空间,设置栈、堆、代码段、数据段,然后把 CPU 控制权交给程序入口。

所以完整运行过程大致是:

可执行文件
    ↓ 操作系统装入器 loader
进程地址空间
    ↓ CPU 从入口地址开始执行
机器指令逐条执行

在操作系统课程中,经常强调一个概念:

程序是静态的,进程是动态的。

可执行文件放在磁盘上时只是一个静态文件;它被操作系统装入内存并开始运行后,才成为进程。

五、高级语言虚拟机和操作系统虚拟机怎么区分

“虚拟机”这个词很容易混乱,因为不同课程里它有不同含义。

1. 高级语言虚拟机:面向某种语言运行环境

高级语言虚拟机典型例子是:

JVM:Java 虚拟机
CLR:.NET 公共语言运行时
Python VM:Python 字节码虚拟机

以 Java 为例,流程通常是:

Java 源程序 .java
    ↓ javac 编译
Java 字节码 .class
    ↓ JVM 解释执行或 JIT 编译
本机机器指令
    ↓ CPU 执行

这里的 JVM 本身其实也是一个运行在操作系统上的程序。CPU 并不是直接执行 Java 字节码,而是执行 JVM 这个程序的机器码。JVM 再去解释或即时编译 Java 字节码。

所以高级语言虚拟机的本质是:

在操作系统之上提供一种语言级运行环境,让程序不直接面向具体机器指令,而是先面向一种中间代码或字节码。

它解决的核心问题是语言运行、跨平台、内存管理、异常处理、类加载、垃圾回收等。

2. 操作系统虚拟机:虚拟出一整台计算机

操作系统虚拟机典型例子是:

VMware
VirtualBox
KVM
Hyper-V

它虚拟的是硬件环境,例如:

虚拟 CPU
虚拟内存
虚拟磁盘
虚拟网卡
虚拟 BIOS/UEFI

然后在这个虚拟硬件上安装一个完整的操作系统。

比如在 Windows 主机上运行 VMware,然后在 VMware 里安装 Linux。这个 Linux 会以为自己运行在一台真实计算机上,但实际上它面对的是虚拟化出来的硬件。

所以操作系统虚拟机的本质是:

在物理硬件或宿主操作系统之上,模拟或虚拟出一套完整硬件环境,使另一个操作系统可以运行。

3. 二者区别

类型虚拟的对象运行对象典型例子
高级语言虚拟机语言运行环境字节码 / 中间代码JVM、Python VM
操作系统虚拟机整台计算机硬件完整操作系统VMware、VirtualBox、KVM

一句话区分:

JVM 是为了运行 Java 程序;VMware 是为了运行另一个操作系统。

六、预处理、编译、汇编、链接分别做什么

这是计算机组成原理和操作系统里非常重要的一条流程,尤其常考“源程序到可执行文件经过哪些阶段”。

以 C 语言为例,完整过程是:

hello.c
    ↓ 预处理
hello.i
    ↓ 编译
hello.s
    ↓ 汇编
hello.o
    ↓ 链接
hello / hello.exe

1. 预处理:处理 # 开头的预处理命令

预处理阶段主要处理:

#include
#define
#if / #ifdef / #endif

例如:

#include <stdio.h>
#define N 100

预处理器会把头文件内容展开,把宏替换掉,处理条件编译,并去掉注释。

预处理之后得到的仍然是 C 语言形式的源程序,只不过已经被展开。

hello.c → hello.i

考研中可以这样记:

预处理主要处理宏定义、文件包含、条件编译,输出预处理后的源程序。

2. 编译:把高级语言翻译成汇编语言

编译阶段把预处理后的高级语言程序翻译成汇编语言程序。

hello.i → hello.s

这一阶段内部其实很复杂,通常包括:

词法分析
语法分析
语义分析
中间代码生成
代码优化
目标代码生成

但在组成原理或操作系统题目里,通常不要求展开到这么细。常见考法只需要知道:

编译阶段把高级语言程序翻译成汇编语言程序。

这里要注意“编译器”这个词有狭义和广义。

狭义地说:

编译:高级语言 → 汇编语言

广义地说,人们也会把整个过程叫“编译”:

预处理 + 编译 + 汇编 + 链接

比如平时说“用 gcc 编译 C 程序”,实际上 gcc 驱动了预处理器、编译器、汇编器、链接器多个工具。

3. 汇编:把汇编语言翻译成机器指令,生成可重定位目标文件

汇编阶段把汇编语言源程序翻译成机器语言指令,并封装成目标文件。

hello.s → hello.o

这个 .o 文件已经包含机器指令,但它通常还不能直接运行,因为它可能还有一些外部符号没有解决,比如调用了 printf,但 printf 的地址还不知道。

所以汇编后的目标文件叫:

可重定位目标文件

它里面通常包含:

机器代码
数据
符号表
重定位信息
调试信息

“可重定位”的意思是:其中某些地址还不是最终运行地址,后续链接时还要调整。

4. 链接:合并目标文件和库,生成可执行文件

链接阶段把多个目标文件和需要的库文件合并起来,生成可执行目标文件。

hello.o + libc 等库
    ↓ 链接
hello / hello.exe

链接器主要做两件大事:

符号解析
重定位

所谓符号解析,就是确定函数名、变量名到底对应哪里。例如 mainprintf、全局变量等。

所谓重定位,就是把目标文件中尚未确定的地址修改成最终地址。例如某条 call printf 指令到底跳到哪里,要在链接时确定或部分确定。

所以链接不是简单地“把文件拼接起来”,而是要解决符号引用和地址安排问题。

七、可重定位目标文件、可执行目标文件、共享目标文件

目标文件常见有三类,这也是容易混的地方。

类型含义是否能直接运行
可重定位目标文件.o / .obj,由汇编生成,等待链接不能
可执行目标文件Linux 下常见 ELF 可执行文件,Windows 下 .exe可以被操作系统装入运行
共享目标文件.so / .dll,运行时或链接时被加载不能单独当普通程序运行

可重定位目标文件里已经有机器指令,但它不是完整程序。它可能没有完整入口,外部函数地址未解决,地址也没有最终确定,所以不能直接运行。

可执行目标文件是链接完成后的结果,操作系统可以把它装入内存并创建进程。

共享目标文件一般用于动态链接。例如 Linux 中的 .so,Windows 中的 .dll。它们可以在程序运行时被加载。

八、静态链接和动态链接

链接还有静态链接和动态链接之分。

静态链接是把需要的库代码直接合并到可执行文件中。这样生成的可执行文件比较大,但运行时对外部库依赖较少。

动态链接不是把所有库代码都复制进可执行文件,而是在运行时加载共享库。例如很多程序运行时会加载 .dll.so 文件。

从考研角度看,重点不是背平台细节,而是理解:

静态链接:库代码进入可执行文件
动态链接:运行时再装入共享库

动态链接的好处是节省磁盘和内存空间,便于库更新;缺点是运行时依赖共享库环境,可能出现版本兼容问题。

九、高级语言程序到可执行目标文件的主要过程

如果题目问:

将高级语言源程序转换为可执行目标文件的主要过程是什么?

标准答案一般写:

预处理、编译、汇编、链接

更完整地说:

高级语言源程序
经过预处理,处理宏定义、文件包含和条件编译,得到预处理后的源程序;
经过编译,翻译成汇编语言源程序;
经过汇编,翻译成可重定位目标文件;
经过链接,把多个目标文件和库文件合并,完成符号解析和重定位,生成可执行目标文件。

如果是简答题,可以写成:

高级语言源程序 → 预处理后的源程序 → 汇编语言源程序 → 可重定位目标文件 → 可执行目标文件。
对应阶段为:预处理、编译、汇编、链接。

如果题目只问“编译系统包括哪些阶段”,通常也是这四步。

如果题目问“编译程序的作用”,则要看语境。狭义编译程序通常指:

把高级语言程序翻译成汇编语言程序或目标代码

但广义编译过程可能包含预处理、编译、汇编、链接。

十、把这些概念放在一张总图里

可以用这张图把所有层次串起来:

程序员写的代码
    │
    ├── C/C++ 这类编译型语言
    │       ↓ 预处理
    │       ↓ 编译
    │       ↓ 汇编
    │       ↓ 链接
    │   本机可执行文件
    │       ↓ 操作系统装入
    │   进程
    │       ↓ CPU 执行机器指令
    │
    ├── Java 这类虚拟机语言
    │       ↓ 编译
    │   字节码
    │       ↓ JVM 解释 / JIT 编译
    │   本机机器指令
    │       ↓ CPU 执行
    │
    └── Python 这类解释型语言
            ↓ 解释器 / 虚拟机
        字节码或解释执行过程
            ↓ 最终仍由 CPU 执行解释器的机器指令

这里最容易错的一点是:不要以为解释型语言就不需要机器指令。

Python 程序看起来没有生成 .exe,但 Python 解释器本身就是一个已经编译好的可执行程序。CPU 执行的是 Python 解释器的机器码,解释器再读取并执行 Python 代码。

所以不管是编译型语言、解释型语言,还是虚拟机语言,最后都绕不开:

CPU 执行机器指令

十一、考研中最容易混的点

第一,汇编语言不是机器语言本身,而是机器语言的符号表示。CPU 直接执行的是机器码,不是汇编文本。

第二,高级语言的一条语句通常对应多条机器指令,不存在一一对应关系。汇编语言和机器指令才基本接近一一对应。

第三,可重定位目标文件不是可执行文件。.o 文件里已经有机器码,但还没有完成链接,不能直接作为普通程序运行。

第四,链接不是简单合并文件,而是完成符号解析和重定位。

第五,操作系统不是编译器。操作系统负责装入、调度、内存管理、文件管理、I/O 管理、系统调用等;编译器、汇编器、链接器负责程序翻译和构造。

第六,高级语言虚拟机和操作系统虚拟机不是一回事。JVM 是语言运行环境,VMware 是虚拟整台计算机。

十二、最后压缩成一句复习版

这组概念可以这样记:

高级语言便于人写,汇编语言接近机器,机器语言由 CPU 直接执行;
指令集规定 CPU 能执行什么机器指令;
编译系统通过预处理、编译、汇编、链接,把高级语言源程序变成可执行目标文件;
操作系统负责把可执行文件装入内存并创建进程;
高级语言虚拟机运行字节码,操作系统虚拟机虚拟整台计算机;
无论哪种方式,最终都必须落实到 CPU 执行机器指令。
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇