05 | 计算机指令:让我们试试用纸带编程

当年学写程序的时古老的物理设备,“打孔卡(Punched Card)”。在纸带或者卡片上打洞,变成一条条纸带或卡片,再交给当时的计算机去处理。

在特定的位置上打洞或者不打洞,来代表“0”或者“1”。

为什么不能用 C 或者 Python 高级语言来写呢?CPU没有能力理解。即使今天计算机,仍只能处理“机器码”(一连串的“0”和“1”)。

高级语言怎么变成“0”和“1”的?一串串“0”和“1”又是怎么在 CPU 中处理的?“机器码”和“计算机指令”到底是怎么回事。

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

CPU 就是计算机的大脑。CPU 的全称是 Central Processing Unit,中文是中央处理器。

硬件角度:CPU 就是超大规模集成电路,通过电路实现了加法、乘法乃至各种各样的处理逻辑

软件角度,CPU执行各种计算机指令(InstructionCode)的逻辑机器。这里指令好比机器语言

不同 CPU 能听懂语言不一样。个人电脑用是 Intel 的 CPU,苹果手机ARM 的 CPU。两组不同的计算机指令集,英文叫 Instruction Set(集合)。

计算机程序成千上万条指令组成的,存储在存储器中,这种计算机叫作存储程序型计算机(Stored-programComputer)。

没有现代计算机之前,发明了一种叫 Plugboard Computer “插线板计算机”。布满了各种插口和插座的板子上,不同的电线来连接不同的插口和插座,完成各种计算任务。 IBM 的 Plugboard:

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

代码怎么变成指令,被 CPU 执行的呢? C 语言程序:

让这段程序在Linux上跑起来,需翻译成汇编语言(ASM,Assembly Language)的程序,这个过程叫编译(Compile)成汇编代码

汇编器(Assembler)翻译汇编代码机器码(Machine Code)。由“0”和“1”组成机器码(一串串的 16 进制数字)计算机指令。Linux:

汇编代码:$ gcc -g -c  test.c  

机器码:$ objdump -d -M  intel -S test.o 

左侧数字,就是机器码;右 push、mov、add、pop 汇编代码。一行 C 语言代码,对应一条或两条机器码和汇编代码。

GCC(GUC 编译器套装,GUI Compiler Collectipon)编译器时,直接把代码编译成机器码呀,为什么要汇编代码呢?机器码摸不着头脑,汇编代码多少也能“猜”出含义。 add、mov 容易记, 不像8b 45 f8 指令

三、解析指令和机器码

日常 Intel CPU,有 2000 条左右的 CPU 指令,分成五大类。

(1)算术类指令。加减乘除

(2)数据传输类指令。给变量赋值、内存里读写数据

(3)逻辑类指令。与或非

(4)条件分支类指令。“if/else”

(5)无条件跳转指令。调用函数时

汇编器怎么把汇编代码,翻译成为机器码:

MIPS 指令是32 位的整数,高 6 位叫操作码(Opcode),代表具体是什么样的指令,剩下 26 位有三种格式,分别是 R、I 和 J。

R 指令:算术和逻辑操作,有读和写寄存器地址。位移操作有位移操作的位移量,操作码不够时,功能码扩展操作码表示对应的具体指令的。

I 指令数据传输、条件分支,运算时候用并非变量还是常数的时候。没有位移量、操作码、第三个寄存器,把这三部分合并成了一个地址值或者一个常数

J 指令:高 6 位之外的 26 位都是跳转后地址

加法算术指令 add t0,t0,t0, s1, $s2, 例,用十进制表示代码。

MIPS 指令里 opcode 是 0,rs 代表第一个寄存器 s1 的地址是 17rt 代表第二个寄存器 s2 的地址是 18rd 代表目标的临时寄存器 t0 的地址,是 8。不是位移操作,位移量是 0。这些数字拼一起,变成了MIPS 加法指令。

二进制数,用 16 进制表示。 0X02324020。数字是指令对应机器码。

1000  1100  1001  0000 0000 1000 00

打孔代表 1,没有打孔代表 0,用 4 行 8 列代表一条指令来打一个穿孔纸带,这条命令长这样:

总结延伸

打孔卡,就是存储程序型计算机。

机器码,程序员“编译”成卡片的。程序存储成打孔卡片。程序运行的逻辑处理一串“0”和“1”组成的机器码。

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

推荐阅读

日常使用 Intel CPU 的指令集有所了解,《计算机组成与设计:软 / 硬件接口》第 5 版的 2.17 小节。

课后思考

把一个数字在命令行里面打印出来,背后对应的机器码是什么?通过 GCC 把这个的汇编代码和机器码打出来。

你可能感兴趣的:(05 | 计算机指令:让我们试试用纸带编程)