计算机组成 -- 指令
CPU + 计算机指令
- 硬件的角度
- CPU是一个超大规模集成电路,通过电路实现了加法、乘法乃至各种各样的处理逻辑
- 软件工程师的角度
- CPU就是一个执行各种计算机指令的逻辑机器
- 计算机指令是一门CPU能听懂的语言,也称为机器语言
- 不同的CPU能够听懂的语言不太一样,两种CPU各自支持的语言,就是两组不同的计算机指令集
- 计算机程序平时是存储在存储器中,这种程序指令存储在存储器里面的计算机,叫作存储程序型计算机
代码 -> 机器码(编译 -> 汇编)
1 | // test.c |
- 编译(Compile)成汇编代码:把整个程序翻译成一个汇编语言(ASM,Assembly Language)的程序
- 汇编:针对汇编代码,用汇编器(Assembler)翻译成机器码(Machine Code)
- 机器码由0和1组成的机器语言表示,一串串的16进制数字,就是CPU能够真正认识的计算机指令
汇编代码 + 机器码
1 | $ gcc --help |
1 | test.o: 文件格式 elf64-x86-64 |
- 左边的一堆数字是机器码,右边一系列的
push,mov,add,pop
就是对应的汇编代码 - 一行C代码,可能会对应一条或多条机器码和汇编代码
- 汇编代码和机器码之间是一一对应的
- 汇编代码:给程序员看的机器码!!
解析指令和机器码
指令类型
指令类型 | 场景 | 示例指令 | 示例汇编代码 | 含义 | 注释 |
---|---|---|---|---|---|
算术指令 | 加减乘除 | 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指令集
- MIPS指令是一个32位的整数,高6位叫作操作码(opcode),代表这条指令具体是一条怎样的指令
- 剩下的26位有三种格式,分别是R、I、J
- R指令
- 一般用来做算术和逻辑操作,里面有读取和写入数据的寄存器地址
- 如果是逻辑位操作,后面还有位移操作的位移量
- 最后的功能码,则是在前面的操作码不够的时候,扩展操作码表示对应的具体指令
- I指令
- 通常用在数据传输、条件分支、以及在运算时使用的并非变量而是常数的时候
- 第三种情况:此时没有了位移量和操作码,也没有第三个寄存器,而是把这三部分直接合并成一个地址值或者一个常数
- J指令
- 跳转指令,高6位之外的26位都是一个跳转后的地址
add $t0,$s1,$s2
,用十进制表示- opcode:0
- rs代表第一个寄存器s1的地址17
- rt代表第二个寄存器s2的地址18
- rd代表目标的临时寄存器t0的地址8
- 由于不是位移操作,所以位移量是0
打孔代表1,没打孔代表0
参考资料
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.