CPU寻址方式总

转自新浪微博,有一定的补充和修改

作者: shmilylff

Windows汇编语言程序设计——操作数的寻址方式                                      

==============================
操作数的寻址方式
==============================
    寻址方式就是在汇编语言程序中如何表示操作数的各种方法,其最终的目的是找到所要操作的数据的地址。

    寻址方式一般有如下七种:

1.立即寻址

    立即(Immediate)寻址,就是在指令中使用的操作数是常数,这个常数就包含在指令中。以下几条指令都是立即寻址的例子:
    MOV AL,0
    MOV AX,190
    MOV EAX,-1
    MOV EAX,0FFFFFFFFH

    这些指令码中,都包含了立即数,如0,190,-1,0FFFFFFFFH。


2.寄存器寻址

    寄存器(Register)寻址方式的操作数在CPU内部的寄存器中。使用寄存器寻址,CPU不用访问内存就可以取得或修改操作数。
    MOV BL,80       //目标操作数BL是寄存器寻址
    MOV EAX,EBX     //源操作数EBX和目标操作数EAX都是寄存器寻址


3.直接寻址(CPU寻找内存中的操作数)

    除了立即寻址和寄存器寻址方式外,其他的几种寻址方式的操作数都在内存单元中,寻址方式要说明的是CPU如何确定内存操 作数的地址,然后CPU再对该内存单元中的操作数进行处理。
    直接寻址(Direct)寻址就是指令中直接给出了操作数的地址。指令中使用变量时,就是直接寻址。
    MOV EAX,dVal   

    MOV dVal,EBX

    MOV EAX,[4000H]  //直接给出内存所在地址

    在翻译成机器指令后,变量是用它的地址而不是它的名字来表示的。地址外面加一对方括号,表示取这个地址中的内容。
    00401010 A1 11 40 40 00       MOV EAX,[00404011]
    00401015 89 1D 11 40 40 00    MOV [00404011],EBX
    CPU在执行指令的时候,可以直接从指令码中取出地址,而不必经过计算或其他操作,所以叫做直接寻址。


4.寄存器间接寻址

   采用寄存器间接(Indirect)寻址方式的操作数的地址放在寄存器中。

    MOV ESI,00404011H   //将内存地址保存到寄存器中
    MOV EAX,[ESI]
    注意,MOV EAX,ESI和MOV EAX,[ESI]的区别。
    在8086/8088/80286等16位的CPU中,只有4个寄存器能用做寄存器间接寻址:BX,BP,SI,DI。因此,寄存器间接寻址只能是下列之一: [BX],[BP],[SI],[DI]。而在80386及以后的32位CPU中,下面8个寄存器能用做寄存器间接寻址:EAX,EBX,ECX,EDX,ESI,EDI,EBP, ESP


5.寄存器相对寻址

    寄存器相对寻址方式的操作数,其地址是寄存器和一个立即数相加后得到的结果。寄存器的内容不直接作为操作数的地址,寄存器的 内容再加上一个“相对量”(displacement)后,就得到内存的地址。
    MOV ESI,0040200AH
    MOV EDI,[ESI+4]
    相对量也可以是一个负数:
    MOV EDI,[ESI-4]


6.基址变址寻址

    基址变址寻址方式的操作数,其地址是两个寄存器相加后得到的结果。这里的两个寄存器分别称为基址寄存器(Base Register)和变址 寄存器(Index Register)。
    MOV ESI,0040200AH
    MOV EBX,4
    MOV EDI,[EBX+ESI]

    在8086/8088/80286等16位的CPU中,基址寄存器有两个:BX和BP,变址寄存器也有两个:SI和DI。因此,基址变址寄存器只能是4种组合
之一:[BX+SI],[BX+DI],[BP+SI]和[BP+DI]。而在80386及以后的32位CPU中,基址寄存器有8个:EAX,EBX,ECX,EDX,ESI,EDI,EBP和 ESP,变址寄存器有7个:EAX,EBX,ECX,EDX,ESI,EDI和EBP。ESP只能作为基址寄存器,而不能作为变址寄存器。


7.基址变址相对寻址

     基址变址相对寻址方式的操作数,其地址是两个寄存器以及一个立即数相加后得到的结果。“基址变址相对”的3个元素代表:基址寄存 器(base register)、变址寄存器(index register)和相对量(displacement)。
     MOV ESI,0040200AH
     MOV EBX,4
     MOV EDI,[EBX+ESI+4]
     相对量为0的基址变址相对寻址就是基址变址寻址。


寻址方式小结:

     内存操作数的地址又称为有效地址(EA Effective Address)。立即寻址和寄存器寻址中,操作数是立即数和寄存器,没有有效地址。
    
段超越:
     内存操作数的地址由两个部分指定:段基址和有效地址(又称偏移地址)。寻址方式中确定操作数的有效地址后,还要依靠段寄存器一起来确定操作数的内存地址。
     在没有指定段寄存器的情况下,如果在寻址方式的有效地址中使用了ESP和EBP寄存器,那么使用SS段寄存器。对所有其他情况,使用DS段寄存器。
     例如,下面指令中的内存操作数在SS段中:
     MOV EAX,[EBP+8]
     MOV EBX,[ESP-4]
     例如,下面指令中的内存操作数在DS段中:
     MOV EAX,[EBX+8]
     MOV EBX,[ESI-4]
     MOV EAX,[0040200AH]
     使用段超越前缀可以改变在寻址方式中默认使用的段寄存器,明确地指定操作数位于哪一个段中。
     MOV EAX,CS:[EDI]
     MOV EBX,ES:[ESP-4]
     MOV DS:[EBP],ECX
    
     CS段寄存器只能用来读取数据,因此,只能作为源操作数的段前缀。
     在Windows 32位环境中,FS段中保存的是系统使用的一些信息,如果要访问这个段的内存时,必须明确指出段寄存器为FS。
     在Windows 32位环境中,CS,DS,ES,SS在内存中指向同一个段,其大小为4GB。所以,程序中一般不需要使用段超越前缀
来指定操作数的段寄存器。
发布了12 篇原创文章 · 获赞 39 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/sjq__python_web/article/details/79794579