一、计算机的结构
1.1 现代计算机的结构
1.2 计算机的工作过程
操作码:做了什么
地址码:对谁动手
由的指令不需要地址码
二、指令的基本格式
2.1 本节总览
2.2 指令的定义
- 基本概念:指令(机器指令)是计算机执行操作的最小功能单位,由二进制代码组成。
- 指令系统:一台计算机所有指令的集合称为指令系统(指令集),如x86和ARM架构的指令集互不兼容。
- 执行限制:计算机只能执行自身指令系统中的指令,这是导致软件在不同架构设备(如PC和手机)间无法直接运行的根本原因。
2.3 指令格式
- 组成要素:指令由操作码(OP)和地址码(A)两部分组成,操作码指明”做什么”,地址码指明”对谁操作”。
- 地址码需求:不同操作对地址码数量的需求不同,如停机指令无需地址码,加减运算需要两个操作数地址。
2.4 零地址指令
-
- 无操作数类型:如停机、关中断、空操作等指令,仅需操作码。
- 堆栈计算机:操作数隐含在栈顶和次栈顶,通过后缀表达式实现运算,如A+B转换为AB+的栈操作过程。
- 访存次数:典型情况下需要3次访存(取指令→读操作数→写结果)。
2.5 一地址指令
- 一地址指令
- 单操作数运算:如加1、取反等操作,格式为OP(A1)→A1,需3次访存。
- 隐含寄存器操作:如(ACC)OP(A1)→ACC,其中一个操作数隐含在累加寄存器,仅需2次访存。
- 指针类比:A1类似C语言指针,(A1)表示指针指向的内容。
2.6 二地址指令
2.7 三地址指令
2.8 四地址指令
- 特殊字段:除三个操作数地址外,A4字段直接指定下条指令地址。
- 流程控制:通过修改PC值实现跳转,不同于常规的PC自动+1顺序执行。
- 地址位数影响:地址码位数决定寻址范围,固定指令长度下地址码数量与单个地址码位数成反比。
2.9 指令-按地址码数目分类
2.10 指令 – 按指令长度分类
- 关键术语:
- 指令字长:单条指令总长度(可变)
- 机器字长:CPU整数运算处理位数(固定)
- 存储字长:存储单元位数(通常等于MDR位数)
- 结构类型:
- 定长指令字结构:所有指令长度相同(如半字长/单字长指令)
- 变长指令字结构:指令长度可变,影响取指时间
2.11 指令 – 按操作码长度分类
- 定长操作码:所有指令操作码位数相同,控制器设计简单但指令数量受限(2n条)。
- 可变长操作码:操作码长度可变,提高指令设计灵活性但增加译码复杂度。
- 扩展操作码:定长指令字结构中实现可变操作码的特殊设计方法。
2.12 指令 – 按操作类型分类
- 数据传送类:如LOAD/STORE指令,实现主存与寄存器间数据交换。
- 运算类:包括算术运算(加减乘除)、逻辑运算(与或非)和移位运算。
- 程序控制类:如jump/call/return指令,通过修改PC值改变程序流程。
- 输入输出类:实现CPU与I/O设备间的数据传送(涉及I/O端口概念)。
2.13 本节回顾
- 分类维度:地址码数目(0-4地址)、指令长度(定长/变长)、操作码长度(定长/可变)、操作类型(4大类)。
- 核心关系:指令字长、机器字长、存储字长三者的区别与联系。
- 设计权衡:地址码数量与寻址能力的反比关系,操作码长度与指令灵活性的正比关系。
三、扩展操作码指令格式
3.1 本节总览
- 基本组成:指令由操作码和若干个地址码组成
- 指令字结构分类:
- 定长指令字结构:指令系统中所有指令长度相等
- 变长指令字结构:指令系统中各种指令长度不等
- 操作码格式分类:
- 定长操作码:所有指令的操作码长度相同
- 可变长操作码:各指令的操作码长度可变
- 扩展操作码特点:采用定长指令字结构+可变长操作码,不同地址数的指令使用不同长度的操作码
3.2 扩展操作码
扩展操作码举例
- 设计原则:
- 指令字长固定为16位
- 每个地址码占4位
- 三地址指令设计:
- 地址码占12位(3×4位)
- 操作码剩余4位,最多表示24=16种状态
- 实际保留15条(0000-1110),保留1111用于扩展
- 二地址指令设计:
- 前4位固定为1111
- 中间4位操作码(0000-1110),保留1111用于扩展
- 最多15条二地址指令
- 一地址指令设计:
- 前8位固定为11111111
- 中间4位操作码(0000-1110),保留1111用于扩展
- 最多15条一地址指令
- 零地址指令设计:
- 前12位固定为111111111111
- 后4位操作码(0000-1111)
- 最多16条零地址指令
设计扩展操作码指令格式时,需要注意的两点
- 关键设计规则:
- 不允许短码是长码的前缀(类似哈夫曼编码的前缀规则)
- 各指令的操作码不能重复
- 优化策略:
- 高频指令分配更短的操作码
- 可减少指令译码时间,简化电路设计
3.3 扩展操作码举例
- 题目要求:设计满足15条三地址、12条二地址、62条一地址、32条零地址指令的系统
- 解题步骤:
- 三地址指令:4位操作码(0000-1110),保留1111用于扩展
- 二地址指令:前4位1111+中间4位(0000-1011),保留1100-1111用于扩展
- 一地址指令:前8位11111111+中间6位(000000-111101),表示62种状态
- 零地址指令:前12位111111111111+后4位(0000-1111),表示32种状态
- 状态计算公式:若上一层留出m种状态,下一层可扩展m×2n种状态(n为地址码位数)
- 三地址→二地址:1×16=16种(实际用12种)
- 二地址→一地址:4×16=64种(实际用62种)
- 一地址→零地址:2×16=32种(全部使用)
3.4 指令操作码
- 扩展操作码特点:
- 优点:指令字长有限时仍能保持丰富指令种类
- 缺点:增加指令译码难度,使控制器设计复杂化
- 定长操作码特点:
- 优点:简化硬件设计,提高译码速度
- 缺点:指令数量增加时会限制操作数地址位数
- 最大指令数:2n条(n位操作码)
- 核心要点:掌握扩展操作码的设计方法和状态计算规则
3.5 总结
前提先明确
假设:
- 指令总长度固定为 16 位(就像一条短信固定 16 个字符);
- 每个 “地址码”(表示操作数存在哪里)需要 4 位(因为 4 位二进制能表示 0~15,刚好对应 16 个不同的存储位置,够用)。
第一步:三地址指令(需要 3 个地址码)
三地址指令格式:[操作码][地址1][地址2][地址3]
- 3 个地址码共占:3×4=12 位;
- 剩下的操作码只能占:16-12=4 位(操作码长度 = 4 位)。
4 位操作码能表示多少种指令?4 位二进制有 16 种组合(0000~1111)。
但我们只用前 15 种(0000~1110)表示 15 条三地址指令,留最后 1 种(1111)不用。
→ 为什么留 1111?因为要用它当 “扩展信号”:告诉 CPU“这不是三地址指令的操作码,后面还有更长的操作码”。
第二步:二地址指令(需要 2 个地址码)
二地址指令格式:[操作码][地址1][地址2]
- 2 个地址码共占:2×4=8 位;
- 剩下的操作码能占:16-8=8 位(操作码长度 = 8 位)。
这 8 位操作码怎么来的?
前 4 位必须是刚才留的 “扩展信号 1111”(告诉 CPU:“我是更长的操作码,不是三地址指令”),后 4 位才是新的编码。
所以 8 位操作码范围是:1111 0000 ~ 1111 1111(前 4 位固定 1111,后 4 位变化)。
同样,我们只用其中 15 种(1111 0000 ~ 1111 1110)表示 15 条二地址指令,再留最后 1 种(1111 1111)当新的扩展信号。
第三步:一地址指令(需要 1 个地址码)
一地址指令格式:[操作码][地址1]
- 1 个地址码占 4 位;
- 操作码能占:16-4=12 位(操作码长度 = 12 位)。
这 12 位操作码的前 8 位,必须是上一步留的扩展信号 1111 1111(告诉 CPU:“我是更长的操作码,不是二地址指令”),后 4 位是新编码。
所以 12 位操作码范围是:11111111 0000 ~ 11111111 1111。
还是只用 15 种(11111111 0000 ~ 11111111 1110)表示 15 条一地址指令,留最后 1 种(11111111 1111)当新的扩展信号。
第四步:零地址指令(不需要地址码)
零地址指令格式:[操作码]
(没有地址码)
- 操作码能占全部 16 位(操作码长度 = 16 位)。
这 16 位操作码的前 12 位,必须是上一步留的扩展信号 11111111 1111(告诉 CPU:“我是最长的操作码,没有地址”),后 4 位是新编码。
所以 16 位操作码范围是:111111111111 0000 ~ 111111111111 1111。
这次不用留扩展信号了(已经是最长的),所以 16 种编码全用,表示 16 条零地址指令。
总结:操作码怎么 “变长” 的?
指令类型 | 地址码数量 | 地址码总位数 | 操作码长度 | 操作码范围(举例) | 指令数量 |
---|---|---|---|---|---|
三地址 | 3 | 12 | 4 位 | 0000 ~ 1110 | 15 条 |
二地址 | 2 | 8 | 8 位 | 1111 0000 ~ 1111 1110 | 15 条 |
一地址 | 1 | 4 | 12 位 | 11111111 0000 ~ … 1110 | 15 条 |
零地址 | 0 | 0 | 16 位 | 111111111111 0000 ~ … 1111 | 16 条 |
核心逻辑:
- 地址码用得越少,操作码就能 “抢” 更多位数(因为总长度固定);
- 每次都留 1 个操作码编码当 “扩展标志”,告诉 CPU “后面还有更长的操作码”,避免混淆(比如三地址的操作码里没有 1111,所以 CPU 看到 1111 就知道要往后看更多位)。
这样一来,16 位的指令字长就能放下 15+15+15+16=61 条指令,比固定 4 位操作码(只能 16 条)多得多~ 明白了吗?
3.6 补充
第一步:定位指令类型(看地址码数量)
表格列是 操作码 + 地址码(A₁、A₂、A₃),行的差异是 地址码数量减少,操作码占的位变多(因为指令总长度固定)。
第二步:逐行解析(核心是「1111」的作用)
第 1 行
- 格式:
0000-1110 | A₁ | A₂ | A₃
- 含义:
- 操作码占 前 4 位(0000~1110,共 15 种),留
1111
不用; - 后面跟 3 个地址码(A₁、A₂、A₃) → 三地址指令。
- 操作码占 前 4 位(0000~1110,共 15 种),留
第 2 行
- 格式:
1111 XXXX | 0000-1011 | A₁ | A₂
(第一列的1111
是关键!) - 含义:
- 前 4 位是
1111
(这是扩展标记,告诉 CPU:“我不是 4 位操作码,后面还有操作码!”); - 操作码扩展为 8 位(前 4 位
1111
+ 中间 4 位XXXX
); - 地址码只剩 2 个(A₁、A₂)(原来的 A₃被操作码占用了)→ 二地址指令。
- 前 4 位是
第 3 行
- 格式:
1111 11XX | 1100-1110 1111 | 0000-1111 0000-1101 | A₁
- 含义:
- 前 6 位是
1111 11
(继续扩展标记,因为上次留了1111
,现在更 “长” 了); - 操作码扩展为 12 位(前 6 位 + 后面 6 位);
- 地址码只剩 1 个(A₁)(A₂、A₃被操作码占用)→ 一地址指令。
- 前 6 位是
第 4 行
- 格式:
1111 1111 111X | 1111 | 1110-1111 | 0000-1111
- 含义:
- 前 12 位是
1111 1111 111
(终极扩展标记); - 操作码占满 16 位(整个指令都是操作码);
- 地址码 0 个(A₁、A₂、A₃全被操作码占用)→ 零地址指令。
- 前 12 位是
核心规律:「1111」是钥匙
- 每出现一次
1111
(或更长的 1 序列),就代表 操作码变长,地址码少一个; - 逻辑像 “俄罗斯套娃”:短操作码(4 位)是外层,长操作码(8、12、16 位)是内层,靠
1111
解锁内层。
本网站原创文章版权归何大锤的狂飙日记所有。发布者:何大锤,转转请注明出处:何大锤的博客