操作数寻址方式一直是汇编语言程序设计的一个重要话题。i386系统提供了丰富的寻址方式,如立即数寻址、直接内存寻址、寄存器寻址、间接寻址、变址寻址。
1.立即数寻址
立即数寻址的操作数就包含在指令中,它是指令码的一部分。值得注意的是,在处理多字节立即数寻址时,高字节的数值存放在高地址存储单元,而低字节的数值存储在低地址存储单元内。在汇编语言程序设计中,通常称之为“小尾顺序”。例如,mov eax,10203040h指令的执行结果如图9-3所示。
图9-3 多字节立即数寻址示例
2.直接内存寻址
直接内存寻址即操作数存储于内存中,指令中包含的是该操作数所在存储单元的地址。注意,这里的地址并不是真正的绝对地址,实际上,只是数据段内的偏移地址。而数据段的基地址则存储于ds寄存器中。例如,mov eax,[1234h]指令的含义是将逻辑地址1234h存储单元内的数据存放到eax中。
3.寄存器寻址
寄存器寻址即操作数存储于寄存器内,指令中包含的是该操作数所在寄存器号。寄存器寻址的速度相对于直接内存寻址快得多,因此,这也是寄存器分配的初衷。例如,mov eax,ebx指令的含义是将ebx内的数据存储到eax中。(www.daowen.com)
4.间接寻址
间接寻址即实际的操作数存储于内存中,而操作数的地址存放在一个32位通用寄存器中。在汇编语言中,间接寻址就是使用方括号括起来的通用寄存器名表示。例如,mov eax,[ebx]。
在实模式下,只能用Si、di、bx、bp作为间接寻址寄存器。其中,bp常用来寻址堆栈段,而其他三个都是寻址数据段的。
在保护模式下,允许使用任意32位通用寄存器作为间接寻址寄存器。不过,间接寻址的范围仅限程序所属的数据段。当寻址超出该区域,则会产生保护故障。因此,在Windows环境下的高级语言中,对野指针、空指针的寻址可能是会导致异常的。然而,在实模式编程中,处理器是不会关注此类异常的。
5.变址寻址
变址寻址即将一个常量的值与一个寄存器的值相加,产生一个有效地址,再根据这个有效地址获取实际数据值。这种寻址方式与高级语言的一维数组类似。这里的常量通常是一个数据块的首地址。而寄存器的值是一个相对于首地址的偏移,也称为“指针寄存器”。例如:
array是数组的基址,ebx中的值是相对于array的偏移。执行完该指令后,eax的值为llh。注意,在实模式下,只能用Sl、di、bx、bp作为指针寄存器,与间接寻址类似,bp是用于堆栈段寻址的。值得注意的是,mov eax,[array+l]指令并不是变址寻址,而是直接内存寻址,应该加以区别。两者的区别在于是否可以在汇编阶段计算得到操作数的地址。变址寻址是不可以计算得到的,而直接内存寻址是可以计算得到的。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。