计组-4.2 指令的寻址方式
4.2 指令的寻址方式
1.指令寻址(先)
指令寻址:寻找 下一条 将要执行 ==指令== 的 ==指令地址==。
程序总是 **根据PC的内容 **去主存(相应位置)取指令的。
- PC的位数 取决于存储器总字数 N 。按字寻址时,位数 =log2N
- (PC可表示的范围 N)
每一条指令的执行都分为:==“取指令”==,“执行指令”两个阶段。
- ==PC+1是发生在 取指令 之后!执行指令之前!==
顺序寻址:PC(程序计数器) ==+ “1”==(1指的是指令字长)【为定长而非变长的指令字】
- 跳跃寻址:通过转移类指令实现。
2.数据寻址(后)
==数据寻址:寻找 本条指令 的地址码指明的 真实地址==
- (数据寻址既是在找地址,也是在找操作数——找地址是手段,获取操作数是目的。)
数据寻址方式:10种。故通常在指令字段中设置**==寻址特征字段==**来标记是哪种寻址方式。
==指令通用格式:| 操作码 | 寻址特征 | 形式地址A |== (为了简便此处都是用单地址而非多地址的形式)
- (操作码位数看有多少操作。寻址特征位数看有几种寻址方式)
形式地址==A==,有效(真实)地址==EA==(effective address)
(A)表示地址A的数值。(A既可以是寄存器编号,也可以是内存地址)
直接寻址
- | LDA | 直接寻址特征 | A |
- 最直接的。**==操作数的真实地址就是形式地址A==** 。即 ==EA = A==
- 优缺:最简单,指令执行阶段只访存一次。A的位数限制了操作数的寻址范围,且操作数的地址不易更改。
- 访存次数2:取指令1次,执行指令1次。(暂不考虑存结果)
间接寻址
- | OP | 间接寻址特征位 | A | (OP可以放任意指令(LDA、ADD、SUB等))
- ==指令的字段给出的==不是操作数真实地址,而==是真实(有效)地址所在的 主存单元的地址==。 即 ==EA = (A)==
- 优缺:可扩大寻址范围(EA可能存放的单元范围),且便于编制程序(多次间接 )。指令执行阶段要多次访存,慢。
- 访存次数3:取指令1次,执行指令2次。(暂不考虑存结果)
寄存器寻址
| OP | 寻址特征 | Rī |
==指令字段给出的是 操作数所在的寄存器编号==。 即 ==EA = Rī==
优缺:指令执行阶段不用访存,仅需访问寄存器,fast,且地址码位数更少,指令字长短。寄存器贵,数量有限。
访存次数1:取指令1次,执行指令0次。(暂不考虑存结果)
寄存器间接寻址
- ==间接寻址的优化==。 即 ==EA = (Rī)==
- 优缺:相比于间接,减少了访存次数(only 1)。相比于寄存器,多了内存访存。
- 访存次数2:取指令1次。执行指令1次。(暂不考虑存结果)
隐含寻址
- 不直接而是==隐含 操作数的地址==。(eg单地址的指令割术就隐含约定第二个操作数由累加器(ACC)提供)
- 优缺:利于缩短指令字长。需增加存储操作数或隐含地址的硬件。
- 访存次数:如果地址由ACC提供,0次。如果地址在内存中,1次。
立即(数)寻址
==| OP | # | A |==
指令字的地址字段给出的不是操作数的地址,而是操作数本身(也称立即数,以补码形式出现!)
优缺:指令执行阶段不访存,fast。A的位数限制了立即数的范围。
访存次数1:取指令1次。
偏移寻址
0.补充内容
- 以某个地址作为起点,另外一个作为偏移量
- 补码:
- ==6位补码表示范围是:-32~+31(注意是得少一位哦)==
- 补码扩充问题,正数前面添0,负数前面添1(FFF)
- Imm8 – 8位补码
- 标志寄存器:
- ZF:是否为零
- SF:结果的符号位
- OF:有符号数运算是否溢出
- CF:无符号数运算是否产生借位
- sizeof(double)=8 (单位B)
a.相对寻址
==以 当前程序计数器PC所指的地址 作为“起点”==
==EA = (PC) + A== ,==【偏移的是A】==
优点:代码段 在程序内浮动时 不用更改==跳转指令==的地址码。
缺点:偏移量(形式地址A)的位数较短。
(A可正可负,以补码表示)(寻址范围:2^A的位数)
(ACC加法指令的地址码,可以采用“分段”的方式将程序段数据段分开,eg可解决M行的问题==?==)

b.基址寻址
- ==以程序的起始存放地址作为“起点”==
- 有效地址 = 形式地址 A + 基址寄存器BR(base address register)的内容 。 即 ==EA = (BR) + A==,==【偏移的是A】==
- 优缺:扩大寻址范围,==便于程序的数据浮动==,实现多道程序并发运行。
- 缺点:偏移量(形式地址A)的位数较短。
- (BR既可以用专属寄存器,也可用某个通用寄存器)
c.变址寻址
- 有效地址 = 形式地址A + 变址寄存器(IX)的内容。 即 **==EA = (IX) + A==**,==【偏移的是(IX)】==
- 优缺: 扩大寻址范围,且==适合编址循环程序==。
- (IX,index register,可以用专用的,也可以用通用的)
d.对比⭐
相对寻址 VS 基址寻址:
- ==相对寻址用 PC 决定“跳到哪里”(代码跳转),基址寻址用寄存器决定“数据在哪”(内存访问)==
基址寻址 VS 变址寻址:
- 基址寻址
- ==BR 决定“数据在哪一段”(BR是基地址)==
- (面向操作系统,主要用于为多道程序或数据分配存储空间)
- 变址寻址
- ==IX 决定“数据在数组中的哪个位置”(IX是下标)==
- (面向用户,主要用于处理数组问题)
堆栈寻址
堆栈是主存(或寄存器)中一块特定的,按FILO原则管理的存储区。
- ==硬堆栈:寄存器堆栈==(速度快,成本高)
- ==软堆栈:主存中划分出区域==
操作数存放在堆栈中,隐含使用堆栈指针(SP,Stack Pointer)作为操作数地址。

总结
| 寻址方式 | 有效地址 | (指令执行阶段)访存次数(不含取值阶段和存结果) |
|---|---|---|
| 直接寻址 | EA = A | 1 |
| 间接寻址(一次) | EA = (A) | 2 |
| 寄存器寻址 | EA = Ri | 0 |
| 寄存器间接寻址(一次) | EA = (RI) | 1 |
| 立即寻址 | A即是操作数 | 0 |
| 隐含寻址 | 程序指定 | 0 |
| 相对寻址(转移指令) | EA = (PC) + A | 1 |
| 基址寻址(多道程序) | EA = (BR) + A | 1 |
| 变址寻址(循环程序) | EA = (IX) + A | 1 |
| 堆栈寻址 | 入栈/出栈EA的确定方式不同 | 硬堆栈不访存,软堆栈访存1次 |
==补充==:
变址 间址寻址方式:先变址,再间值
指令3B,PC指向240。指令取出后:PC = 243
以低字节地址为字地址:小端存储,从末尾开始存储。
==bgt(大于零转移)==
若bgt指令是无符号数比较:跳转条件(即A-B>0)是 ZF + CF = 0
- ZF一定为0(表示结果不是0)。
- CF也一定为0(表示A-B无进位/错位)
若bgt指令是有符号数比较:跳转条件是 ZF + (SF⊕OF)= 0
ZF一定为0。
要么未发生溢出(7-1=6),SF=OF=0
要么已发生溢出(127 - -1),SF=OF=1
==(SF=0,结果的最高位(即符号位)为正数)==
==(SF=1,结果的最高位(即符号位)为负数)==
0111 1111 (127) + 0000 0001 (1) = 1000 0000 (-128)异或⊕:两个操作数相同则为 0,不同则为 1。
注意内存是无符号数,如果要和形式地址(用补码表示,可能为负数,比如基址然后负偏移时候)加一起时候,要注意转换为正数再相减(加一个负数等于减它的正数嘛)

