学习汇编记录Day1——寻址方式

0,复习一下cpu中的寄存器:

32位cpu有4个32位的通用寄存器eax, ebx, ecx, dex和16位的cpu中AX, BX, CX, DX作为区分,同时增加了2个fs, gs段寄存器。

其中32位cpu的通用寄存器,对低16位的存取,不影响高16位的数据。在16位的cpu中,ax, bx, cx, dx不可以作为基址和变址

寄存器来存放存储单元的地址。但在32位cpu中,通用寄存器不仅可以传送数据、暂存数据保存逻辑运算结果,而且还可以

作为指针寄存器,所以32位的通用寄存器更具有通用性。

寄存器功能:

1)数据寄存器

ax: 称为累加器(Accumulator),累加器可用于乘,除,输入/输出等操作,他们的实用频率很高。

bx: 称为基地址寄存器(Base register),它可作为存储器指针来使用。

cx: 称为计数寄存器(Count register),在循环和字符串操作时,要用它来控制循环次数;在位操作时,当移多位时,

        用CL来指明移位的位数。(循环中实用,移位时实用,CX

dx:称为数据寄存器(Data register),在进行乘,除运算时。它可作为默认的操作数参与运算,也可以用于存放I/O的端口地址

2)变址寄存器

si 和 di: 称为变址寄存器(Index register),它们主要用于存放存储单元在段内的偏移量。

                用它们可以实现多种寄存器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。

                变址寄存器不可分割成8位寄存器(ax,bx,cx,dx都可以分为高8位和低8位的如AH+AL)。作为通用寄存器,也可存储

                算术逻辑运算的操作数和运算结果。

                它们可作为一般的存储器指针使用,但在字符串操作指令中,有特定要求。

3)指针寄存器

主要用于存放堆栈内存单元的偏移量,用它们可以实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元

提供方便。

bp:称为基指针寄存器(Base pointer),用它可直接存取堆栈中的数据。

sp:称为堆栈指针寄存器(stack pointer),用它只可访问栈顶。

4)段寄存器(s结尾 segment)

根据内存分段的管理模式而设置的,内存单元的物理地址由段寄存器的值和一个偏移量组合而成的,这样可以用两个较少位数

的值访问一个较大物理空间的内存地址。

cs:代码段寄存器(code segment register)

ds:数据段寄存器(data segment register)

es:附加段寄存器(extra segment register)

ss:堆栈段寄存器(stack segment register)

fs: 附加段寄存器(extra segment register)

gs:附加段寄存器(extra segment register)

5)指令指针寄存器

ip:称为指令指针寄存器(instructional pointer)是存放下次将要执行的指令在代码段的偏移量。

       (在具有预取指令功能的系统中,下次执行的指令通常已被预取到指令队列中。不考虑这种情况)

6)实模式和保护模式:

      是32位cpu的,实模式和16位相同,另外一个模式有一个新的概念叫“选择子(selector)”。

1,操作数的寻址方式

    在指令中,指定操作数或操作数存放位置的方法称为寻址方式。在16位cpu中总共有7个方式:

    立即寻址、寄存器寻址、直接寻址、寄存器间接寻址、

    寄存器相对寻址、基址加变址寻址、相对基址加变址寻址。

    后面用“(x)”表示x的值, 如: (AX)表示寄存器AX的值。

1)立即寻址方式

    概念:操作数作为指令的一部分而直接写在指令中,这种操作数叫做立即数,这种方式叫立即寻址方式。

              在指令中,立即数不能作为指令中的第一操作数,这和“赋值语句的左边不能是常量”规定一致。

ps,原文中写的是立即数不能作为第二操作数,但是都知道mov ah, 80h第二个就是立即数,而且第一操作数是目的,

第二操作数是源,也就是把源赋值给目的,就和c语言常量不能做左值一样,所以这里应该是个错误,遂改为第一操作数

              方法:  mov oprd1, oprd2             注意长度一致,如AH是8位后面的立即数也要是8位,不能是16位。

               例子: mov  ah,    80h                    没有分号,记住高高低低原则

                           add   ax,    1234h

                           mov  ecx,  123456h

                      

2)寄存器寻址方式

    概念:指令所要的操作数,已经存储在某寄存器中,或把目标操作数存入寄存器。把在指令中指出所使用寄存器的

              寻址方式称为寄存器寻址。 源和目的操作数都是寄存器。

              1.源操作数是寄存器寻址方式           add  varw, ax                  mov varb, bh       (w 半字, b, 字节)

              2.目的操作数是寄存器寻址方式       add  ax,  1234h               mov bh, 78h

              3.源和目的操作数都是寄存器寻址    mov ax,  bx                     mov bh,  bl

              因为都在寄存器中,执行过程会减少读/写存储单元的次数,所以具有较快的执行速度。

3)直接寻址方式

    概念:指令所要的操作数存放在内存中,在指令中直接给出该操作数的有效地址,叫做直接寻址方式。

    注意:立即寻址方式和直接寻址方式的书写格式的不同,直接寻址的地址要写在括号“[”,“]”内。在程序中,

               直接地址通常用内   存变量名来表示,如:MOV BX, VARW,其中,VARW是内存字变量。

     这中寻址方式要考虑段寄存器!!!    物理地址 = 段地址x16 + 偏移地址。 那么直接寻址就要计算物理地址,会和

     段寄存器有相关的操作。默认段寄存器是ds, 如果指定是其他的寄存器则需要在第一个操作数加段前缀如

                                        mov es:[1000h], ax

     有代表性又醒目。

    

4)寄存器间接寻址方式

     概念:操作数在存储器中,操作数的有效地址用si, di(变址寄存器), BX(基址寄存器),  BP(基指针寄存器)之一来指定,称为寄存器间接寻址。

     寻址方式的计算方法: PA(物理地址) = 段地址x16 + (si / di / bx / bp)   # “ / ” 或的意思

     若有效地址用si, di, bx之一来指定, 缺省的段寄存器是ds,

     若有效地址用bp来指定,缺省的段寄存器是ss(堆栈段)。

5)寄存器相对寻址方式

   概念:操作数在存储器中,其有效地址是一个基址寄存器(bx, bp)或变址寄存器(si, di)的内容 和 指令中8位/16位偏移量之和。

  若有效地址用si, di, bx之一来指定, 缺省的段寄存器是ds,

  若有效地址用bp来指定,缺省的段寄存器是ss(堆栈段)。

  寻址方式的计算方法:PA = 段地址 x 16 + ( EA(偏移地址) = (bx / bp/ si/ di) +  (8bit / 16bit)偏移量)

  这个图很好理解了, 这种方式算出的是偏移地址,然后要加上段地址x16才是真正的物理地址。

指令中给出的8位/16位偏移量用补码表示。在计算有效地址时,如果偏移量是8位,则进行符号扩展成16位。当所得的有效地址超过0FFFFH,则取其64K的模。

6)基址加变址寻址方式

     概念:操作数在存储器中,其有效地址是一个基址寄存器(bx, bp)和一个变址寄存器(si, di)的内容之和。

     寻址方式的计算方法:PA = 段地址X16 + (EA = (bx / bp) + (si / di))

      在不使用段超越前缀的情况下,规定:如果有效地址中含有BP,则缺省的段寄存器为SS;否则,缺省的段寄存器为DS

7)相对基址加变址寻址方式

      概念:操作数在存储器中,其有效地址是一个基址寄存器(bx, bp)的值,一个变址寄存器(si, di)的值和指令中

                 的8位/16位偏移量之和。

      寻址方式计算方法: EA = (bx / bp) + (si / di) + (8 bit / 16bit) 偏移量

       用D1[i]来访问一维数组D1的第i个元素,它的寻址有一个自由度,用D2[i][j]来访问二维数组D2的第i行、第j列的元素,

       其寻址  有二个自由度。多一个可变的量,其寻址方式的灵活度也就相应提高了。

       相对基址加变址寻址方式有多种等价的书写方式,下面的书写格式都是正确的,并且其寻址含义也是一致的。

                                         MOV AX, [BX+SI+1000H]   MOV AX, 1000H[BX+SI]
                                         MOV AX, 1000H[BX][SI]    MOV AX, 1000H[SI][BX]

       但书写格式BX [1000+SI]和SI[1000H+BX]等是错误的,即所用寄存器不能在“[“,”]”之外,该限制对寄存器相对寻址方式

       的书写也同样起作用。

       指令中给出的8位/16位偏移量用补码表示。在计算有效地址时,如果偏移量是8位,则进行符号扩展成16位。

       当所得的有效地址超过0FFFFH,则取其64K的模。

8)32位cpu比16位cpu多一种寻址方式

     当用32位地址偏移量进行寻址时,内存地址的偏移量可分为三部分:

      一个32位基址寄存器,

      一个可乘1、2、4或8的32位变址寄存器,

      一个8位/32位的偏移常量,并且这三部分还可进行任意组合,省去其中之一或之二。

     

总结: 首先明白这7种寻址方式各自的操作数存在哪里,指令中, 寄存器中,内存中。

           然后记住默认的段,以及较为复杂的几种寻址方式要先算EA, 以及书写规范在“[      ]”内,

          如果有指定的段,则在前面加“:” 如  es:[1000h]。

猜你喜欢

转载自blog.csdn.net/WeiLuckyStrike/article/details/89341274