一、前言
直接寻址、间接寻址、立即寻址,只是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
设计资源 培训 开发板 精华推荐
- 使用STWLC68的基于Qi的无线功率接收器,适用于最高5W的低功率标准(BPP)应用
- 具有 8V 栅极驱动器的 LTC3892MPFE-1 高效率、双相降压型 5V/8.5V 转换器的典型应用电路
- Si3056SSI-EVB,全球语音/数据直接访问安排
- LTC2970,具有外部反馈电阻器的 DC/DC 转换器的应用电路
- ADR3540 微功耗、高精度电压基准的典型应用
- 使用 ROHM Semiconductor 的 BD48L38G-TL 的参考设计
- LT1170CT、5A 背光 CCFL 电源的典型应用
- ADP2139CB-0.8EVALZ,ADP2138 评估板,800 mA,输出电压 0.8 V,3 MHz 降压稳压器
- 采用 FRAM 微控制器实现的水表
- 辐射加固FPGA电源解决方案