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

一、前言

    直接寻址、间接寻址、立即寻址,只是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

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

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


猜你喜欢

转载自blog.csdn.net/bjbz_cxy/article/details/80534371
今日推荐