汇编代码是由两部分组成:操作码(mov)+操作数,既然有操作数的参与,那么对于操作数必然需要存储。
在计算机中,对于操作数的存取至少有两种方式:寄存器和存储器,那么相对而言就产生了各种寻找操作数的方式,本文一一介绍
1、立即寻址方式
操作数就包含在指令代码中,它作为指令的一部分跟在操作码后放在代码段(CS)中。
这种操作数被称作立即数,立即数可以是8位的也可以是16位的。
如果立即数是16位的就按照“高高低低”的原则存储<主要是针对寄存器,与存储单元的大端和小端没有关系>
指令示例:mov ax,1234H<H代表的是16位>
AH = 12, AL=34
但是汇编指令在代码段中的存储方式需要依据存储器的大小端格式来定。
2、寄存器寻址方式
操作数放在CPU内部的寄存器中,指令指定寄存器的编号。
对于16位的操作数,寄存器可以如下:
数据寄存器(AX/BX/CX/DX)
地址寄存器(DI/SI)
指针寄存器(SP/BP)
对于8位的操作数,可以是第一节的8个8位的寄存器
因为操作数在寄存器中,不需要占有系统总线,访问速度快。
指令示例:mov ax,bx
如果执行前:(AX) = 3064H,(BX)=1234H,指令执行后
(AX)= 1234H
3、直接寻址方式
指令直接包含操作数的有效地址(偏移地址)
操作数的有效地址一般存储在代码段中,操作数放在数据段中,默认的是ds段
所以操作数的地址由DS加上偏移地址得到有效地址,取出有效地址中的数据进行操作。
指令示例:
MOV AX,[1234H]
假设DS = 4567H,内存中(468A4H) = 0001H,那么有效地址 = (4567H)*16+(1234H) = (468A4H)
那么寄存器AX = 0001H
因为默认的是DS寄存器,其实也可以指定前缀寄存器,即所谓的段超越前缀
MOV AX, SS:[1234]H
AX = SS*16+(1234H)
4、寄存器间接寻址方式
操作数在寄存器中,操作数的有效地址在SI\DI\BX(DS), BP(SS)
在这四个寄存器之一种,一般情况下如果有效地址在SI、DI、 BX中,则默认段地址是DS
如果在BP中,则默认是SS
不过和上面一样,指令中也可以指定段超越前缀来取得其他段中的数据
指令示例:
MOV AX,[SI] 引用的段寄存器是DS
MOV AX,ES:[SI],引用的段寄存器是ES
MOV [BP],AX,引用的段寄存器是SS
5、寄存器相对寻址方式
操作数放在存储器中,操作数的有效地址是一个基址寄存器(BX、BP)或者是变址寄存器的(SI 、DI)内容加上指令中给定的8位
或者是16位的位移偏移量之和
其中和上面的一样,引用段地址的时候,BX、SI、DI的段地址寄存器是DS,BP的是SS,不过也可以采用段地址超前缀。
其中给定的8位或者是16位采用补码形式表示。如果偏移量是8位,则需要进行符号扩展到16位
MOV AX,[BX+1234H] ,引用段寄存器是DS,有效物理地址=DS*16+BX+1234H,(AX)=(DS*16+BX+1234H)
MOV [BP+1234H],AX,引用段寄存器是SS
MOV ES:[SI+1234H],AX,引用段寄存器是ES
有时候指令也可以表示如左:MOV AX,1234H[BX]等。
6、基址加变址寻址方式
操作数在存储器中,操作数的有效地址由基址寄存器(BX、BP)的内容与变址寄存器(DI、SI)之一的内容相加
如果有BP则段寄存器是SS,其他的是DS
指令示例:
MOV AX,[BX][DI] 等价于 MOV AX,[BX+DI]
有效地址 = DS*16+BX+DI ,(AX) =(有效地址)
同时也允许段超越前缀
MOV DS:[BP+SI],AX
寻址方式适合于数组操作,利用基址存储数组的首地址,变址存储元素的相对地址
7、相对基址加变址寻址方式
操作数在存储器中,操作数的有效地址由基址寄存器之一的内容+变址寄存器之一的内容+8位或者是16位的偏移量之和。
段寄存器和相关的符号扩展同前面。
如果得到的有效地址超过FFFFH时,取64K的模。