80X86寻址方式总结

80X86寻址方式总结20080503 星期六 下午 11:48

一:概论

    80x86汇编程序都是分段程序设计结构,每个程序段都有一个开始地址:段基址。在保护模式下段基址要由16位的段选择子得到,这些段选择子存放在六个段寄存器(CSSSDSESFSGS)中:

    代码段总是由 CS 段寄存器来指示;

    堆栈段总是由 SS 段寄存器来指示;

    字符处理指令总是使用 ES 段寄存器作为目标操作数的段寄存器;

    一般的数据段可用 DSESFSGS来指示,但 DS 作为数据段的默认段寄存器,用它来寻址比其它几个段寄存器的效率高,因此最好安排 DS 寻址最常引用的数据段,而 ESFSGS去寻址一些不常用的数据段。

 

    段内偏移地址(某个字节相对段基址的偏移量)也被称为有效地址 EAeffective address),它由以下4个部分组成:

    EA 基址 (变址 * 比例因子) 位移量

    基址、变址、位移量的值可正可负,比例因子只能为正。

 

    1:基址

    32位寻址):

        1):如果基址寄存器是 ESPEBP,则段寄存器为 SS

        2):如果基址寄存器是其它通用寄存器,则段寄存器为 DS

    16位寻址):

        基址寄存器可以是 BX BP

 

    2:变址

    32位寻址):

        变址寄存器可以为除 ESP 之外的32位通用寄存器

    16位寻址):

        变址寄存器可以是 SI DI

    3:比例因子

        一个常数,可取 1248

    4:位移量

        一个8位、16位、32位的常数。

 

二:详解

    默认情况下,存储器寻址使用DS数据段,可以使用段寄存器来显式指出选择的段。

 

 

   1:立即寻址

       对多字节立即数,高字节放在寄存器高位,低字节放在寄存器低位。

       例:

           MOV BL43                ;把十进制数43放入BL

           MOV AX98H            ;把十六进制数98H放入AX

           MOV AL'A'                 ;把字符'A'ASCII码放入AL

           MOV CX'AB'            ;把字符'AB'ASCII码放入CX

 

    2:寄存器寻址

       指令中必须是同长的寄存器

 

    3:直接寻址

       指令中直接提供源操作数的偏移地址,它作为代码的一部分存放在代码段中。

       例:

           MOV BLDS:[00300H]              ;把DS数据段中偏移地址为300H的字节复制到BL

           MOV CXES:[00300H]              ;把ES数据段中偏移地址为300H的字复制到CX

           MOV EAXDwordVar               ;把DS数据段中DwordVar单元复制到EAX

           MOV CLByteVar                      ;把DS数据段中ByteVar单元复制到CL

 

 

    4: 寄存器间接寻址

       操作数的有效地址存放在指令指明的寄存器中,能够用作间接寻址的寄存器有:

       EAX,EBX,ECX,EDX,ESI,EDI --> 使用 DS 作为段寄存器

       ESP,EBP                 --> 使用 SS 作为段寄存器

       例:

           LEA EBX, ARRAY                  ;把数组开始地址送EBX

           MOV AL [EBX]                   ;访问数组的第0个元素,若要访问其它元素,只需增加数组索引EBX的值

 

           MOV AX, [EBP]                    ;把SS段中EBP指向的字单元复制到 AX

           MOV [EBP], AX                    ;把AX的值复制到SS段中EBP指向的单元

           MOV [EDI], AL                     ;把AL的值复制到DS段中EDI指向的单元

           MOV AL, [EDX]                    ;把DS段中EDX指向的字节单元复制到 AL

 

    5:寄存器相对寻址

       有效地址EA等于寄存器R中的内容与位移量X的和,即 EA X [R],该方式适用于数组、表格处理。

       EAX,EBX,ECX,EDX,ESI,EDI     -->    使用 DS 作为段寄存器

       ESP,EBP                                      -->     使用 SS 作为段寄存器

       例:

           MOV AX Table[ESI]                Table中存放表的首地址,ESI存放要访问的表项的索引

           MOV AX [Table + ESI]            (MOV AX [Table + ESI]) == (MOV AX Table[ESI])

 

 

           MOV AX, 100H[ESI]                      ;把DS段中ESI100H的字存储单元的内容复制到 AX

           MOV ARRAY[EDI], AL                   ;把AL的值复制到DS段中ARRAY中的第EDI字节单元中

           MOV LIST[EDI3], AX                 ;把AX的值复制到DS段中EDILIST3的字单元中

           MOV ARRAY[EBX],EAX               ;把EAX的值复制到DS段中ARRAYEBX的双字单元中

 

    6:基址变址寻址

       ESP不能作为变址寄存器。汇编器按如下规则区分基址寄存器和变址寄存器:指令的第二操作数中的第一个寄存器为基址寄存器,第二

 

个寄存器为变址寄存器。比如 MOV EAX, [EDX][ESI](或MOV EAX, [EDXESI])中,EDX 为基址寄存器,ESI 为变址寄存器。该方式适用

 

于数组、表格的处理。

       例:

           MOV AX [EBXESI]                 DS段中地址为EBXESI的存储单元的字数据送AX

           MOV AX [EBPESI]                SS段中地址为EBPESI的存储单元的字数据送AX

           MOV AX ES:[EBXESI]           ES段中地址为EBXESI的存储单元的字数据送AX

 

   7:相对基址变址寻址

       该方式适用于二维数组的寻址。

       EA X [BP] [IR]

       例:

           MOV AX Disp[EBX][EDI]

           MOV AX Disp[EBXEDI]

           MOV AX [DispEBXEDI]

 

    以下三种方式中,任何32位通用寄存器都能用作基址寄存器,除ESP之外的32位通用寄存器均可作为变址寄存器;

    若比例因子为1,指令的第二操作数中的第一个寄存器为基址寄存器,第二个寄存器为变址寄存器。若基址寄存器为EBPESP,则默认的段寄存器是SS;若基址寄存是其它的寄存器,则默认的段寄存器是DS

    若比例因子为248,则与比例因子相乘的那个寄存器是变址寄存器。

 

    8:比例变址寻址方式

       EA X [IR * K]

       和寄存器相对寻址相比增加了比例因子,优点在于:对元素大小为248字节的数组,可在变址寄存器中给出数组元素的下标。

       例:

           MOV EAX ARRAY[ESI*4]           ;将ARRAY数组中第 ESI 个元素送EAX,其中ARRAY数组中元素大小为4

 

    9:基址比例变址寻址

       EA [BR] [IR * K]

       例:

           LEA EBP, ARRAY                         ;把数组开始地址送EBX

           MOV EAX [EBP][ESI*4]           ;将ARRAY数组中第 ESI 个元素送EAX,其中ARRAY数组中元素大小为4

 

   10:相对基址比例变址寻址

       EA X [BR] [IR * K]

       例:

           MOV AL 0040400H[EBX][ESI*2]         

 

           MOV [EAXEDI*215H] DX              DX寄存器的内容复制到数据段的一存储单元,

                                                                                   该存储单元EA = EAXEDI*215H

 

           MOV AL, [EBPESI*2-30H]                    把堆栈中的一字节单元的内容复制到AL中,

                                                                                    该存储单元EA = EBPESI*2-30H

 

你可能感兴趣的:(list,汇编,table,存储,X86)