深入浅出计算机组成原理学习笔记:第五讲

一、在软硬件接口中,CPU帮我们做了什么事情

1、从硬件角度看CPU

2、软件工程师看CPU

3、不同的cpu能听懂的语言不太一样

4、不同的指令无法相通

5、存储程序型计算机

一台IBM的Plugboard

 

二、从编译到汇编,代码怎么变成机器码?

1、C 语言程序程序案例

1、我们拿一小段真实的 C 语言程序来看看。

1
2
3
4
5
6
7
[root@luoahong c]# cat test.c
int main()
{
  int a = 1;
  int b = 2;
  a = a + b;
}

2、要让这段程序在一个 Linux 操作系统上跑起来,我们需要把整个程序翻译成一个汇编语言

1
2
[root@luoahong c]# gcc -g -c test.c
[root@luoahong c]# objdump -d -M intel -S test.o

3、在一个 Linux 操作系统上,我们可以简单地使用 gcc 和 objdump 这样两条命令,把对应的汇编代码和机器码都打印出来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[root@luoahong c]# objdump -d -M intel -S test.o
 
test.o:     file format elf64-x86-64
 
 
Disassembly of section .text:
 
0000000000000000 <main>:
int main()
{
   0:   55                      push   rbp
   1:   48 89 e5                mov    rbp,rsp
  int a = 1;
   4:   c7 45 fc 01 00 00 00    mov    DWORD PTR [rbp-0x4],0x1
  int b = 2;
   b:   c7 45 f8 02 00 00 00    mov    DWORD PTR [rbp-0x8],0x2
  a = a + b;
  12:   8b 45 f8                mov    eax,DWORD PTR [rbp-0x8]
  15:   01 45 fc                add    DWORD PTR [rbp-0x4],eax
}
  18:   5d                      pop    rbp
  19:   c3                      ret

2、为什么需要汇编代码呢?

我们实际在用 GCC(GUC 编译器套装,GUI CompilerCollectipon)编译器的时候,可以直接把代码编译成机器码呀,

为什么还需要汇编代码呢?原因很简单,你看着那一串数字表示的机器码,是不是摸不着头脑?但是即使你没有学过汇编代码,

看的时候多少也能“猜”出一些这些代码的含义。因为汇编代码其实就是“给程序员看的机器码”,也正因为这样,机器码和汇编代码是一一对应的。

3、从高级语言—汇编代码—机器码

 

从高级语言到汇编代码,再到机器码,就是一个日常开发程序,最终变成了 CPU 可以执行的计算机指令的过程。

三、解析指令和机器码

1、常见指令

你可能一下子记不住,或者对这些指令的含义还不能一下子掌握,这里我画了一个表格,给你举例子说明一下,帮你理解、记忆。

 

2、MIPS的指令

 

 为了读起来方便,我们一般把对应的二进制数,用 16 进制表示出来。在这里,也就是0X02324020。这个数字也就是这条指令对应的机器码。

回到开头我们说的打孔带。如果我们用打孔代表 1,没有打孔代表 0,用 4 行 8 列代表一条指令来打一个穿孔纸带,那么这条命令大概就长这样:

 

四、总结和延伸

到这里,想必你也应该明白了,我们在这一讲的开头介绍的打孔卡,其实就是一种存储程序型计算机。

 

只是这整个程序的机器码,不是通过计算机编译出来的,而是由程序员,用人脑“编译”成一张张卡片的。对应的程序,也不是存储在设备里,而是存储成一张打好孔的卡片。

但是整个程序运行的逻辑和其他 CPU 的机器语言没有什么分别,也是处理一串“0”和“1”组成的机器码而已

 

这一讲里,我们看到了一个 C 语言程序,是怎么被编译成为汇编语言,乃至通过汇编器再翻译成机器码的。

 

除了 C 这样的编译型的语言之外,不管是 Python 这样的解释型语言,还是 Java 这样使用虚拟机的语言,其实最终都是由不同形式的程序,把我们写好的代码,转换成 CPU 能够理解的机器码来执行的。

 

只是解释型语言,是通过解释器在程序运行的时候逐句翻译,而 Java 这样使用虚拟机的语言,则是由虚拟机对编译出来的中间代码进行解释,或者即时编译成为机器码来最终执行。

然而,单单理解一条指令是怎么变成机器码的肯定是不够的。接下来的几节,我会深入讲解,包含条件、循环、函数、递归这些语句的完整程序,是怎么在 CPU里执行的

posted @   活的潇洒80  阅读(2200)  评论(1编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示