第3章8086寻址方式和指令系统3.18088/8086的寻址方式3.2指令的机器码表示方法3.38088/8086的指令系统3.18088/8086CPU的寻址方式计算机的指令通常包含操作码和操作数两部分,前者指出操作的性质,后者给出操作的对象。寻找和获得操作数、操作数存放地址或指令转移地址的方法称为寻址方式。8086访问操作数采用多种灵活的寻址方式,使指令系统可以方便地在1M存储空间内寻址。指令有单操作数、双操作数和无操作数之分。如果是双操作数指令,要用逗号将两个操作数分开,逗号右边的操作数称为源操作数,左边的为目的操作数。指令的一般格式:操作码操作数,……,操作数计算机中的指令由操作码字段和操作数段组成。操作码:指计算机所要执行的操作,或称为指出操作类型,是一种助记符。操作数:指在指令执行操作的过程中所需要的操作数。该字段除可以是操作数本身外,也可以是操作数地址或是地址的一部分,还可以是指向操作数地址的指针或其它有关操作数的信息。一、立即寻址方式所提供的操作数直接包含在指令中。它紧跟在操作码的后面,与操作码一起放在代码段区域中,如图所示。例如:MOVCX,2A50H立即寻址方式的指令常用来给寄存器赋初值。立即数不但可以送到寄存器中,还可以送到一个存储单元(8位)中或两个连续的存储单元(16位)中去。在所有的指令中,立即数只能作源操作数,不能作目的操作数。另外要注意,以A~F打头的数字出理在指令中时,前面一定要加一个数字0,以免与其它符号相混淆。如将立即数FF00H送到AX的指令必须写成如下形式:MOVAX,0FF00H二、寄存器寻址方式在这种寻址方式下,操作数包含在寄存器中,由指令指定寄存器的名称。对于16位操作数,寄存器可以是AX、BX、CX、DX,SI、D1、SP和BP等。对于8位操作数,则用寄存器AH、AL、BH、BL、CH、CL、DH和DL。例如:MOVDX,AXMOVCL,AH注意:源操作数的长度必须与目的操作数一致,否则会出错。例如,不能将AH寄存器的内容传送到CX中去,尽管CX寄存器放得下AH的内容,但汇编程序不知道将它放到CH还是CL中。这种寻址方式的优点是:寄存器数量一般在几个到几十个,比存储器单元少很多,因此它的地址码短,从而缩短了指令长度,节省了程序存储空间;另一方面,从寄存器里取数比从存储器里取数的速度快得多,从而提高了指令执行速度。三、直接寻址方式1.直接寻址方式在IBMPC机中,把操作数的偏移地址称为有效地址EA。使用直接寻址方式的指令时,存储单元的有效地址直接由指令给出,在它们的机器码中,有效地址存放在代码段中指令的操作码之后。而该地址单元中的数据总是存放在存储器中,所以必须先求出操作数的物理地址,然后再访问存储器,才能取得操作数。当采用直接寻址指令时,如果指令中没有用前缀指明操作数存放在哪一段,则默认为使用的段寄存器为数据段寄存器DS,操作数的物理地址=16×DS+EA=10H×DS+EA。指令中有效地址上必须加一个方括号,以便与立即数相区别。例如:MOVAX,[2000H]MOVAL,[2000H]2.段超越前缀如果要对代码段、堆栈段或附加段寄存器所指出的存储区进行直接寻址,应在指令中指定段超越前缀。例如,数据若放在附加段中,则应在有效地址前加“ES:”,这里的冒号“:”称为修改属性运算符,计算物理地址时要用ES作基地址,而不再是默认值DS。例如:MOVAX,ES:[500H]该指令的源操作数的物理地址等于16×ES+500H。3.符号地址在汇编语言中还允许用符号地址代替数值地址,实际上就是给存储单元起一个名字,这样,如果要与这些单元打交道,只要使用其名字即可,不必记住具体数值是多少。例如:MOVAX,AREA1光从指令的形式上看,AREAl不仅可代表符号地址,也可以表示它是一个16位的立即数,两者之间究竟如何来区别呢?程序中还必须事先安排说明语句也叫做伪指令来加以说明。例如:AREA1EQU0867HMOVAX,AREA1例如:AREA1DW0867HMOVAX,AREA1(该指令也可写为MOVAX,[AREA1])符号地址也允许段超越,下面两条指令是等价的,即:MOVAX,ES:AREA1MOVAX,ES:[AREA1]源操作数的物理地址=16×ES+AREA1四、寄存器间接寻址指令中给出的寄存器中的值不是操作数本身,而是操作数的有效地址,这种寻址方式称为寄存器间接寻址。寄存器名称外面必须加方括号,以与寄存器寻址方式相区别。这类指令中使用的寄存器有基址寄存器BX、BP及变址寄存器SI、DI。如果指令中指定的寄存器是BX、SI或DI,则默认操作数存放在数据段中,这时要用数据段寄存器DS的内容作为段地址,操作数的物理地址由DS左移4位后与BX、SI或Dl相加形成。例如:MOVBX,[SI]设DS=1000H,SI=2000H,(12000H)=318BH则物理地址=16×DS+SI=10000H+2000H=12000H如果指令中用寄存器BP进行间接寻址,则默认操作数在堆栈段中,操作数的段地址在寄存器SS中,操作数的物理地址=16×SS+BP。指令也可以指定段超越前缀来从默认段以外的段中取得数据。这种寻址方式一般用于访问表格,执行完一条指令后,通过修改SI、DI、BX或BP的内容就可访问到表格的下一数据项的存储单元。五、寄存器相对寻址方式操作数的有效地址是一个基址或变址寄存器的内容与指令中指定的8位或16位位移量之和。这种寻址方式与寄存器间接寻址十分相似,主要区别是前者在有效地址上还要加一个位移量。同样,当指令中使用BX、SI或DI寄存器时,段寄存器使用DS,当指定寄存器是BP时,段寄存器使用SS。例如:MOVBX,COUNT[SI]六、基址变址寻址方式操作数的有效地址是一个基址寄存器(BX或BP)和一个变址寄存器(SI或DI)的内容之和,两个寄存器均由指令指定。若:基址寄存器为BX时,段址寄存器用DS则:物理地址=16×DS十BX十SI或=16×DS+BX十DI若:基址寄存器为BP时,段址寄存器应用SS则:物理地址=16×SS十BP+SI或=16×SS十BP十DI例如:MOVAX,[BX][SI]设:DS=3000H,BX=1200H,SI=0500H,(31700H)=0ABCDH则:物理地址=16×DS十BX十SI=30000H+1200H+0500H=31700H执行结果AX=0ABCDH。指令中的方括号有相加的意思,上述指令也可以写成:MOVAX,[BX+SI]七、相对基址变址寻址方式操作数的有效地址是一个基址寄存器和一个变址寄存器的内容,再加上指令中指定的8位或16位位移量之和。若:基址寄存器为BX时,用DS作段寄存器则:物理地址=l6×DS十BX十SI+8位或16位位移量或=l6×DS十BX十DI+8位或16位位移量若:基址寄存器为BP时,用SS作段寄存器则:物理地址=l6×DS十BP十SI+8位或16位位移量或=l6×DS十BP十DI+8位或16位位移量例如:MOVAX,MASK[BX][SI]设:DS=2000H,BX=1500H,SI=0300H,MASK=0200H,(21A00H)=26BFH则:物理地址=16×DS+BX+SI+MASK=20000H+1500H+0300H+0200H=21A00H执行结果,AX=26BFH。同样,上述指令也可写成:MOVAX,[MASK+BX+SI]MOVAX,200H[BX+SI]MOVAX,MASK[BX+SI]八、其它1.隐含寻址指令中不指明操作数,但有隐含规定的寻址方式,例如指令DAA,它的含义是对寄存器AL中的数据进行十进制数调整,结果仍保留在AL中。2.I/O端口寻址8086有直接端口和间接端口两种寻址方式。在直接端口寻址方式中,端口地址由指令直接提供,它是一个8位立即数。由于一个8位二进制数的最大值为255,所以在这种寻址方式中,能访问的端口号为00~FFH,即256个端口。例如:INAL,63H在间接寻址方式中,被寻址的端口号由寄存器DX提供,这种寻址方式能访问多达64K个I/O端口,端口号为0000~0FFFFH。例如:MOVDX,213HINAL,DX3.一条指令有几种寻址方式上面介绍的各种寻址方式都是针对源操作数的,目的操作数均用寄存器来表示。实际上,目的操作数也可以用除立即寻址方式以外的所有寻址方式指定,许多指令还具有各自的隐含规则,所以一条指令可能包含几种寻址方式。例如:MOV[BX],AL设:BX=3600H,DI=1000H,AL=05H目的操作数的物理地址=16×DS十BX=10000H十3600H=13600H指令执行结果为(13600H)=05H。3-2指令的机器码表示方式一、机器语言指令的编码目的和特点用汇编语言(即主要由指令系统组成的语言)编写的程序称为汇编语言源程序,若直接将它送到计算机,机器并不认识那些构成程序的指令和符号的含义,还必须由汇编程序将源程序翻译成计算机能认识的二进制机器语言指令(机器码)后,才能被计算机识别和执行,得到运算结果。8086指令系统采用变长指令,指令的长度可由l~6字节组成。一字节指令中只包含8位操作码,没有操作数。如清进位位指令CLC的机器码为11111000,可直接从指令编码表中查到。对于大部分指令来说,除了操作码(不一定是8位)外,还包含操作数部分,所以要由几个字节组成。不同的指令,其操作码和寻址方式都是不一样的,故指令的长度也不一样。二、编码格式说明以MOV指令为例MOV传送:寄存器/存储器与寄存器之间交换数据,指令编码格式为3-38088/8086CPU的指令系统3.3.1数据传送指令8086/8088有四类传送指令,分别是:通用传送指令、累加器专用传送指令、地址传送指令和标志传送指令。1.通用传送指令表3-1通用传送指令操作码MOVPUSHPOPPUSHFPOPFXCHG操作功能通用传送入栈出栈标志压栈标志出栈交换1)通用传送指令MOV可实现寄存器之间、寄存器和存储器之间传送数据,还可实现将立即数送至寄存器或存储单元的操作。汇编格式:MOV目的操作数,源操作数执行的操作:(目的操作数)←源操作数功能:将源操作数存入目的操作数的寄存器或存储单元中去。注意:①目的操作数不能是立即寻址方式。②源操作数与目的操作数不能同时为存储器寻址方式,即两个内存单元之间不能直接传送数据。③立即数不能直接送段寄存器,即段寄存器只能通过寄存器或存储单元传送数据。④两个段寄存器之间不允许直接传送数据。⑤不允许给CS、IP、PSW三个寄存器传送数据,即这3个寄存器的值用户无权改变。⑥源操作数和目的操作数必须字长相等。⑦MOV指令不影响标志位。例:DATA是用户定义的一个数据段的段名。则:MOVAX,DATAMOVDS,AX两条指令完成对DS段寄存器的赋值。若写成:MOVDS,DATA则是错误的。如果把CPU内部的寄存器细分为段寄存器和寄存器的话,则MOV指令有九种形式:①从寄存器到寄存器;②从寄存器到段寄存器;③从寄存器到存储器;④从段寄存器到寄存器;⑤从存储器到寄存器;⑥从段寄存器到存储器;⑦从存储器到段寄存器;⑧从立即数到寄存器;⑨从立即数到存储器。MOV指令的九种形式如下图所示。MOV指令的九种形式说明:寄存器寻址有直接、寄存器间接、寄存器相对、基址变址和相对基址变址五种存储器寻址方式。CSDS、SS、ES通用寄存器AX、BX、CX、DX、SI、DI、BP、SP立即数存储器数2)进栈指令PUSH及出栈指令POP堆栈是由若干个连续存储单元组成的“后进先出”或“先进后出”存储区域,它的段地址存于SS寄存器中,它只有一个数据出入口,堆栈指针寄存器SP任何时候都指向当前的栈顶,入栈出栈都必须通过SP来确定。如果有数据PUSH压入或POP弹出,SP必须及时修改,以保证(SP)始终指向当前的栈顶位置。在子程序调用和中断处理过程中,分别需要保存返回地址和断点地址,即将当前CS和IP的值压栈;在进入子程序和中断处理后,还需要保存通用寄存器的值;子程序和中断处理程序将