CPU + 计算机指令

  1. 硬件的角度
    • CPU是一个超大规模集成电路,通过电路实现了加法、乘法乃至各种各样的处理逻辑
  2. 软件工程师的角度
    • CPU就是一个执行各种计算机指令的逻辑机器
    • 计算机指令是一门CPU能听懂的语言,也称为机器语言
    • 不同的CPU能够听懂的语言不太一样,两种CPU各自支持的语言,就是两组不同的计算机指令集
    • 计算机程序平时是存储在存储器中,这种程序指令存储在存储器里面的计算机,叫作存储程序型计算机

代码 -> 机器码(编译 -> 汇编)

1
2
3
4
5
6
7
// test.c
int main()
{
int a = 1;
int b = 2;
a = a + b;
}
  1. 编译(Compile)成汇编代码:把整个程序翻译成一个汇编语言(ASM,Assembly Language)的程序
  2. 汇编:针对汇编代码,用汇编器(Assembler)翻译成机器码(Machine Code)
    • 机器码由01组成的机器语言表示,一串串的16进制数字,就是CPU能够真正认识的计算机指令

汇编代码 + 机器码

1
2
3
4
5
6
7
8
9
10
$ gcc --help
-c 编译、汇编到目标代码,不进行链接

$ objdump --help
-d, --disassemble Display assembler contents of executable sections
-M, --disassembler-options=OPT 将文本传递到 OPT 反汇编程序
-S, --source Intermix source code with disassembly

$ gcc -g -c test.c
$ objdump -d -M intel -S test.o
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
test.o:     文件格式 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
  1. 左边的一堆数字是机器码,右边一系列的push,mov,add,pop就是对应的汇编代码
  2. 一行C代码,可能会对应一条或多条机器码和汇编代码
  3. 汇编代码和机器码之间是一一对应
    • 汇编代码:给程序员看的机器码!!

解析指令和机器码

指令类型

指令类型 场景 示例指令 示例汇编代码 含义 注释
算术指令 加减乘除 add add $s1,$s2,$s3 $s1=$s2+$s3 将s2和s3寄存器中的数相加后的结果放到寄存器s1中
逻辑指令 与、非 or or $s1,$s2,$s3 $s1=$s2|$s3 将s2和s3寄存器中的数按位取或后的结果放到寄存器s1中
数据传输指令 变量赋值、在内存读写数据 load load $1,10($2) $s1=memroy[$s2+10] 取s2寄存器中的数,加上10偏移量后,
找到内存中的,存入到s1寄存器中
条件分支指令 if-else branch on equal beq $s1,$s2,10 if($s1==$s2) goto PC+4+10 如果s1和s2寄存器内的值相等,从程序计数器往后跳10
无条件跳转指令 函数调用 jump j 1000 goto 1000 跳转到1000这个目标地址

MIPS指令集

  1. MIPS指令是一个32位的整数,高6位叫作操作码(opcode),代表这条指令具体是一条怎样的指令
    • 剩下的26位有三种格式,分别是RIJ
    • R指令
      • 一般用来做算术逻辑操作,里面有读取和写入数据的寄存器地址
      • 如果是逻辑位操作,后面还有位移操作的位移量
      • 最后的功能码,则是在前面的操作码不够的时候,扩展操作码表示对应的具体指令
    • I指令
      • 通常用在数据传输条件分支、以及在运算时使用的并非变量而是常数的时候
      • 第三种情况:此时没有了位移量和操作码,也没有第三个寄存器,而是把这三部分直接合并成一个地址值或者一个常数
    • J指令
      • 跳转指令,高6位之外的26位都是一个跳转后的地址
  2. add $t0,$s1,$s2,用十进制表示
    • opcode:0
    • rs代表第一个寄存器s1的地址17
    • rt代表第二个寄存器s2的地址18
    • rd代表目标的临时寄存器t0的地址8
    • 由于不是位移操作,所以位移量是0

打孔代表1,没打孔代表0

参考资料

深入浅出计算机组成原理