ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据寻址(2)

2021-12-07 21:35:13  阅读:414  来源: 互联网

标签:变址 基址 PC 地址 寻址 寄存器 数据


数据寻址(2)

偏移寻址

  1. 基址寻址
  2. 变址寻址
  3. 相对寻址
  • 三种的区别:在于偏移的“起点”不一样
  • 三种的相同点:访存次数——指令执行期间都是1次。

  1. 第一个:运行到第 3 行,就让PC=7,跳跃到7。这里当然没有错误。但是,当我们无法从主存起始值为0的地方开始呢?

  2. 第二个:我们起始位置是100,到了103我们又跳到7?当然不是,我们的本意是要到这个程序的第7行。所以,这个7应该视为从100起的偏移量,即第107行。所以,要改变对它的解读方式

  3. 第三个:运行到第 103 行,此时PC=104 。故第 103 行的3的意思是“让PC在原有基础上+3”,这样PC=107

基址寻址

基址寻址:以程序的起始存放地址作为“起点”

  • 将指令格式中的形式地址A 加上 CPU中基址寄存器BR(Base address Register)的内容,而形成操作数的有效地址
  • EA=(BR)+A。

一个专门的基址寄存器【操作系统中的重定位寄存器】

在指令中指明,要将哪个通用寄存器作为基址寄存器使用

  • 要用几个bit来指明寄存器? 根据通用寄存器总数判断—— 比如一共有8个,那么就2^3=8,故 3bit。
  • 由用户决定哪个寄存器作为基址寄存器时,但其内容仍由操作系统确定,程序员不可以修改BR的内容
  • 在程序执行过程中,基址寄存器的内容不变(作为基地址),形式地址可变(作为偏移量)。

例:执行主存中的一段从100起始的代码

int a=2 ,b=3,c=1,y=0;
void main() {
	y=a*b+c;
}

  • 这个程序,从100开始存放。例如变量a的形式地址为A = 5,但是实际存放地址为 EA = 105,必须使用基址寻址了。

  • 右边表格的每个地址码都加上100,就得到目标结果。即程序运行前,CPU将BR的值修改为该程序的起始地址

  • 所以,程序可以在主存中浮动。

优点:

  • 便于程序“浮动”,可用于编制浮动程序(整个程序在内存里边的浮动)。
  • 扩大寻址范围(基址寄存器的位数大于形式地址A的位数);由于A本来比较短,但是在R中内容比较大,就可以跟着范围变大。
  • 用户不必考虑自己的程序存于主存的哪一空间区域,故方便实现多道程序并发运行,因为主存中可以有多个程序同时存在

变址寻址

  • 有效地址 EA 等于指令字中的形式地址A与变址寄存器 IX 的内容相加之和
  • EA = (IX) + A
  • 其中 IX 可为专用变址寄存器(BR),也可用通用寄存器作为变址寄存器(统称IX)
  • 区别注:变址寄存器是面向用户的,在程序执行过程中,变址寄存器的内容可由用户改变 IX 作为偏移量),形式地址A不变(作为基地址)。程序员自己决定从哪里作为“起点”

例:对某数组求和

采用变址寻址前

for(int i=O; i<10; i++)	sum += a[i];

  • 第 0 行:立即寻址(#),得到 0 并给到 ACC

  • 第 1 ~ 10 行:依次完成10次数组和相加。

  • 第 12 行:存储数据

  • 共12条指令。导致编程麻烦。

  • 如果需要100次数组和相加。岂不是还需要再加上90次?

采用变址寻址后

for(int i=O; i<10; i++)	sum += a[i];

  • 第 0 行:立即寻址(#),得到 0 并赋值给 ACC
  • 第 1 行:立即寻址(#),得到 0 并赋值给 IX
  • 第 2 行:变址寻址,地址码是给出数组的初始地址,
  • 第 3 行:立即寻址(#),得到 1 并给 IX 加上
  • 第 4 行:立即寻址(#),得到 10 ,然后与 IX 内含的数比较大小
  • 第 5 行:直接寻址,操作码是条件跳转,地址码是2。
    • 当上一行的比较结果若符合循环条件,则又跳转,使得 PC = 2
    • 当不符合循环条件,则 PC + 1
  • 第 6 行:存储数据
  • 就这样,通过每一次给变址寄存器 IX ➕ 1 ,使得轻松完成了数组的循环。

变址寻址的作用

数组处理过程中,可设定A为数组的首地址,不断改变变址寄存器IX的内容,便可很容易形成数组中任一数据的地址,特别适合编制循环程序。

基址寻址&变址寻址复合

实际中往往是多个复合使用的:

基址寻址:EA = (BR)+ A

变址寻址:EA = (I X)+ A

先基址寻址后变址寻址: EA = (IX) + ((BR)+ A )

相对寻址

  • 把程序计数器 PC 的内容加上指令格式中的形式地址 A 而形成操作数的有效地址

    • 其中A是相对于PC所指地址的位移量,可正可负,补码表示。
  • EA=(PC)+A

  • 即:以程序计数器器PC所指地址作为“起点”

  • 注意A不是相对于当前指令地址的位移量而是相对于下一条指令的指令的偏移量

例:挪动一段循环代码

比如说,随着代码越写越多,想要在自己写的程序中挪动这一段循环代码到其他位置,就要用到相对寻址。

for(int i=0;i<10;i++)	sum += a[i];

挪动前

  • 此时可以正常运行。
  • 但是如果我们往后挪动呢?

挪动后

  • 观察第 M+3 行:操作码:条件跳转;地址码:2 此处挪动到了M+3后,条件再次跳转到2,必然发生错误。

  • 执行到 M+3 时,PC = M + 4

  • 所以我们修改第 M+3 行:操作码:条件跳转;地址码:-4(补码)

  • EA = ( PC )+ - 4 //就是说改成条件跳转回到 M

    修改后

  • 此时不论你把这段程序放在哪里,都可以正常执行。

  • 另注:ACC加法指令的地址码,是采用分段的方式解决。程序段存放程序,数据段存放数据我们给个段落,专门存放数组a[ ]

优点:

  • 便于程序浮动(一段代码在程序内部的浮动)。
  • 相对寻址广泛应用于转移指令

与基址寻址的区别

BR中也说了程序的浮动,区别:

  • 基址寻址:整段程序在内存中的浮动

  • 相对寻址:一段代码在程序内部的浮动

硬件层面是如何比较 a>b

硬件视角:

  • 通过"cmp指令”比较a和b(如cmp a,b) ,实质上是用 a-b
  • 相减的结果信息会记录在程序状态字寄存器中(PSW)【标志寄存器】
  • 根据PSW的某几个标志位进行条件判断,来决定是否转移
  • 汇编语言中,条件跳转指令有很多种
    • 如 je 2 【jump when equal】 表示当比较结果为 a=b 时跳转到 2 ,就是令PC=2
    • 如 jg 2 【jump when greater】 表示当比较结果为 a>b 时跳转到 2,就是令PC=2
    • 无条件转移指令 jmp 2:不管PSW的各种标志位,就直接令PC=2

标签:变址,基址,PC,地址,寻址,寄存器,数据
来源: https://www.cnblogs.com/tupo/p/15658935.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有