寻址方式

1,简介

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

2、直接寻址

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

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

CS寄存器负责保存段地址,CPU会根据此段地址,去内存中将指令读取到CS:IP寄存器当中,然后执行。假如我想要将0x00000001地址里的数据取出来,放到AX寄存器当中,那么需要在内存中写好指定代码:

MOVE AX,[0x00000001H]

(AX内存=DS段寄存器,+0x00000001H)

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

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

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

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

3、间接寻址

间接寻址是建立在直接寻址之上的一种概念,地址不是直接寻址那样直接给出,而是通过某个特定的内存单元得出,第一次是得到某个特定内存单元里的地址数据,第二次在将得出的地址进行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寄存器的低位,直接寻址的地址是存放在指令中的,而不需要二次获取。

4、立即寻址

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

int a = 5;

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

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

mov ax,[135h]

ax内容=135;
CPU会到135h的内存中根据位宽寻址,将值寻回来以后,放入到ax寄存器当中。立即数不同,立即数是不占任何空间的,它存在于代码段,是指令的一部分。当这个指令执行完成之后内存被释放掉之后,我们下次想要找到这个内存空间是找不到的。立即寻址要快于其它寻址,因为它无需进行寻址。

参考博文:https://blog.csdn.net/bjbz_cxy/article/details/80534371

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值