直接寻址、间接寻址、立即寻址

发布者:TranquilJourney最新更新时间:2020-03-20 来源: eefocus关键字:直接寻址  间接寻址  立即寻址 手机看文章 扫描二维码
随时随地手机看文章

一、前言


直接寻址、间接寻址、立即寻址,只是CPU在通过总线与内存交互时的不同交互方法,而产生的三种概念词!


对于这些寻址方式,很多人没有听说过,但是对于学习汇编的同学来说,非常熟悉,很多书中都有提到过这几种寻址方式,但是没有细说,这里来给大家详细介绍一下这三种寻址方式的不同体现在哪里!


二、直接寻址


直接寻址即直接给出内存单元的物理地址/虚拟地址直接寻址!


详细说一下:


假如有一个内存,且大小是:0x00000000~0xFFFFFFFF


每个物理地址代表一个内存单元(这里抛开虚拟内存管理机制),那么我想要取得0x00000001地址里的数据,首先CPU需要通过地址总线找到该内存单元,然后通过控制总线确定操作方法,在通过数据总线将其数据送回来,便于处理!


那么我们要怎样将地址给CPU呢?


答:


放到CS段地址寄存器中,CS寄存器负责保存段地址,CPU会根据此段地址,去内存中将指令读取到CS:IP寄存器当中,然后执行!


假如我想要将0x00000001地址里的数据取出来,放到AX寄存器当中,那么需要在内存中写好指定代码:


MOVE AX,[DS:0x00000001H]


MOVE AX,[0x00000001H]

(AX内存=DS+0x00000001H)

DS是段寄存器,这里无需多说,详细介绍可以看这篇文章:C语言内存模型详细介绍_堆栈介绍


操作系统会自动帮我们把CS:IR寄存器指向我们的代码段,当CPU将指令取到CS:IP寄存器以后,就会通过CU控制单元译码解析指令转换成对应的电平信号,驱动CPU晶体管工作!


CPU会直接将段地址+0x00000001的物理地址通过北桥,传送给内存芯片,内存芯片会把该地址里的数据取回来传递给CPU,当CPU接受到返回来的数据时,会把该数据写入到AX寄存器,这样一个指令就执行完成了,实际上并不是一个指令,其实CPU要分好几次时钟周期来执行,第一次去将DS寄存器里的段首地址读取出来,第二次加上0x00000001,第三次去内存中取数据,第四次将获取到的数据写入到AX中,即四个个时钟周期来完成一个指令,其中还会用到alu运算单元来进行段地址+偏移地址的运算,所以实际上可能需要多个时钟周期来完成!


CPU是由晶体管来驱动的,每次开关驱动一次都称为一次时钟周期,时间周长不算,一般用赫兹来表示时钟周期的单位!


上面的过程仅一步到位非常之快,因为我们直接给出了实际物理地址!


下面来说说间接寻址


三、间接寻址


间接寻址是建立在直接寻址之上的一种概念,地址不是直接寻址那样直接给出,而是通过某个特定的内存单元得出,第一次是得到某个特定内存单元里的地址数据,第二次在将得出的地址进行DS+偏移地址H的运算直接寻址!


这样说可能有点含糊不清,不过来看一下这段汇编代码,你就应该能明白直接寻址与间接寻址之间的区别了:


MOV esp,0x00000001

MOV AX,[esp]

esp、eax等寄存器均为8086寻址寄存器,用于暂时存放地址的,并且寻址时也是以DS+esp的方式!


其实esp和eax等e开头的寄存器和AX,BX,CX通用寄存器的作用没有区别,只是CPU设计者,设计出这么多寄存器是为了方便区分,某些寄存器做某些事情,这样更加方便于统一和区分,你也可以使用BX来进行间接寻址,只要你在里面写上[],这个括号在汇编里表示寻址括号,如果你把bx用[]括起来,CPU会把BX里的内容当做地址看待!


这样的话,CPU要做的工作可就很多了,首先要将0x00000001地址送入到esp里,在将esp里的地址取出来,然后通过DS+esp在去内存中寻址,在取回来放到AX中!


所以间接寻址说的明白一点,就是通过寄存器得到要寻址的地址,然后在寻址,而非直接给出地址直接寻址!


上面有个疑惑,就是直接寻址的地址是怎么来的?


答:在内存中取出指令存入到IP寄存器时,这个地址就已经存放进去了,在IP寄存器的低位,直接寻址的地址是存放在指令中的,而不需要二次获取!


其如果使用间接寻址,在8085系列的CPU设计出了R0,R1的寄存器,并且如果间接寻址使用@符号表示


mov R0,0x00000001

mov ax,@R0

用于表示间接寻址,不过这种寻址方式更加少见了,因为自8086系列CPU出现以后,[]指令的出现,更加方便于寻址,并且直观性更强,但是还是可以使用上面这种方法寻址的,因为向前兼容(即新的东西兼容老的东西),只是不同架构的CPU编写方法不同,但意思都是一个样!


三、立即寻址


通过上面的了解,立即寻址就非常简单了,即立即数寻址!


立即数即指令的一部分,平常我们所看到的编程语言当中:


int a = 5;

这样我们在栈中保存了一个数据5,但是它是有空间的,在汇编中对它寻址是这样的:


比如a在栈中的偏移地址是0x135h


mov ax,[135h]

CPU会到135h的内存中根据位宽寻址,将值寻回来以后,放入到ax寄存器当中!

立即数不同,立即数是不占任何空间的,它存在于代码段,是指令的一部分:


mov ax,135H

ax内容=135


当这个指令执行完成之后内存被释放掉之后,我们下次想要找到这个内存空间是找不到的!


立即寻址要快于其它寻址,因为它无需进行寻址!

关键字:直接寻址  间接寻址  立即寻址 引用地址:直接寻址、间接寻址、立即寻址

上一篇:寄存器与七种寻址方式
下一篇:Keil C51中code、data、bdata、idata、xdata、pdata的解释

推荐阅读最新更新时间:2024-11-13 11:10

西门子S7-300PLC的寄存器间接寻址问题
在FC1程序中,第4条指令L     W ,后面注释是取指针第1个字内的数据块编号,第9条指令L     D ,后面的注释是取指针内数据区的起始地址。这2条指令格式一样,怎么一个是取地址内的内容(数据块编号),一个是取起始地址? 答:下图是参数类型Pointer的结构: 下面是书中的程序: 参数类型为Pointer的输入参数Start_Addr占6个字节,P##Start_Addr是第1个字节的地址。执行第二条指令后,AR1中是输入参数Start_Addr(指针)的首地址,所以第4条指令装入累加器的是指针第1个字内的数据块编号,第9条指令“L   D ”装入的是指针第2个字节开始的双字,即指针内数据区的起始地址。
[嵌入式]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved