一溪风月
一溪风月
Published on 2023-01-06 / 103 Visits
0
0

使用纸带编写计算机程序

使用纸带编写计算机程序

计算机并不认识高级语言,因此需要将高级语言翻译成机器语言,CPU才能执行。机器语言就是一串数字。我们用纸带的孔来代表 0 和 1。这样我们就可以使用纸带表示一条条机器指令,让 CPU 去执行。接下来看一个例子。

//test.c
int main(){
    int a = 1;
    int b = 2;
    a += b;
}

这是一段非常简单的 C 程序。首先我们需要知道这段程序的机器指令,可以借助 gcc 和 objdump 这两个工具帮助我们把这段程序的汇编代码和机器码打印出来。

gcc -g -c test.c
objdump -d -M MIPS -S test.o

执行上面两条指令后,可以在控制台看到下面的内容

test.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <main>:
int main(){
   0:   f3 0f 1e fa             endbr64
   4:   55                      push   %rbp
   5:   48 89 e5                mov    %rsp,%rbp
        int a = 1;
   8:   c7 45 f8 01 00 00 00    movl   $0x1,-0x8(%rbp)
        int b = 2;
   f:   c7 45 fc 02 00 00 00    movl   $0x2,-0x4(%rbp)
        a += b;
  16:   8b 45 fc                mov    -0x4(%rbp),%eax
  19:   01 45 f8                add    %eax,-0x8(%rbp)
  1c:   b8 00 00 00 00          mov    $0x0,%eax
}
  21:   5d                      pop    %rbp
  22:   c3                      retq

不同的 CPU 有不同的指令集,对应着不同的汇编语言和不同的机器码。上面我们是使用了 MIPS 指令集,MIPS 是一组有 MIPS 技术公司在 80 年代中期设计出来的 CPU 指令集,现在已经开源了。

指令类型

6位

5位

5位

5位

5位

6位

解释

R

opcode

rs

rt

rd

shamt位移量

funct功能码

算术操作、逻辑运算

I

opcode

rs

rt

address/immediate 地址/立即数

数据传输、条件分支、立即数操作

J

opcode

taget address 目标地址

无条件跳转

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

  1. R 指令一般用来做算术和逻辑运算,里面有读取和写入数据的寄存器的地址。如果是逻辑位移操作,后面还有位移操作的位移量,而最后的功能码,则是在前面的操作码不够的时候,扩展操作码表示对应的具体指令的。

  2. I 指令,则通常是用在数据传输、条件分支以及在运算的时候使用的并非变量而是常数的时候。这个时候,没有位移量和操作码,不需要第三个寄存器,而是把这三部分直接合并成了一个地址值或者一个常数。

  3. J 指令就是跳转指令,高 6 位之外的 26 位都是一个跳转后的地址。

看下面的例子

add $t0,$s2,$s1

这是 R 型指令,对应的 opcode 为 0。rs 代表第一个寄存器 s1 的地址是 17。rt 代表第二个寄存器 s2 的地址是 18。rd代表目标的临时寄存器 t0 的地址,是 8。因为不是位移操作,所以位移量是 0。把这些数字拼在一起,就是一条 MIPS 的加法指令。

指令

格式

opcode

rs

rt

rd

shamt

funct

add

R

0

17

18

8

0

32

二进制

000000

10001

10010

01000

00000

100000

十六进制

0X02324020

现在对这个十六进制的指令在纸带上编程,我们约定,打孔表示 1,未打孔表示0。

Snipaste_2023-01-06_15-37-26.png

这样就可以使用纸带打孔编程了。


Comment