(1)操作数包含在指令中。在取指令的同时,操作数也随着取出,这种操作数被称为立即数。
(2)操作数包含在CPU的某个内部寄存器中。由于该寄存器在CPU内部,因此取操作数也较简单。
(3)操作数在内存储器中。由于内存储器在CPU的外部,因此在寻找此种操作数时需要执行一个总线周期,首先找到该操作数在内存中存放的地址,再从该地 址中取出操作数。在80x86微机系统中,任何内存单元的地址由段基址和偏移地址(又称偏移量)组成,段基址由段寄存器提供,而偏移地址则由以下四个基本 部分组合而成:
基址寄存器;
间址寄存器(或称变址寄存器);
比例因子;
位移量。
这四个部分被称为偏移地址四元素。一般将这四种元素按某种计算方法组合形成的偏移地址称为有效地址EA(Effective Address)。它们的组合方式和计算方法为:
EA基址+(间址×比例因子)+位移量
采用16位寻址时,位移量是8位或16位,用BX和BP作基址寄存器,SI和DI作间址寄存器,比例因子为1。
采用32位寻址时,可使用8位和32位的位移量,32位的通用寄存器都可以作基址寄存器或间址寄存器(ESP不用于间址),并且可采用2、4或8几种不同的比例因子。
这四种元素可优化组合出9种存储器寻址方式,加上立即数寻址和寄存器寻址,共有11种寻址方式,下面详细讨论。为了说明数据的寻址方式,以汇编语言中的MOV指令为例。指令的格式为:MOV目标操作数,源操作数;其功能是将源操作数传送到目标操作数。
1.立即数寻址(Immediate Addressing)
指令中所需操作数存放在指令中,放在操作码(OP)后。操作数可以是8位、16位或32位。由于在指令执行过程中,立即数作为指令的一部分直接从指令预取单元中取出,不需要再访问存储器,因此这种寻址方式执行速度快。
例如,在MOV AX,1020H指令中,1020H为立即数,该指令的功能是将立即数1020H传送到AX中,执行示意图见。
立即数寻址时,只允许源操作数为立即数,目标操作数必须是寄存器或存储器,其作用是给寄存器或存储单元赋值。
2.寄存器寻址(Register Addressing)
指令中所需操作数在CPU的某个寄存器中,由于存取此类操作数在CPU内部进行,所以执行速度快。
例如:MOV AL, BL
执行情况见。
3.直接寻址(Direct Addressing)
操作数一般存放在存储器的数据段中,而操作数的有效地址EA(16位或32位)由指令给出。在直接寻址中,为取得操作数必须先求出存放操作数的存储单元的物理地址。如果操作数在数据段中,则求得:物理地址(DS)×16+EA,其操作过程。
例如:MOV AX, DS:[2000H]
设(DS)3000H,物理地址(3000H)×16+2000H32000H,即将存储器32000H和32001H两个单元的内容送到AX寄存器。注意,低地址的存储单元32000H的内容送到AX的低字节AL中。
直接寻址允许用符号地址来代替数值地址,例如:MOV AX,[DATA],此时变量DATA为存放操作数的存储单元的符号地址。上述指令还可写为:MOV AX, DATA,两者是等效的。直接寻址适用于处理单个变量。
4.寄存器间接寻址(Register Indirect Addressing)
操作数在存储器中,操作数的有效地址EA存放在某个寄存器(Reg)中,其寻址方式。寄存器的使用在16位寻址和32位寻址时不一样。
1)16位寻址
偏移地址放在SI、DI、BX、BP中。
如果指令中指定的寄存器是BX、SI、DI,则操作数在数据段中,操作数的物理地址为:
物理地址(DS)×16+(BX)
……(SI)
……(DI)
如果指令中指定的寄存器是BP,则操作数在堆栈段中,段基址在SS中,操作数的物理地址为:
物理地址(SS)×16+(BP)
2)32位寻址
8个32位通用寄存器均可作寄存器间接寻址用。除ESP和EBP默认段寄存器为SS外,其余6个通用寄存器均默认段寄存器为DS。