PC_寻址方式

寻址方式

  • 寻找指令或者操作数有效地址的方式,即,确定本条指令的数据地址以及下一条指令的地址的方法
    • 包含指令寻址和数据寻址两类
  • 指令中断地址码字段不代表操作数的真是地址,则称这种地址为形式地址(A)
  • 形式地址结合寻址方式可以计算出操作数在存储器中的真实地址(称为有效地址(EA))
  • (A)表示地址为A的数值
    • A可以是寄存器编号
    • 也可以是内存单元地址
    • 对应的(A)就是寄存器中的数值(或相应内存单元的数值)
    • EA=(A)表示有效地址EA就是A处保存的值
    • (EA)就表示操作数本身

指令寻址

  • 寻找下一条将要执行的指令地址称为指令寻址

    • 顺序寻址

    • 跳跃寻址

      • 如果发生跳跃,跳跃结果是当前指令修改PC值,所以下一条指令依然是通过PC给出
      • 但是PC中的值可能不再是默认+1的结果

数据寻址

  • 寻找本条指令的(操作数)数据地址称为数据寻址

    • 在指令中表示一个操作数的地址

    • 并且如何用这种表示,得到操作数或者如何计算出操作数的地址

      • 将地址码字段进一步划分为寻址特征形式地址

      • O P 操 作 码 寻 址 特 征 形 式 地 址 A \begin{array}{|c|c|c|c|} \hline OP操作码&寻址特征&形式地址A\\ \hline \end{array} OPA

  • 对于按字寻址的机器

    • 程序计数器PC的位数取决于存储器的容量(字数)
    • 指令寄存器的长度取决于指令字长

寻址特征字段

  • 如果机器支持多种寻址方式,那么需要有不同的寻址特征来指定指令采用的是那种寻址方式
  • 计算机采用16位定长指令格式,操作码位数和寻址方式位数固定
    • 已知该机器指令系统中有48条指令
    • 并且支持4中寻址方式:
      • 直接
      • 间接
      • 立即
      • 相对
    • 在单地址指令中,直接寻址方式的可能寻址范围是多少?
    • 分析
      • 由于指令数量 2 5 < 48 < 2 6 2^5<48<2^6 25<48<26
      • 因此需要6bit来区分不同指令(不同操作码)
        • 如果只用5bit或者更少的二进制位不足以表达48中不同编码(至多32条),所以采用6
      • 为了支持不同的寻址方式,区分4种寻址方式需要2位( 2 2 = 4 2^2=4 22=4,2位足够表达4中不同编码)
      • 16-6-2=8bit
      • 因此,剩余8bit留给直接寻址方式,范围宽度为 2 8 = 256 2^{8}=256 28=256
      • 无符号范围 0 ∼ 255 0\sim{255} 0255

隐含寻址

  • 不明显地给出操作数地址
    • 在指令中隐含操作数地址
  • 特点:
    • 缩短指令长度
    • 由于隐地址不需要在指令中显式指出操作数地址,因此可以最大程度简化指令(地址)结构
    • 需要增加存储操作次数或者隐含地址的硬件
    • 这就是为什么隐含寻址的指令中虽然没有操作数地址码,但是速度并不快

立即数寻址🎈

  • 这种类型的指令的地址字段指出的不是操作数地址,而是操作数本身,又称为立即数
  • 特点:
    • 指令在执行阶段不访问主存,指令执行时间最短
      • 甚至不需要通过访问寄存器来获得操作数(地址),因此立即数寻址的速度最快
    • 缺点是位数限制了立即数的范围

直接寻址

  • 指令中的形式地址A是操作数的真是地址EA
    • 即EA=A
  • 特点:
    • 简单(在执行阶段仅需要访问一次主存,不需要专门计算操作数的有效地址)
    • A的位数决定了指令操作数的寻址范围,操作数的地址不易修改

间接寻址

  • 相对于直接寻址而言的
  • 设操作数为 x x x
  • E A = ( A ) EA=(A) EA=(A)
  • x = ( E A ) = ( ( A ) ) x=(EA)=((A)) x=(EA)=((A))
  • 如果是2次间接寻址,那么:
    • EA=((A))
    • x = ( E A ) = ( ( ( A ) ) ) x=(EA)=(((A))) x=(EA)=(((A)))
  • 依次类推
  • 特点
    • 间接寻址可以扩大寻址范围
    • 形式地址A的位数往往比有效地址位数更少
    • 但是自行阶段需要多次访存
      • 每多1次间址,就需要多访存一次(根据存储字的最高位确定访问次数)
      • 这是非常坏的,效率很低

寄存器寻址

  • 指令字中直接给出操作数所在寄存器编号
    • E A = R i EA=R_i EA=Ri( R i R_i Ri表示编号为i的寄存器,可以将 R i R_i Ri理解为地址,而且是可以高速访问的地址)
    • x = ( E A ) = ( R i ) x=(EA)=(R_i) x=(EA)=(Ri), R i R_i Ri寄存器中的内容就是操作数 x x x
  • 特点:
    • 指令在执行阶段不需要访存只访问寄存器
      • 因为寄存器数量少,对应的地址码(寄存器编号)长度较小,使得指令字短,不需要访存
      • 支持向量/矩阵运算
    • 但是,寄存器价格高,寄存器的数量有限

寄存器间接寻址

  • 在寄存器 R i R_i Ri给出的表示操作数本身,而是操作数所在主存单元的地址

    • E A = ( R i ) EA=(R_i) EA=(Ri)

    • x = ( E A ) = ( ( R i ) ) x=(EA)=((R_i)) x=(EA)=((Ri))

  • 特点

    • 相比于一般间接寻址的速度快(第一次访问的地址是寄存器,速度快)
    • 指令执行阶段需要访问主存

相对寻址

  • 将PC中的内容加上指令格式中的形式地址A ,形成操作数的有效地址EA

    • E A = ( P C ) + A EA=(PC)+A EA=(PC)+A
    • A是相对于当前指令地址的位移量
    • 不过,实际问题中,经常会说,取值令时,每取出一个字节,PC自动+1
      • 这时候,PC的值需要做修正
      • 假 设 被 取 出 的 指 令 有 k 个 字 节 : P C ′ = ( P C ) + k 假设被取出的指令有k个字节:PC'=(PC)+k k:PC=(PC)+k
      • 然后再计算相对偏移后的有效地址EA=(PC’)+A=(PC)+k+A
      • 相应的偏移量 A = E A − ( P C ) − k A=EA-(PC)-k A=EA(PC)k
  • 从公式上看,容易理解,A的位数决定了操作数的范围

  • 相对寻址提供的相对地址实质上是:

    • 下一条指令在内存中的首地址基准位置偏移量
    • 因为,寻址阶段位于取值阶段之后
      • 众所周知,取指阶段结束后,PC已经完成了自增,此时的PC内容是下一条(默认情况下)的指令的首地址
      • EA=(PC)+A正是在取指阶段后的寻址阶段执行的,因此,偏移量A是相对于当前正在执行的指令的下一条指令的首地址的偏移量
  • 优点是:

    • 操作数的地址是不固定的
    • 它随着PC的变化而变化,且与指令之间总是相差一个固定值
  • 相对寻址相对于多到程序设计最为重要

    • 多道程序设计中,各个程序段可能需要在内存中浮动
    • 相对寻址特别有利于程序浮动,广泛应用于转移指令🎈
  • 相对寻址指令长度为3B
    • 第一字节为操作码
    • 第二,第三字节为地址码(作为偏移量)
      • 采用补码的形式来表示
    • 数据字存储器中采用低字节为字地址的方式(即,小端方式方式存放数据)
    • 每当cpu从存储器中取出1字节时,自动完成 ( P C ) + 1 → P C (PC)+1\to{PC} (PC)+1PC
    • 如果PC的当前值为240(十进制)
    • 要求转移到290(十进制)
    • 则,转移指令的第2,3个字节的内容为?
    • 分析:
      • 完成取值周期操作时,PC的值自增了3(指令的长度为3字节,所以执行了三次PC+1)
      • 此时PC的内容为240+3=243
      • 为了转移到地址290(即EA=290),根据相对寻址公式EA=(PC)+A
        • A=290-243=47
      • 将47转为二进制(16进制: 47 = 8 ∗ 5 + 7 = 10100 0 2 + 11 1 2 = 10111 1 2 47=8*5+7=101000_2+111_2=101111_2 47=85+7=1010002+1112=1011112)
        • + 47 的 原 码 T ( + 47 ) = 0 , 101111 ; 补 码 C ( + 47 ) = T ( + 47 ) +47的原码T(+47)=0,101111;补码C(+47)=T(+47) +47T(+47)=0,101111;C(+47)=T(+47)
        • 由于47是个正数,所以扩充为2字节后,得到0000 0000 0010 111 1 2 1111_2 11112=002FH
        • 由因为要求用低字节为字地址的方式存放数据,则低字节2FH应该位于指令的地址码字段的第二字节位置,第三字节为00H
    • 又比如,PC的值是240,要求转移到200
      • 那么根据公式EA=(PC)+A
        • A=EA-(PC)=200-(240+3)=-43
        • 即,偏移量为-40(十进制真值)
          • 40 = 4 ∗ 10 + 3 = 101 0 2 × 100 2 + 1 1 2 = 10101 1 2 40=4*10+3=1010_2\times{100}_2+11_2=101011_2 40=410+3=10102×1002+112=1010112
          • T ( − 40 ) = 1 , 10101 1 2 T(-40)=1,101011_2 T(40)=1,1010112
        • 其补码 C ( − 40 ) = 1 , 010101 C(-40)=1,010101 C(40)=1,010101
          • 扩充为2字节(16bit)
          • 1111 1111 1101 0101=FFD5H
          • 同样因为小端方式,随意指令的第二字节是D5H,而第三字节是FFH

基址寻址

  • 将cpu中的基址寄存器BR的内容加上指令格式中的形式地址A形成的操作数有效地址EA

    • E A = ( B R ) + A EA=(BR)+A EA=(BR)+A
    • BR可以采用专用寄存器或者通用寄存器实现
  • 特点

    • 基址寄存器BR是面向操作系统的
      • 内容有操作系统/管理程序确定
        • 采用通用寄存器作为BR时,虽然用户可以决定哪个GPR作为BR,但是内容依然有操作系统决定
      • 主要是用来解决程序逻辑空间存储器物理空间的无关性
      • 程序执行过程中,BR的内容不变(作为基地址)
      • 形式地址可以变(作为偏移量)
    • 优点:
      • 可扩大寻址范围
        • BR的位数大于形式地址A的位数
      • 用户不必考虑自己的程序存于主存的哪个空间区域,有利于多道程序设计
        • 相对寻址也是有利于多道程序设计
        • 可以编制浮动程序,但偏移量(形式地址A)位数较短
        • 因此主要说相对寻址方式对于多道程序设计/浮动程序的设计最为重要
  • 某计算采用大端方式,按字节编址
  • 某指令中的操作数的机器数为1234 FF00H
  • 该操作数采用基址寻址方式
    • 形式地址的补码表示为FF12H
    • 基址寄存器BR的内容(BR)=F000 0000H
    • 该操作数的LSB(最低有效字节)所在内存地址为?
  • 分析:
    • 基址寻址方式有效地址的公式EA=(BR)+A
    • A的补码为FF12H=1,111 1111 0001 0010 2 {0010}_2 00102,最高位为1是负数,则其真值为:
      • 1,000 0000 1110 1101+1=1,000 0000 1110 1110,
      • 将符号位改为-,得到真值的二进制形式:-000 0000 1110 1110
      • 真值的16进制形式-00EEH
      • 带入公式EA=F000 0000H+(-00EEH)=EFFF FFFFH+1H-00EEH=EFFF FF11H+1H=EFFF FF12H
        • 也即是说,操作数所在地址为EFFF FF12H
        • 更具体的说,是第一个被放置的字节位置是EA=EFFF FF12H+0H
      • 由于机器采用大端方式存储数据,而且操作数位数是4*8=32bit=4B
        • 那么操作数的最低有效字节00H所在字节地址为EA+3=EFFF FF15H
          • 注意不是+4,而是+3
          • 因为第1个字节是+0;第2个字节+1,第3字节+2,第4个字节+3
          • 类似于数组从0开始计算下标一样
        • 这里EA表示的是有效地址的简写

变址寻址

  • E A = ( I X ) + A EA=(IX)+A EA=(IX)+A
    • 变址寄存器IX(index Register)
  • 特点:
    • 变址寄存器面向用户
    • 在程序执行过程中,IX的内容可以作为偏移量,由用户改变
      • 偏移量的位数足以表示整个存储空间
    • 形式地址A不变(和基址寻址特点相反)
    • 也可以扩大寻址范围
    • 便于编制循环程序
    • 变址寻址立足用户,主要用户处理数组用提,在变址寻址中,变址寄存器的内容是由用户设定
      • 在程序执行过程中其值可变,指令字中的形式地址A反而不可变
  • 在按字节编址的计算机中,某double类型(double占8字节(sizeof(double)=8,单位是字节),(64bit))数组A的首地址为2000H
  • 现在使用变址寻址方式(循环结构)访问数组A
    • 已知保存数组下标的变址寄存器的初始值为0
    • 为了便于描述,设变址寄存器的值为 ( I X ) (IX) (IX)
    • 每次循环取一个数组元素,其偏移地址(偏移量) O = ( I X ) × s i z e o f ( d o u b l e ) O=(IX)\times{sizeof(double)} O=(IX)×sizeof(double)
    • 取完编址寄存器的内容自动加1,即 ( I X ) + + (IX)++ (IX)++
  • 现在,问,某次循环所取的元素的地址是2100H的情况下,进入该次循环是的编址寄存器的内容?
    • 设所求内容为X
    • O = 8 X O=8X O=8X
    • 2000 H + O = 2100 H 2000H+O=2100H 2000H+O=2100H
      • 8X=100H,为了便于计算,统一化为二进制(或者10进制)计算
      • X = 1 6 2 2 3 = 2 8 2 3 = 2 5 X=\frac{16^2}{2^3}=\frac{2^8}{2^3}=2^5 X=23162=2328=25
    • 所以X=32(十进制)
  • Note:
    • 由于计算机按照字节编址,所以地址值每加1,在内存上就对应(代表下一个字节的)

堆栈寻址

  • 堆栈是存储器(寄存器组)中一块特定的,按照后进先出(LIFO)的原则管理的存储区
  • 该存储区中读写单元的**地址(指针)**是用一个特定的寄存器给出
    • 该寄存器称为堆栈指针
  • 寄存器堆栈又称为硬堆栈
    • 成本高
  • 从主存中划分一段区域来做堆栈称为软堆栈(比较常用)
  • 在采用堆栈结构的计算机系统中,大部分指令表面上都表现为无操作数指令心事
    • 应为操作数地址都隐含使用了SP
    • 通常,在读写堆栈中的一个单元的前后,都便有自动完成对SP内容的增量/减量操作

小结

  •  寻 址 方 式   有 效 地 址   访  存 次 数   隐含寻址   程序指定  0  立即寻址  A  即是操作数  0  直接寻址  E A = A 1  一次间接寻址  E A = ( A ) 2  寄存器寻址  E A = R i 0  寄存器间接一次寻址  E A = ( R i ) 1  相对寻址  E A = ( P C ) + A 1  基址寻址  E A = ( B R ) + A 1  变址寻址  E A = ( I X ) + A 1 \begin{array}{c|c|c} \hline \text { 寻 址 方 式 } & \text { 有 效 地 址 } & \text { 访 } \text { 存 次 数 } \\ \hline \text { 隐含寻址 } & \text { 程序指定 } & 0 \\ \hline \text { 立即寻址 } & \mathrm{A} \text { 即是操作数 } & 0 \\ \hline \text { 直接寻址 } & \mathrm{EA}=\mathrm{A} & 1 \\ \hline \text { 一次间接寻址 } & \mathrm{EA}=(\mathrm{A}) & 2 \\ \hline \text { 寄存器寻址 } & \mathrm{EA}=\mathrm{R}_{i} & 0 \\ \hline \text { 寄存器间接一次寻址 } & \mathrm{EA}=\left(\mathrm{R}_{i}\right) & 1 \\ \hline \text { 相对寻址 } & \mathrm{EA}=(\mathrm{PC})+\mathrm{A} & 1 \\ \hline \text { 基址寻址 } & \mathrm{EA}=(\mathrm{BR})+\mathrm{A} & 1 \\ \hline \text { 变址寻址 } & \mathrm{EA}=(\mathrm{IX})+\mathrm{A} & 1 \\ \hline \end{array}       隐含寻址  立即寻址  直接寻址  一次间接寻址  寄存器寻址  寄存器间接一次寻址  相对寻址  基址寻址  变址寻址       程序指定 A 即是操作数 EA=AEA=(A)EA=RiEA=(Ri)EA=(PC)+AEA=(BR)+AEA=(IX)+A 访     001201111

  • 偏移寻址方式包括

    • 相对寻址
    • 基址寻址
      • 偏移量是形式地址A的内容
      • BR的内容在执行过程中是不变的
    • 变址寻址
      • 偏移量是变址寄存器IX的内容
      • 形式地址A的内容执行过程中不变
  • 依赖于寄存器的寻址方式

    • 包括了偏移寻址方式的三种
    • 还有寄存器寻址和寄存器间接寻址
    • 共有5种设计寄存器的寻址方式
    • 其中有4中可以使用通用寄存器实现,一种是程序计数器实现

  • 设计算机有16个通过寄存器
  • 采用32bit定长指令
  • 操作码OP占8bit
    • 包含了寻址方式位(用于指出计算操作数有效地址的方法)
  • Store指令的源操作数和目的操作数分别用寄存器直接寻址基址寻址
    • E A = R i EA=R_i EA=Ri
    • E A = ( B R ) + A = R i + A EA=(BR)+A=R_i+A EA=(BR)+A=Ri+A
    • (即,有两个显示操作数,指令有2个(操作数)地址码)
  • 两种寻址方式都各需要一个寄存器
    • 它们都可以使用通用寄存器来实现
    • 如果基址寄存器可以选用任意一个通用寄存器,那么由于寻址范围是16,恰为 2 4 2^4 24,所以需要用4bit来区分不同的寄存器(0000$\sim$1111)
    • 那么两个操作数寄存器寻址占用了4+4=8位
    • 而寄存器寻址不需要偏移量(不属于偏移寻址方式)
    • 那么32位指令字长剩余32-8-4-4=16bit可以用来表示偏移量(A的位数16bit)
      • Note:基址寻址的偏移量正是有形式地址A提供
      • 如果是变址寻址,则由IX提供偏移量
    • 如果使用补码来表示偏移量;那么表示范围为?
      • 对于给定的16位,划分最高位1位作为符号位
      • 还有n=15位作为数值位
      • 那么根据补码的知识,可以表示的范围为:
        • − 2 15 ∼ 2 15 − 1 -2^{15}\sim{2^{15}-1} 2152151
        • − 32768 ∼ 32767 -32768\sim{32767} 3276832767

混合/复合寻址

  • 例如,先变址寻址后在间址寻址

    • 假设指令格式为:
      • O P ; M ; I ; D OP;M;I;D OP;M;I;D
      • 其中OP操作码,M表示寻址方式
      • I表示(变址)寄存器IX的编号
      • D为形式地址
    • 那么操作数的有效地址为:
      • E A = ( ( I ) + D ) EA=((I)+D) EA=((I)+D)
      • 其中 ( I ) + D (I)+D (I)+D对于变址寻址而言已经是有效地址
      • 但是对于基址寻址和间址寻址的复合寻址方式, ( I ) + D (I)+D (I)+D还不是有效地址
        • 为了便于描述,借助C语言的取地址概念,那么可以描述为 & E A = ( I ) + D \&EA=(I)+D &EA=(I)+D
      • 再次寻址 ( ( I ) + D ) ((I)+D) ((I)+D)才是有效地址
      • 操作数 x = ( E A ) = ( ( ( I ) + D ) ) x=(EA)=(((I)+D)) x=(EA)=(((I)+D))
posted @   xuchaoxin1375  阅读(33)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示