8086处理器的内存寻址方式主要分三种
最简单的寻址方式就是寄存器寻址。也就是指程序执行时,操作的数就存放在寄存器当中,可以直接从寄存器中取得。例如:
mov ax ,bx
mov cx ,0xf000
inc cx
这些都涉及了寄存器寻址。
第二条指令中的目的操作数是寄存器寻址方式,因此该操作数也是寄存器寻址
立即寻址,有些书上也叫立即数寻址。也就是操作数是一个立即数,例如:
mov bx ,0xf000
mov dx ,label_a
第一条的目的操作数是寄存器寻址,源操作数则是直接给出的数值,参与运算的时候不需要通过其他方式进行查找。
第二条指令中的目的操作数是寄存器寻址方式,源操作数是一个标号,在汇编语言中,标号是数值的等价形式,代表了它所在位置的汇编地址,在编译过程中,它会被编译器转换为一个立即数。
寄存器寻址和立即数寻址都是速度较快的寻址方式,但也有局限性,寄存器寻址需要数据在寄存器间不断的倒腾,有时候寄存器数量还不够用。立即数寻址则不太灵活,有的时候并不知道这个数据是多少;有的时候用立即数也会使程序很难改动。
内存寻址是一类寻址方式,具体可分为四种或五种(不同的书这个分类不太一样)方式。
直接寻址的操作数是一个偏移地址,直接给出了偏移的具体数值。例如:
mov [0x5000] ,ax
mov word [0x2000] ,0x5000
xor byte [es:label_a] ,0x05
这三条指令中的目的操作数都是采用的直接寻址方式。
凡是表示地址用来寻址的操作数,都要用’[]'括起来,如果第一条指令写成mov 0x5000 ,ax
,这很明显是错的,立即数怎么能作为传送的目标呢。
第三条指令目的操作数使用的段超越和标号,但由于标号在编译阶段就换成了数值,所以还是直接寻址方式。
寄存器间接寻址方式是偏移地址存放在寄存器中,然后把寄存器用’[]'括起来进行内存访问,这样的寄存器也称为间址寄存器。例如:
mov bx ,0xb800
mov byte [bx] ,0x31
寄存器间接寻址在用法上有一些限制,并不是所有的寄存器都可以像例子中的bx
那样使用,像ax
cx
等就不行。只有一些特定的通用寄存器才能够作为间址存器使用,如下表:
间址寄存器和约定访问的逻辑段
间址寄存器 | 默认访问的逻辑段 | 寻址位数 |
---|---|---|
BP | 堆栈段 | 16位 |
BX、SI、DI | 数据段 | 16位 |
EBP、ESP | 堆栈段 | 32位 |
EAX、EBX、ECX、EDX、ESI、EDI | 数据段 | 32位 |
默认访问的逻辑段就是在使用寄存器间接寻址时,如果不使用段超越的方式直接指明访问的逻辑段,程序会按照上表所示的段进行访问。
基址寻址是使用基址寄存器进行内存访问的寻址方式,在8086微处理器中就有一个基址寄存器 bx
和基址指针寄存器 bp
。
基址寻址方式所采用的方式,还有一些限定条件和寄存器间接寻址差不多,有些书上还将偏移加了进去,即如下指令所示:
mov bx ,0xb800
mov byte [bx+0x01] ,0x30
mov byte [bx+0x01] ,0x31
还有就是限定条件上将一些变址寄存器从上表中剔除,也就变成了下表所示:
基址寄存器和约定访问的逻辑段
基址寄存器 | 默认访问的逻辑段 | 寻址位数 |
---|---|---|
BP | 堆栈段 | 16位 |
BX | 数据段 | 16位 |
EBP、ESP | 堆栈段 | 32位 |
EAX、EBX、ECX、EDX、ESI、EDI | 数据段 | 32位 |
表格《 基址寄存器和约定访问的逻辑段》较之表格《 间址寄存器和约定访问的逻辑段》少了SI
和DI
两个变址寄存器。
这种寻址方法将偏移加进去,使用上就显得更方便了,可以将基址寄存器指定数据表中访问的起始点,进而改变偏移即可。
变址寻址类似与基址寻址,不同的是这种寻址方式使用的是变址寄存器(有些书上也称索引寄存器),例如:
mov [si] ,dx
mov ax ,[di]
mov byte [si+0x01] ,0x31
在32位机上也有一些通用寄存器作为变址寄存器使用,
使用的时候可加比例因子,例如:
mov ah ,[4*EBX+3]
比例因子只能是:1、2、4、8中的一个数
具体寄存器如下表:
变址寄存器和约定访问的逻辑段
变址寄存器 | 默认访问的逻辑段 | 寻址位数 |
---|---|---|
SI、DI | 数据段 | 16位 |
EBP | 堆栈段 | 32位 |
EAX、EBX、ECX、EDX、ESI、EDI | 数据段 | 32位 |
无比例因子的变址寻址只能用SI
和DI
,当然在8086上也只有这两个可以做变址寄存器了。
基址加变址寻址更像是基址寻址和变址寻址的组合了,不过这种寻址方式也能带来一些便利,处理一些更加复杂的任务,例如对二维数组的访问。
5种不同的内存寻址方式有各自的特点和应用场景:直接寻址更适用于访问单个内存操作数;寄存器间接寻址、基址寻址和变址寻址更适用于访问连续排列规律的多个内存操作数;基址加变址寻址则更多用于访问二位数组和数据结构体。实际编程应根据程序中的数据结构特点合适选择相应的寻址方式