指令的基本形式为“操作码 目标操作数 源操作数”,其中操作码代表了如何对数据进行操作,目标操作数和源操作数分别代表了数据计算之后的归宿和数据的获取处。操作数本身是个数据,但是数据的性质(这个数据象征的是数据还是地址)要由操作码说了算。
立即数操作数表征着参加操作数据的本身,例如“mov AX 8080H”中8080H代表了立即数,将8080H拷贝至AX寄存器中。
由于立即数操作数表征着被操作数据本身,即操作数并不用从其他地方获取,因此立即数操作数和操作码一起被存放在存储器的代码段。
注意:立即数操作数不可以作为目标操作数!目标操作数必须可以存放操作后的数据,立即数只是个存放在代码段的数据,显然不可以存放操作后的数据。
参加运算的数存放在指令给出的寄存器中,可以是16位或8位。例如“mov AX 8080H”就是要将8080H拷贝至寄存器AX中,但是AX在这里是数据存放目标地址的代名词。
注意:
1. 无论是存储器操作数[8080H]还是寄存器操作数AX,都代表着数据所在地/目的地的地址。存储器操作数/寄存器操作数当作为目标操作数时,表征着数据操作之后存放的地址;存储器操作数/寄存器操作数当作为源操作数时,表征着数据来源的地址;
2. 寄存器操作数可以是8位也可以是16位字长的数据。
参加运算的数存放在指令给出的存储器内存单元中,参与运算的数据长度不定。存储器操作数有个明显的特征:“[存储单元的相对地址]”,括号内是“内存单元相对于所在逻辑段的偏移地址”。我们有时候会遇到以下两种形式的存储器操作数:
1. [立即数操作数]
“mov AX [8080H]”表示“要将数据段偏移地址为8080H的存储单元中的内容拷贝至AX寄存器中”,这里如果我们不使用“段重设”的方式显式的指明,数据的偏移地址指的是“相较于数据段的偏移地址”。
注意:无论是存储器操作数[8080H]还是寄存器操作数AX,都代表着数据所在地/目的地的地址。存储器操作数/寄存器操作数当作为目标操作数时,表征着数据操作之后存放的地址;存储器操作数/寄存器操作数当作为源操作数时,表征着数据来源的地址。
2. [寄存器操作数]
“mov AX [BX]”中“BX中的内容象征着存储单元相对于所在逻辑段的偏移地址”,该指令的含义就是“将内存单元中的数据拷贝至AX寄存器中”。
首先,存储器的内存单元是线性排列的,不同于寄存器操作数固定长度,存储器的存储单元运算的数据没有固定的长度。例如“mov [1000H] 8080H”
1. 立即数并没有字长限制,即立即数可以在最高位前无限的添加0,例如008080H、00008080H等都和8080H数值相同;
2. 存储器的内存单元是线性排列的,那立即数可以在最高位前无限的添加0 数值仍不变,“mov [1000H] 8080H”、 “mov [1000H] 008080H”、 “mov [1000H] 00008080H”都一样,即一条指令出现了以下多种结果:
一个指令三种结果,那这样的指令不可能被执行。那我们只有一种选择:指定字长。在双操作数的指令中有个规定“两个操作数如果都没有字长的限制,那么我们必须显示的指明操作数的字长,而且两个操作数对于字长的限定必须相同“。
那么“mov [1000H] 8080H”应改为“mov [1000H] WORD PTR(8080H)”、“mov WORD PTR([1000H]) 8080H”或者“mov WORD PTR([1000H]) WORD PTR(8080H)”,我们显式的指明两个操作数中任意一个操作数的字长即可。“WORD PTR(限定对象)“和”BYTE PTR(限定对象)”分别可以将数据限定在word和byte长度。
由于立即数和存储器操作数的字长不定,因此对于双操作数均为存储器操作数、操作数一个为存储器操作数一个为立即数的情况,我们必须显式的指定字长,否则系统根本无法确定被操作数据到底占用几个字节。