Post

计算机指令

计算机指令

“计算机指令”到底是什么、结构是怎样的、常见指令有哪些、各种架构的异同等。


一、什么是计算机指令?

一条指令就是告诉 CPU 执行“一步操作”的命令。

这些操作可能包括:

指令作用分类 举例
算术运算 add, sub, mul, div
逻辑运算 and, or, xor, not
数据传输 load, store, mov
跳转控制 jmp, call, ret, beq
系统调用 syscall, int(中断)

这些指令是用机器码(01串)或汇编语言写的,最终是给 CPU 解码执行的。


二、CPU 执行指令的流程

一个 CPU 的基本执行流程叫做 “取-译-执行”(Fetch-Decode-Execute):

  1. 取指(Fetch):从内存中读取一条指令;
  2. 译码(Decode):识别这条指令的意思;
  3. 执行(Execute):执行这个动作,如加法、写寄存器、跳转等;
  4. 写回(Write-back):将结果保存回寄存器或内存。

每条指令就是 CPU 的一块“积木”,拼成一个完整程序。


三、一条指令的结构是什么样?

通常包含几个部分(按字节排列):

字段 功能
操作码(Opcode) 表示是加法、跳转还是其他操作
寄存器编号 指出哪两个寄存器参与操作
立即数 / 偏移量 某些操作需要一个常数,或偏移地址等信息
补充字段 某些架构可能有 SIB 字节、ModR/M 等特殊字段(如 x86)

例子:MIPS 架构中一条加法指令

add $t0, $t1, $t2

意思是 $t0 = $t1 + $t2

机器码表示:

字段 位数
opcode 操作码(加法是 000000) 6
rs($t1)源寄存器 $t1 的编号 5
rt($t2)源寄存器 $t2 的编号 5
rd($t0)结果写入的 $t0 编号寄存器 5
shamt 移位量(对加法来说为0) 5
funct(ADD) 6

总共 32位(即4字节),这是一条“定长指令”。


四、RISC 与 CISC 指令集设计的不同

架构 类型 特点
ARM RISC 简洁、固定长度、寄存器操作为主,适合嵌入式
MIPS RISC 教学用典范,结构清晰,每条指令一件事
x86 CISC 指令复杂,支持很多组合、操作可直接访问内存,变长指令

五、常见指令分类和示例

类型 指令示例 说明
算术 add r1, r2, r3 r1 = r2 + r3
逻辑 and r1, r2, r3 r1 = r2 AND r3
比较 cmp r1, r2 比较两个寄存器的值
赋值 mov r1, r2 把 r2 的值赋给 r1
加载/存储 ldr r1, [r2] / str 从内存读取/写入数据
跳转 jmp label, beq label 跳到其他地方执行指令(控制流)
系统 syscall, int 0x80 操作系统调用

六、不同架构的指令示例对比(加法)

架构 汇编指令 含义
x86 add eax, ebx eax = eax + ebx
MIPS add $t0, $t1, $t2 $t0 = $t1 + $t2
ARM ADD R0, R1, R2 R0 = R1 + R2

偏移量和跳转

1. 偏移量是一种“描述位置”的方式

偏移量的本质是:

“我不告诉你具体去哪,而是告诉你从当前位置出发,往前或往后走多少”

2. 跳转为什么常常用偏移量?

在汇编语言中,跳转(分支)指令需要告诉 CPU —— “下一条该执行哪条指令?”

有两种方式可以告诉 CPU:

类型 例子 描述
绝对地址跳转 j 0x00401020 直接跳到具体地址
相对偏移跳转 beq $t0, $t1, +4 从当前 PC 加上偏移跳过去

大多数“条件跳转(branch)”都采用偏移量,因为它:

  • 编码小巧(只需要表示“跳几条指令”)
  • 可移植(无论程序搬到哪里,偏移相对不变)
  • 支持前跳/后跳(例如循环、if 判断)

3. 所以是否“涉及跳转”就一定有偏移?

不是“所有跳转一定用偏移”,但:

指令类型 是否使用偏移 原因
条件跳转(如 beq ✅ 一般使用偏移 因为它描述“从当前 PC 向前/向后跳几条”
绝对跳转(如 j ❌ 使用的是地址 通常是固定地址跳转,不一定使用偏移
函数跳转(如 jal ✅ 或 ❌ 有些用偏移,有些用地址,取决于目标是否固定
跳寄存器(如 jr $ra 跳到寄存器保存的地址,和偏移无关
This post is licensed under CC BY 4.0 by the author.