第三章 IBM PC 机的指令系统和寻址方式
计算机完成的任何功能,都是通过执行一系列指令来实现的,因而每种计算机都有一组指令集提供给用户使用,这组指令集合就称为计算机的指令系统。
什么是寻址方式?计算机指令中,为了取得操作数的地址(目的取得操作数的内容)而进行的寻找该操作数物理地址的方式。
计算机的大部分计算都需要数据参加,这些参加某一指令计算的数据就叫该指令的操作数。汇编语言的指令格式如下:
操作码 操作数1,操作数2,操作数3,…,操作数n
操作码:指示计算机要进行的某种指令操作,在汇编语言中,操作指令采用助记符的形式来表示操作指令,即操作码。
操作数:不同的操作码需要不同的操作数数量,大部分操作码需要的操作数不超过3个,也有的指令不需要操作数。操作数的类型也是多种多样,它可以是常数、可以是存储单元、可以是地址、甚至可以某中指令操作码等等。汇编语言中很多操作码需带有两个操作数,就把前面的操作数称为目的操作数、后面的操作数称为源操作数。
IBM PC机的寻址方式
一、与数据有关的寻址方式
(一)立即寻址方式操作数直接存放在指令中,紧跟在操作码之后,它作为指令的一部分存放代码段中,这种操作数叫立即数(相当高级语言的常量)。立即数可以是8位或16位数,若是16位数则高位字节存放在高地址中,低位字节存放在低地址中。这种方式如下图所示:

操作码直接对立即数进行操作。
立即寻址方式用来表示常数,它主要用于给寄存器赋初值,注意:只能用于源操作数字段,不能用于目的操作数字段。
例1 MOV AL,5
则指令执行后,(AL)=05H,8位运算例2 MOV AX,3064H
则指令执行后,(AX)=3064H,16位运算数据的执行过程可用下图示意:

OP表示该指令的操作码部分。
(二)寄存器寻址
操作数在寄存器,指令指定寄存器号。对于16位操作数,寄存器可以是AX、BX、CX、DX、SI、DI、SP相BP等;对于8位操作数,寄存器可以是AL、AH、BL、BH、CL、CH、DL和DH。这种寻址方式由于操作数就在寄存器中,不需要访问存储器来取得操作数,因而可以取得较高的运算速度。这种方式如下图所示:

例3 MOV AX,BX
如指令执行前(AX)=3064H,(BX)=1234H,则指令执行后,(AX)=1234H,(BX)保持不变。
除了上述两种寻址方法外,以下介绍的寻址方式的操作数都在除代码段以外的存储区中,通过不同的方式求得操作数地址,从而取得操作数。
(三)直接寻址在IBM PC机中将操作数的偏移地址称为有效地址EA。在直接寻址方式中有效地址EA就在指令中,它存放在代码段中指令操作码之后,但操作数一般存放在数据段中,所以必须先求出操作数的物理地址,然后再访问存储器才能取得操作数,如下图所示。

如操作数在数据段中,则物理地址=16d×(DS)十EA。1BMPC机中允许数据存放在数据段以外的其他段中,此时应在指令中指定段跨越前缀,在计算物理地址时应使用指定的段寄存器。
例4 AX,[2000H]
(DS)=3000H,则执行情况如下图所示。执行结果为;(Ax)=3050H

在汇编语言指令中,可以用符号地址代替数值地址,如:
MOV AX,VALUE
此时VAIUE为存放操作数单元的符号地址。如写成
MOV AX,[VALUE]
也是可以的.两者是等效的。如果VALUE在附加段中,则应该指定段跨越前缀如下;
MOV AX,ES:VALUE
或 MOV AX,ES:[VALUE]
直接寻址方式适用于处理单个变量,例如需要处理某个存放在存储器里的变量,可用直接寻址方式,将该变量先取到一个寄存器中,然后在做处理。
IBM PC机规定:除在双操作数中,除立即数外,必须有一个操作数使用寄存器方式。这也是一个常量常常送到寄存器去的原因。
(四)寄存器间接址操作数的有效地址在基址寄存器BX、BP或变垃寄存器SI、DI中,而操作数则在存储器中,如下图所示。

如果指令中指定的寄存器是BX、SI、DI,则操作数在数据段(DS)中,所以用DS寄存器的内容作为段地址,即操作数的物理地址为:
物理地址=16d×(DS)十(BX)
或 物理地址;16 d×(DS)十(SI)
或 物理地址=16d×(DS)十(DI)
如指令中指定SP寄存器,则操作数在堆栈段(SS)中,段地址在SS中,所以操作数的物理地址为:
物理地址=16d×(SS)十(SP)
例5 MOV AX,[BX]
如果 (DS)=2000H,(BX)=1000H
则物理地址=16d×(DS)十(BX) = 20000H+1000H = 21000H
执行结果见下图所示:

执行结果为:(AX)=50A0H
指令中也可指定段跨越前缀来取得其他段中的数据。如;
MOV AX,ES:[BX]
这种寻址方式可以用于表格处理,执行完一条指令后,只需要修改寄存器内容就可取出表格中的下一项。
(五)寄存器相对寻址方式
操作数的有效地址是一个基址或变址寄存器的内容和指令中指定的8位或16位位移量之和。即

同样,除有段跨越前缀者外,对于寄存器为BX、SI、DI的情况,段寄存器用DS,而寄存器BP则使用SS段寄存器的内容作为段地址。这种寻址方式示于下图。

其物理地址计算如下:

例6 MOV AX,COUNT[SI] (也可表示为MOv AX,[COUKT十SI;]
其中,COUNT 为16位位移量的符号地址。
如果(DS)=3000H,(SI)=2000H COUNT=3000H
则物理地址 = 30000十2000十3000 =35000H
指令执行情况如下图所示,执行结果是(AX)=1234H

这种寻址方式同样可用于表格处理,表格的首地址可设置为COUNT,利用修改基址或变址寄存器的内容来取得表格中的数值。
直接变址寻址方式也可以使用段跨越前缀。
(六)基址变址寻址方式操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和。两个寄存器均由指令指定。如果基址寄存器为BX,段寄存器使用DS;如基址寄存器为BP时,段寄存器则用SS。因此,物理地址为:

这种寻址方式见下图:

例7 MOV AX,[BX][Dl]
(或写为,MoV AX,[DX十D1]
如 (DS)=2100H (BX)=0158H (D1)=l0A5H
则 EA=0158H十10A5H=11FDH
物理地址=2l000H十11FDH =221FDH
指令执行情况如下图所示。执行结果(AX)=1234H。

(七)相对基址变址寻址方式
操作数的有效地址是一个基址寄存器和一个变址寄存器的内容和8位或16位位移量之和。同样,当基址寄存器为BX时,使用DS段寄存器;而当基址寄存器为BP时,则使用SS为段寄存器。因此物理地址为:

这种寻址方式参见下图:

刨8 MOV AX,MASK[BX][SI]
(也可以写成 M0V AX,MASK[DX十SI]
或 MoV AX.[MASK十BX十SI] )
如 (DS)=3000H,(BX)=2000H、(SI)=l000H,MASK=0250H,
则 物理地址=16d×(DS)十(BX)十(SI)十MASK
=30000十2000十1000十0250
=33250H
指令执行情况如下图所示。执行结果(AX)=1234H。

这种寻址方式为堆栈处理提供了方便。一般(BP)可指向栈顶,从栈顶到数组的首地址可用位移量表示,变址寄存器可用来访问数组中的某个元索。
二、与转移地址有关的寻址方式这种寻址方式用来确定转移指令及CALL指令的转向地址。
(一)段内直接寻址
转向的有效地址是当前IP寄存器的内容和指令中指定的8位或16位位移量之和。如下图:

这种方式的转向有效地址用相对于当前IP值的位移量来表示,所以它是一种相对寻址方式。指令中的位移量是转向的有效地址与当前IP值之差,所以当这一程序段在内存中的不同区域运行时,这种寻址方式的转移指令本身不会发生变化,这是符合程序的再定位要求的。这种寻址方式用于条件转移和无条件转移指令,但是,当它用于条件转移时,位移量只允许8位。无条件转移指令在位移量为8位时,叫短跳转。
指令的汇编语言格式为:
JMP NEAR PTR PROGIA
JMP SHORT QUEST
其中,PROGIA和QUEST均为转向的符号地址,在机器指令中,用位移量来表示。在汇编指令中,如果位移量为16位,则在符号地址前加操作符NEAR PTR。如果位移量为8位,则在符号地址前加操作符SHORT。
(二)段内间接寻址
转向有效地址是一个寄存器或是存储单元的内容,这个寄存器或存储单元的内容可以用数据寻址方式中除立即数以外的任何一种寻址方式取得,所得到的转向的有效地址用来取代IP寄存器的内容。此种寻址方式如下图所示。

注意:这种寻址方式以及以下的两种段间寻址方式都不能用于条件转移指令。也就是说,条件转移指令只能使用段内直接寻址的8位位移量,而JMP和CALL指令则可以使用任何跳转方式。
段内间接寻址转移指令的汇编格式可以表示为
JMP BX
JMP WORD PTR[BP+TABLE]
等。其中WORD PTR又称为操作符(伪),用以指出其后的寻址方式所取得的转向地址是一个字的有效地址,也就是说它是一种段内转移。
以上两种寻址方式均为段内转移,所以直接把求得的转移的有效地址送到IP寄存器就可以了。如果需要计算转移的物理地址,则计算公式应该是:
物理地址=l 6d×(CS)十EA
其中EA即为上述转移的有效地址。
下面举例说明在段内间接寻址方式的转移指令中,转移的有效地址的计算方法
假设,(DS)=2000H,(BX)=1256H,(SI)=528FH,
位移量=20A1H,(232F7H)=3280H,(264E5H)=2450H。
例9 JMP BX
则执行该指令后(IP)=1256H
例10 JMP TABLE[BX]
则执行该指令后(IP)=(16d×(D)十 (BX)十位移量)
=(20000十1256十20A1)
=(232F7H)
=3280H
例11 JMP [BX][SI]
则指令执行后(IP)=(16d×(DS)十(BX)十(SI))
=(20000十l256十528F)
=(264E5H)
=2450H
(三)段间直接转移
指令中直接提供了转向段地址和偏移地址,所以只要用指令中指定的偏移地址取代IP寄存器的内容,用指令中指定的段地址取代CS寄存器的内容就完成了从一个段到另一个段的转移操作,如下图所示。

这种指令的汇编语言格式可表示为:
JMP FAR PTR NEXTROUTINT
其中,NEXTROUTINT为转向的符号地址,PAR FAR 则是表示段间转移的操作符。
(四)段间间接转移
用存储器中的二个相继字的内容来取代IP和CS寄存器中的原始内容以达到段间转移约目的。这里存储单元的地址是由指令指定除立即数方式和寄存器方式以外的任何一种数据寻址方式取得,如下图所示。

这种指令的汇编语言格式可表示为:
JMP DWORD PTR[INTERS+BX]
其中,[INTERS+BX]说明数据寻址方式为直接变址寻址方式,DWORD PTR为双字操作符,说明转向地址需要取双字为段间转移指令。
IBM PC机的机器语言指令概况
我们用汇编语言编写的汇编语言程序输入计算机后,由机器提供的“汇编程序”将它翻译成由机器指令组成的机器语言程序,才能由计算机识别并执行。因此汇编语言程序是由汇编程序翻译成可执行的机器语言程序曲,一般说来,这一过程不必由人来干预。我们这里只介绍一下基本原理,以便在必要时也可完成类似的工作。
机器语言指令由操作码和地址码两部分组成,下面分别加以说明。
一、操作码的机器语言
IBM PC机的机器语言指令是多字节指令,一条指令可以由1—7个字节组成。指令的操作码(用OP表示)采用二进制代码表示本指令所执行的操作,在IBMPC机中,它通常用指令的第一个字节表示,有时由于用8位还不够,因此在指令的第二个字节中还可能占有3位操作码,除此以外的其他字节则用来表示地址码。
在多数操作码中,常使用某些位来指示某些信息。例如

其中W位用来指示本指令是对字(w=1)还是对字节(w=0)进行操作。
d值在双操作数指令中才有效。IBMPC机规定双操作数指令的两个操作数必须有一个操作数放在寄存器中,d位指定寄存器用于目的操作数(d=1)还是源操作数(d=0)。
另外,当使用立即方式寻址时,操作码中用S位表示符号扩展;

如立即数为8位,但要求扩展成16位数(高位字节按低位字节的最高有效位作符号扩展)时、S位为l。
因此当指令作字节操作时,SW=00,当指令有16位立即数且作字操作时SW=01;而当指令有8位立即数但需要经符号扩展成l6位立即数作字操作时,则SW=11。
出于IBM PC的指令格式很多,这里我们只作一些基本清况介绍,必要时读者可通过查子二、寻址方式的机器语言表示
IBMPC机用一个寻址方式字节表示操作数的寻址方式,它通常是机器指令的第2个字节。寻址方式字节可表示如下:

其中reg表示寄存器方式,在双操作效指令的情况下规定必须有一个操作致在寄存器中,该寄存器由reg字段指定。它与操作码字节中的w位相结合确定的寄存器如下表所示。

mod字段与r/m(register/memory)字段结合在一起确定另一个操作数的寻址方式。
(1)mod=11为寄存器方式,由r/m的内容确定选用哪个寄存器,具体值由下表来确定。

其他三种寻址方式则为操作数在存储器中时的寻址方式,由表3.2表示,下面分别加以说明:
(2)mod=00为无位移量字节的存储器寻址方式。其中当r/m=110时指定为直接寻址方式,此时寻址方式字节之后跟有16位位移量D16,用来指出操作数的有效地址。
(3)mod=01为带有一个位移量字节的存储器寻址方式,因此指令中应有

其中D8为8位位移量,是带符号数,当用来计算有效地址时,可自动将符号扩展到16位。
(4)mod=10为带有二个位移量字节的存储器寻址方式,因此指令中有

其中D16为16位位移量,它也是带符号数。
上表中每项下的段寄存器是指无段跨越前缀的情况下所使用的隐含的段寄存器。如果指令中指定段跨越前缀,则在机器语言中使用放在指令之前的一个字节来表示,如下所示:

其中001及110均为段前缀标志,SEG则指定四个段寄存器中的一个,如下表所示

IBM PC机规定下列三种情况下不允许使用段跨越前缀;
1.访问堆栈的指令(如PUSH和CALL等)使用SP作为偏移地址指针,只能使用SS作为段奇存器。
2.串处理指令规定源寄存器使用SI,源串在DS段中,目的寄存器使用DI,目的串必须在ES段中。这里如果要用段跨越前缀则只能用于源而不能用于目的,也就是说,SI可以更换段寄存器,而DI则只能使用ES作为段寄存器,不允许用段跨越前缀更换。
3.指令只能存放在代码段中。
根据以上说明,我们对IDM PC机的机器指令情况已经有了一般的了解,下面在以加法指令为例,对机器指令作一些具体的分析。
(三)加法的机器指令举例加法指令的汇编语言格式为:
ADD DST,SRC
其中SRC表示源操作数地址,DST表示目的操作数地址。
(DST)( (DST) + (SRC)
根据不同的寻址方式,加法指令可以有三种格式:
1,ADD mem/reg1,mem/reg2
其中mem/reg1表示目的操作数地址,mem/res2表示源操作数地址,它们都可以指定一个寄存器或一个存储单元的内容作为操作数。这些操作数可以是8位的或16位的,它们可同时指定两个寄存器,但不能同时指定两个存储单元,因此它的工作方式可以是以下:
a) 寄存器与寄存器的内容相加,结果存入寄存器中。
b) 寄存器与存储单元的内容相加,结果存入存储单元中。
c) 存储单元与寄存器的内容相加,结果存入寄存器中。
这种寻址方式的机器语言为;

其中000000为操作码。w=0为字节运算;w=1为字运算。d=0时,由mod、r/m决定目的mem/reg1,reg决定源mem/reg2;d=1时,由mod、r/m决定源mem/reg2,reg决定目的mem/reg1,虚线框中的位移量根据寻址方式确定其有无。
2,ADD mem/reg,data
把存储在代码段中的立即数与指定的寄存器或存储单元的内容相加,结果存放于寄存器或存储单元中。指令的机器语言为:

3,ADD ac,data
把存储在代码段中的立即数与AL(W=0时)或AX(W=1时)中的内容相加,结果送回AL或AX中。指令的机器语言为:

(以下内容自己复习)
第三节 IBM PC机的指令系统
IBMPC机的指令系统可以分为以下6组:
数据传送指令 串处理指令算术指令 控制转移指令逻辑指令 处理机控制指令下面分别加以说明。
一、数据传输指令
数据传送指令负责把数据、地址或立即数传送到寄存器或存储单元中。它可以分为以下四种,分别说明如下:
(一)通用数据传送指令
MOV(Move) 传送
PUSH(Push onto the stack) 进栈
POP(Pop from the stack) 出栈
XCHG(Exchange) 交换
1、MOV(Move) 传送指令
格式为;MOV DST,SRC
执行操作:(DST) ( (SRC)
其中DST表示目的操作数,SRC表示源操作数。以下相同。
Mov指令的机器语言可以有7种格式
(1) MOV mem/reg1,mem/reg2

当然,双操作数指令不允许两个操作数都使用存储器,因而两个操作数中必须有一个是寄存器。这种方式不允许指定段寄存器。
(2) MOV reg,data

其中reg字段指定寄存器。当然,这种方式也不允许指定段寄存器。
(3) MOV ac,mem

其中ac为累加器,D给出存储单元的偏移地址。
(4) MOV mem,ac

(5) MOV segreg,mem/reg (注意,对段寄存器赋初值)

其中reg指定段寄存器,但不允许使用CS寄存器。此外,这条指令执行完后不响应中断,要事下一条指令执行完后才可能响应中断(有关中断处理问题,将在第八章中说明)。
(6) MOV mem/reg,segreg (注意,是段寄存器)

(7) MOV mem/reg,data

这种方式的目的操作数只用存储器寻址方式而不用寄存器方式。
总结:
以上七种方式说明MOV指令可以在CPU内或CPU和存储器之间传送字或字节,它传送的信息可以从寄存器到寄存器,立即数到寄存器,立即数到存储单元,从存储单元到寄存器,从寄存器到存储单元,从寄存器或存储单元到除CS外的段寄存器(注意立即数不能直接送段寄存器),从段寄存器到寄存器或存储单元。
但是注意
MOV指令中的源操作数绝对不能是立即数和代码段CS寄存器;
MOV指令中绝对不允许在两个存储单元之间直接传送数据;
MOV指令中绝对不允许在两个段寄存器之间直接传送数据;
MOV指令不会影响标志位
例:MOV AX,DATA_SEG
MOV DS,AX
注意:段寄存器(段地址)必须通过寄存器如AX寄存器进行立即数的初始化。
例,MOV AL,‘E’
把立即数(字符E的ASC码)送到AL寄存器。
例,MOV BX,OFFSET TABLE
将TABLE的偏移地址(而不是内容)送到BX寄存器中。其中OFFSET为属性操作符,表示的是将其后的符号地址的值(不是内容)作为操作数。
例 MOV AX,Y[BP][SI]
把地址为16d×(SS)十(BP)十(SI)十位移量Y的存储单元的内容送给AX寄存器
2.PUSH进栈指令格式为 PUSH SRC
执行操作,(SP) <- (SP) - 2
((SP)十1,(SP)) <- (SRC)
3.POP出栈指令格式为 POP DST
执行操作,(DST) <- ((SP)十1,(SP))
(SP) <-〔SP〕十2
这是两条堆栈的进栈和出栈指令。堆栈是以“后进先出”方式工作的一个存储区,它必须存在于堆栈段中,因而其段地址存放于SS寄存器中。它只有一个出入口,所以只有一个堆栈指针寄存器SP,SP的内容在任何时刻都是指向当前的栈顶,所以PUSH和PoP指令都必须根据当前SP的内容来确定进栈或出栈的存储单元,而且必须及时修改指针,以保证(SP)指向当前的栈顶。
堆栈的存取必须以字为单位,(IBM PC中不允许字节堆栈),所以PUSH和POP指令只能作字操作。
它们可以使用初立即数以外的其他寻址方式。
指令也可以指定段寄存器作为操作数,注意POP绝对不能使用代码段(CS)寄存器。
这两条指令不影响标志位。
例 PUSH AX
指令执行情况如下图所示。

例 POP AX
指令执行情况如下图所示。

堆栈在计算机工作中起着重要的作用,如果在程序中要用到某些寄存器,但是它的内容在将来工作中还有用,这时就可以利用堆栈把它们保存下来,然后到必要时恢复其原始内容。例如:

4.XCHG交换指令
格式为 XCHO OPRl,OPR2
执行操作,(OPRl) 〈一一〉 (OPR2)
其中OPR表示操作数。该指令的两个操作数中必须有一个在寄存器中,因此,它可以是寄存器之间;寄存器和存储器之间交换信息,注意不能使用段寄存器。指令允许字和字节操作,且不会影响标志位。
例 XCHG BX,[BP+SI]
如指令执行前:
(BX)=6F30H,(BP)=0200H,(SI)=0046H,(SS)=2F00H,(2F246H)=4l54H
OPR2的物理地址=2F000十0200十0046=2F246
则指令执行后:
(BX)=4154H (2F246H)=6F30H
(二)累加器专用传送指令
IN (input) 输入
OUT (output) 输出
XLAT(Translate) 换码这组指令只限于使用累加器AX和AL传送信息。
1.IN 输入指令

2、OUT 输出指令

注意:
所有的I/O端口与CPU之间的通信都由IN和OUT指令来完成。其中IN完成从I/O到CPU的信息传送,而OUT完成从CPU到I/O的信息传送。
CPU只和累加器(AX或AL)进行接收或发送信息,外部最多可以有64K个端口,端口号为0000H – FFFFH。
长格式:对于前256个端口,可以在指令中直接指定,这就是常格式的端口(PORT)。
短格式:当端口号大于等于256时,则必须先将端口号置于DX寄存器中,然后再利用IN或OUT进行信息的传递。
注意,在利用IN/OUT进行信息传递时,所有的端口号(或DX的内容)均为地址,而传送的均为端口号的内容。
输入、输出指令不影响标志位。
例 IN AX,28H
MOV DATA_WORD,AX
这两条指令把地口28的内容经过AX传送到存储单元DATA_WORD中。
例 MOV DX,3FCH
IN AX,DX
从端口03FCH送一个字到AX寄存器中。
例 OUT 5,AL
从AL寄存器输出一个字节到端口5
3.XLAT换码指令格式为; XLAT OPR
或 XLAT
执行的操作,(AL) 〈一 ((BX)十(AL))
功能:将一种代码转换为另一种代码。
在使用这条指令之前,应该先建立一个字节表格,表格的首地址提前存入BX寄存器,需要转换的代码应该是相对于表格首地址的位移量也提前存放在AL寄存器中,表格的内容则是需要转换的代码,该指令执行后就可在AL中得到转换后的代码。
该指令可以使用XLAT或XLAT OPR两种格式中的任一种,使用XLAT OPR时,OPR为表格的首地址(一般为符号地址),但在这里的OPR只是为提高程序的可读性而设置的,指令执行时只使用预先已存入BX中的表格首地址,而并不用汇编格式中指定的值。该指令不影后标志位。
例 如(BX) = 0040H,(AL)=0FH,(Ds)=F000H
所建立的表格如下图所示。

指令 XLAT
把 F0000H+0040H+0FH的内容送AL,所以指令执行后:(AL) = 2CH
即指令把AL中的代码0FH转换为2CH。
必须注意,由于AL为8位二进制位,所以表格的最大长度不能超过256。
如果我们想把十进制数转换为ASC码,如何进行转换呢?
(三)地址传送指令
LEA 有效地址送寄存器
LDS 指针送寄存器和DS
LES 指针送寄存器和ES
这一组指令完成把地址送到指定寄存器的功能。
1.LEA 有效地址送寄存器
格式,LEA REG,SRC
执行过程,(REG)<- SRC
完成功能,指令将有效地址送到指定的寄存器中。
2.LDS 指针送寄存器和DS
格式,LDS REG,SRC
执行的操作:(REG)〈一(SRC)
(DS)〈- (SRC十2)
把源操作数指定的4个相继字节送到由指令指定的寄存器及DS寄存器中。该指令通常用来指定SI寄存器。
3.LES 指针送寄存器和ES
格式,LES REG,SRC
执行的操作:(REG)〈一(SRC)
(ES)〈- (SRC十2)
把源操作数指定的4个相继字节送到由指令指定的寄存器及ES寄存器中。该指令通常用来指定DI寄存器。
注意:以上三条指令,不能指定段寄存器,指令操作不影响标志位本组指令把变量的偏移地址(LEA)或段地址和偏移地址(LDS和LES)送给寄存器,以提供访问变量的工具。
例,LEA BX,[BX十SI十0F62H]
如指令执行前 (BX)=0400H,(SI)=003CH
则指令执行后 (BX)=0400十003C十0F62=139EH
必须注意,在这里BX寄存器得到的是偏移地址而不是该存储单元的内容。
例,LDS SI,[10H]
如指令执行前 (DS)=C000H,(C0010H)=0180H,(C0012H)=2000H
则指令执行后 (S1)=0180H,(DS)=2000H
例 LES DI,[BX]
如指令执行前 (DS)=B000H,(BX)=080AH,(0B080AH)=05AEH,(0B080CH)=4000H
则指令执行后 (D1)=05AEH,(ES)=4000H
(四) 标志位寄存器传送指令
LAHF 标志寄存器的低字节送AH
SAHF AH送标志寄存器的低字节
PUSHF 标志进栈
POPF 标志出栈
1.LAHF 标志送AH指令格式为,LAHF
执行的操作,(AH)〈- (PSW寄存器的低字节)
2.SAHF AH送标志寄存器指令格式为,SAHF
执行的操作:(PSW的低字节)一〉(AH)
3.PUSHF 标志进栈指令格式为; PUSHF
执行的操作,(SP) 〈- (SP)-2
((SP)+1,(SP))〈- (PSW)
4.POPF 标志出栈格式为:POPF
执行过程为,(PSW) 〈-- ((SP)十1,(SP))
(SP) 〈一 (SP)十2
这组指令中的LAHF和PUSHF不影响标志位。SAHF相POPF则由装入的值来确定标志位的值。
二、算术指令
IBMPC机的算术运算指令包括二进制运算及十进制运算指令。算术指令用来执行算术运算,它们中有双操作数指令,也有单操作数指令。如前所述,双操作数指令的两个操作数中除源操作数为立即数的情况外,必须有一个操作数在寄存器中。单操作数指令不允许使用立即数方式。算术指令的寻址方式,均遵循这二越剧。
(一)加法指令
ADD 加法
ADC 带进位加法
INC 加1
1.ADD 加法指令格式,ADD DST,SRC
执行的操作;(DST)〈一 (SRC)十(DST)
2.ADC 带进位加法指令格式,ADC DST,SRC
执行的操作:(DST) 〈— (SRC)十(DST)十CF (CF为进位位的值)。
3.INC 加1指令
格式 INC OPR
执行的操作:(OPR)〈— (OPR)十1
以上三条指令都可以做字或字节运算,而且除INC指令不影响CF标志位外,它们都影响条件标志位。什么是条件标志位?
条件标志(或条件码)中最主要的是CF、ZF、SF、OF四位,分别表示进位、结果为零、符号和溢出的情况。其中ZF、SF位的设置比较简单,在第二章中已经说明,这里不再赘述,在这里将进一步分析CF和OF位的设置情况。
执行加法指令时,CF位是根据最高有效位是否有向高位的进位设置的。有进位时CF=1,无进位时CF=0。OF位则根据操作数的符号及其变化情况来设置;若两个操作数的符号相同,而结果的符号与之相反时,OF=1;否则OF=0。溢出位OF既然是根据数的符号及其变化来设置的,当然它是用来表示带符号数的溢出的,从其设置条件来看,结论也是明显的。
那么进位位CF的意义是什么呢?在第一章说明补码运算规则的过程中,我们曾经提到在补码加、减法中。从最高有效位向高位的进位说明模运算中的进位自动丢失的现象,对结果并没有影响。那么。为什么还要保存CF位呢?
CF位可以用来表示无符号数的溢出。由于无符号数的最高有效位只是数字意义,而无符号怠义,所以从该位产生的进位应该是结果的实际进位值,但是在有限数位的范围内就说明了结果的溢出情况,另一方面,它所保存的进位值有时是有用的。例如,双字长数运算时,可以利用进位值把低位字的进位计入高位字中等。这可以根据不同情况在程序中加以处理。
我们已经知道8位二进制数可以表示十进制数的范围是;无符号数为0一255,带符号数为一128一十127。16位二进制数可以表示十进制效的范围是:无符号数为0一65535,带符号数-32768一十32767。下面我们以8位数为例分析
(1)带符号数和无符号数都不溢出

(2)带符号数不溢出和无符号数溢出

(3)带符号数溢出和无符号数不溢出

(4)带符号数和无符号数都溢出

上面的4个例子清楚地说明了:OF位可以用来表示带符号数的溢出,CF位可以用来表示无符号数的溢出。应该注意,如果(2),(4)中的进位值以28=256为其权值考虑在内时(即考虑进位是有效数据位,对无符号数而言),计算结果应该是正确的。 。
ADC及INC对条件码的设量方法与ADD指令相同,但INC指令不影响CF标志。
例,ADD DX,0F0F0H

例,下列指令序列执行两个双精度数的加法。设目的操作数存放在DX和AX寄存器中,其中,DX存放高位字。源操作数存放在BX、CX中,其中BX存放高位字。如指令执行前:

指令序列为:
ADD AX,CX
ADC DX,BX
则:执行第一条指令后:

(AX)=0D389H,SF=1,ZF=0,CF=1,OF=0
第二条指令执行后:

(DX)=0008H,SF=0,ZF=0,CF=0,OF=0
因此该指令序列执行完后
〔DX〕=0008H,(AX)=D389H 结果正确。
可以看出:为实现双精度加法,必须用两条指令分别完成低位字和高位字的加法,在高位字相加时,应该使用ADC指令以便把前一条ADD指令作低位字加法所产生的进位值加入高位字之内。另外,带符号的双精度数的溢出,应该根据ADC指令的OF位来判断,而作为低位字加法用的ADD指令的溢出是无意义的。
(二)减法指令
SUB 减法
SBB 带借位减法
DEC 减1
NEG 求补
CMP 比较
1.SUB 减法指令格式,SUB DST,SRC
执行的操作:(DST)〈一 (DST)- (SRC)
2.SBB 带借位减法指令格式,SBB DST,SRC
执行的操作;(DST) 〈一 (DST) - (SRC) - CF
其中CF为进位位的值。
3。DEC 减1指令
格式,DEC OPR
执行的操作:(OPR)〈一 (OPR) - 1
4.NEG 求补指令
格式,NEG OPR
执行的操作:(OPR) 〈一 -(OPR)
亦即把操作数按位求反后末位十1,因而执行的操作也可表示为
(OPR)〈— 0FFFFH - (OPR)十1
5.CMP 比较指令
格式,CMP OPRl,OPR2,
执行的操作;(OPRl) - (OPR2)
注意:CMP指令进行与SUB减法操作相似,但是不保存结果,它起到改变条件标志位的作用。
以上五种指令均可以进行字节或字运算,除DEC指令不影响CF标志外,它们都影响条件标志位。
减法运算的条件码情况与加法类似。CF位说明无符号数相减的溢出,同时它又确实是被减数的最高有效位向高位的借位值。OF位则说明带符号数的溢出,这里不再详细讨论,只说明其设置方法。减法的CF值反映无符号数运算中的借位情况,因此当作为无符号数运算时,若减数>被减数,此时有借位则CF=1,否则CF=0。或者也可以简单地用二进制减法运算中最高有效位向高位的进位情况来判别;有进位时CF=0,无进位时CF=1。减法的OF位的设置方法为:若两个数的符号相反,而结果的符号与减数相同则OF=1,除上述情况外OF=0。OF=1说明带符号数的减法溢出,结果是错误的。
这里再简单说明—下NEG指令的条件码设置情况:NEG指令的条件码按求补后的结果设置:只有当操作数为0时求补运算的结果使CF=0,其它情况则均为1。所以只有当字节运算时对一128求补以及字运算时对一32768求补的情况下OF=1,其它则均为0。
例,SUB [SI十14H],0136H
如指令执行前 (DS)=3000H,(S1)=0040H,(30054H)=4336H
则指令执行后:

所以,(30054H)=4200H,SP=0,ZF=O,CF=0,0F=0
例 SUB DH,[BP十4]
如指令执行前 (DH)=4lH,(SS)=0000H,(BP)=00E4H,(000E8)=5AH
则指令执行后

所以,(DH)=0E7H,SF=1,ZF=0,CF=1,OF=0
例 设X,Y,Z均为双精度数,它们分别存放在地址为X,X十2;Y,Y十2;Z,Z+2的存储单元中,存放时,高位字在高地址中,低位字在低地址中。下列指令序列实现:

并用W和W+2单元存放运算结果。

(三)乘法指令
MUL 无符号数乘法
IMUL 带符号数乘法
1.MUL 无符号数乘法指令
格式,MUL SRC
执行的操作:
字节操作数:(AX) 〈一 (AL)*(SRC)
字操作数,(DX,AX) 〈— (AX)*(SRC)
2.IMUL 带符号数乘法指令
格式; IMUL SRC
执行的操作:与MUL相同,但必须是带符号数。而MUL是无符号数。
注意:
在乘法指令里,目的操作数必须是累加器,字运算为AX,字节运算为AL。两个8位相乘得到的16位乘机存放在AX中,两个16位数相乘得到的是32位乘积,存放在DX,AX中,其中DX存放高字节,AX存放低字节。
指令中的源操作数可以使用除立即数方式以外的任一种寻址方式。
MUL指令和IMUL指令的使用条件是由数的格式决定的。很明显(11111111b)*(11111111b)当把它看作无符号数时应为255d×255d=65025d;而把它看作带符号数时则为(一1)×(一1)=1。因此必须根据所要相乘数的格式来决定选用哪一种指令。
乘法指令对除CF和OF以外的条件码位无定义(注意:无定义的意义和不影响不同,无定义是指指令执行后这些条件码位的状态不定,而不影响则是指该指令的结果并不影响条件码,因而条件码应保持原状态不变)。
对于MUL指令,如果乘积的高一半为0、即字节操作的(AH)或字操作的(DX)为0,则CF和OF均为0;否则(即字节操作时的(AH)或字操作时的(Dx)≠0)则CF和OF均为1。这样的条件码设置可以用来检查字节相乘的结果是字节还是字,或者可以检查字相乘的结果是字还是双字。
对于IMUL指令,如果乘积的高一半是低一半的符号扩展则CF和OF均为0,否则就均为1。
例,如(AL)=0B4H,(BL)=11H求执行指令
IMUL BL和MUL BL 后的乘积值。
(AL)=0B4H为无符号数的180D,带符号数的一76D
(BL) =11H为无符号数的17D,带符号数的17D
执行IMUL的结果为,(AX)=0FAF4H==-1292D
执行MUL 的结果为,(AX)=0BF4H=3060D
CF = OF =1。
(四)除法指令
DIV 无符号数除法
IDIV 带符号数除法由于使用除法指令的需要,这里顺便介绍两条符号扩展指令
CBW 字节转换为字
CWD 字转换为双字
1.DIV 无符号数除法指令格式为,DIV SRC
执行的操作:
字节操作:16位被除数在AX中,8位除数为源操作数,结果的8位商在AL中,8位余数在AH中。表示为:
(AL)〈— (AX)/(SRC)的商
(AH)〈一 (AX)/(SRC)的余数字操作:32位被除数在DX、AX中,其中DX为高位字;16位除数为源操作数,结果的16位商在AX中,16位的余数在DX中。表示为:

商和余数均为无符号数。
2.IDIV 带符号数除法指令格式,IDIV SRC.
执行的操作,DIV相同,但操作数必须是带符号数,商和余数也均为带符号数,且余数的符号和被除数的符号相同。
注意:
除法指令的寻址方式与乘法指令相同。其目的操作数必须存放在AX或DX中。
其源操作数可以用除立即数以外的任何寻址方式。
除法指令对所有条件码均无定义。
由于除法指令的字节操作要求被除数为16位,字操作要求被除数为32位,因此常常需要用符号扩展的办法取得除法指令所需要被除数的格式,为此需要进行如下符号扩展指令来实现符号扩展的功能:
3.CBW字节转换为字指令
格式,CBW
执行的操作:DL的内容符号扩展到AH
如(AL)的最高有效位为1,则(AH)=0FFH。
4,CWD字转换为双字指令
格式,CWD
执行的操作:AX的内容符号扩展到DX。即如(AX)的最高有效位为0,则(DX)=0000H;如(AX)的最高有效位为l,则(DX)=0FFFFH。
这两条指令都不影响条件码。
注意除法指令的溢出:
除法要求字节操作时商为8位,字操作时商为16位。如果字节操作时,被除数的高8位绝对值 〉除数的绝对值;或字节操作时,被除数的高16位绝对值 〉除数的绝对值,这时商就会产生溢出(注意符号位的扩展造成,当有效位最高位为1时,进行无符号计算,容易出现溢出),这种溢出的处理由中断来进行处理,为了避免这种情况,必要时程序应该进行溢出判断及处理。
例,设(AX)=0400H,(DL)=0B4H
即(AX)为无符号数的1024D,带符号数的十1024D
(DL)为无符号数的180D,带符号数的一76D
执行 DIV BL的结果是:
(AH) = 7CH = 124D 余数
(AL)=05H=5D 商
IDIV BL的结果是:
(AH)=24H=36D 余数
(AL)=0F3H=-13D 商例,算术运算综合举例,计算
(V一(X*Y十Z一540))/X
其中X、Y、X和V均为16位带符号数,已分别装入X、Y、Z、V单元中,要求上式计算结果的商存入AX,余数存入DX寄存器。程序段如下

(五)十进制调整指令
前面提到的所有算术运算指令都是二进制数的运算指令,但是人们最常用的是十进制数,这样,当用计算机进行计算时,必须先把十进制数转换成二进制数,然后再进行二进制数的计算,计算结果又转换为十进制数输出。为了便于十进制数的计算,计算机还提供了一组十进制数调整指令,这组指令在二进制计算的基础上,给予十进制调整,可以直接得到十进制的结果。在说明这组指令之前,我们首先介绍计算机中常用的表示十进制数的BCD码。
BCD是一种用二进制编码的十进制数,又称二一十进制数。它是用4位二进制效表示一个十进制数码的,由于这4位二进制数的权为8421,所以BCD码又称为8421码。十进制数码对应的BCD码见下表所示:

在IBM PC机里,表示十进制数的BCD码可以用压缩的BCD码和非压缩的BCD码两种格式来表示。压缩的BCD码用4位二进制数表示一个十进制数位。整个十进制数形式为一个顺序的以4位为一组的数串。例如,9502D应表示为:
1001 0101 0000 0010。
非压缩的BCD码则以8位为一组表示一个十进制数值
4位表示8421的BCD码,而高4仅则没有意义。例如,9502D应表示为:

注意:数字的ASC码可以看着是一种非压缩的BCD码。因为数字的ASC码的高四位值为0011,而低4位是以8421码表示的十进制数位。这符合非压缩BCD码高4位无意义的规定。
IBMPC机的十进制调整指令分为两组,下面分别加以说明:
(一)压缩的BCD码调整指令 ·
DAA 加法的十进制调整指令
DAS 减法的十进调调整指令
我们知道,机器所提供的ADD、ADC以及SUB、SBB指令只适用于二进制加、减法,但压缩的BCD码却是一个字节含有两个十进制数值的二进制数。在使用加、减法指令对BCD码运算后必须经调整后才能得到正确的结果。加法的调整规则是;任意两个用BCD码表示的十进制数位相加的结果,如数值在10l0和1111之间或者产生了向高位的进位,则在其上加6就可得到正确的结果。

可见第一次得到的1101不是BCD码,根据调整规则应在其上加6,得到个位为3并向高位进位的正确结果。
又如:
低位来的进位值:

第一次加法得到的结果有向高位的进位,根据调整规则在其上加6,得到个位为9,并保留进位值而得到正确的结果。
1.DAA 加法的十进制调整指令
执行的操作:
(AL)〈— 把从AL中的和调整到压缩的DCD格式,这条指令之前必须执行ADD或ADC指令,加法指令必须把两个压缩的BCD码相加,并把结果存放在AL寄存器中。本指令的调整方法是;
如果AF标志(辅助进位位)为1,或者AL寄存器的低4传是十六进制的A – F,则AL寄存器内容加06H,且将AF位置入1。
如果CF标志为1,或者AL寄存器的高4位是十六进制的A – F,则AL寄存器内容加 60H,并将CF位置1。
DAA指令对OF标志无定义,但影响所有其它条件标志。
例,ADD AL,BL
DAA
如指令执行前,(AL)=28,(BL)=68
28
0010 1000
68
0110 1000
+
1001 0000
执行ADD指令后(AL)=90,CF=0,AF=1
执行DAA指令时.因AF=1而做
(AL)〈一(AL)+06
得(AL)=96,CF=0,AF=结果正确。
例 如(BCDl)=1834,(BCD2)=2789
要求执行 (BCD3)〈— (BCDl)十(BCD2)
BCDl和BCD2均为用压缩的BCD码表示的十进制数,由于它们都是4位数,所以每个数占有2个字节,高位数占有高位字节,其存放方式为
(BCDl)=34,(BCDl十1)=18;
(BCD2)=89,(BCD2十1)=27。
可写出指令序列如下:

第—组四条指令把低位字节相加经调整后存入BCD3,其中ADD指令后(AL)=34+89=BDH,CF=0,AF=0;经DAA调整后,(AL)=23,CF=1,AF=1。第二组四条指令把高位字节相加经调整后存入BCD3十1。其中ADC指令后(AL)=8十27十CF=40,CF=0,AF=1;经DAA调整后(AL)=46,CF=0,AF=1;最后(DCD3)=4623结果正确。
1.DAS 减法的十进制调整指令
执行的操作:
(AL)〈一 把AL中的差调整到压缩的BCD格式。
这条指令之前必须执行SUB或SBB指令,减法指令必须把两个BCD码相减、并把结果存放在AL寄存器中。本指令的调整方法是;
如果AF标志为l,或者AL寄存器的低4位是十六进制的A—F,则使AL寄存器的内容减去06H.并将AF位置1。
如果CF标志为1,或者AL寄存器的高4位是十六进制的A—F,则使AL寄存器的内容减去60H,并将CF位置l。
DAS指令对OF标志无定义,但影响所有其它条件标志。
例,SUB AL,AH
DAS
如指令执行前,(AL)=86,(AH)=07
86
1000 0110
- 07
0000 0111
↓↓
86
1000 0110
(-7)补
1111 1001
+
0111 1111
执行SUB指令后,(AL)=7FH,CF=0,AF=1
执行DAS指令时。因AF=1,需做:
(AL)=(AL) – 06
而得(AL)=79,CF=0,AF=1,结果正确。
例,如(DCD1)=1234,(BCD2)=4612,试写出指令序列完成(BLD3)〈—(BCD1)- (BCD2)。
BCDl和BCD2均为用压缩的BCD码表示的十进制数,由于它们都是4位数,所以每个数占有2个字节,高位数占有高位字节,其存放方式为
(BCDl)=34,(BCDl十1)=12;
(BCD2)=12,(BCD2十1)=46。
指令序列如下:

第一组四条指令把低位字节相减经十进制调整后存入BCD3。其中SUB指令后(AL)=22,CF=0,AF=0,所以DAS并未做什么操作而把结果送往BCD3。第二组四条指令把高位字节相减经十进制调整后存入BCD3+1。其中SBB指今后,(AL)=CCH,CF=1,AF=1经DAS调整后(AL)=66,CF=1,AF=1;最后(BCD3) = 6622,到这里,会说结果错了,其实,结果是对的、6622是一3378的十的补码。
下面讨论可以有两种方法用BCD码表示十进制数的符号问题。
(1)一种是专门设一个表示符号的字段。例如下一章将讨论的DT伪操作用来定义一个十个字节的压缩BcD码,其中就规定其最高地址的字节用来表示数的符号,该字节的最高有效位为符号位,其余7位为0.这就提供了用这种方法表示数的符号的手段。
(2)另一种方法就是使用十的补码来表示,如十进制数的数值为n、则任意整数d的十的补码定义为10n - d,数位为n的十进制数的表数范围为一5×10 n-1 一5×10 n-1-1。如n=8,则可用二个字(32位)来表示一个十进制数,其表数范围为-5000 0000 - 49999999。n=4,用16位表示一个带符号数,此时的表数范围是-5000一 十4999,所以6622应表示一个负数.它是-3378。
(二)非压缩的BCD码调整指令
AAA 加法的ASCII调整指令
AAS 减法的ASCII调整指令
AAM 乘法的ASCII调整指令
AAD 除法的ASCII调整指令这—组指令适于数字ASCII的调整,也适用于一般的非压缩BCD码的十进制调整,下面分别说明各条指令的功能。
1.AAA 加法的ASCII调整指令
执行的操作:
(AL)〈— 把AL中的和调整到非压缩的BCD格式
(AH) = (AH)十调整产生的进位值这条指令之前必须执行ADD或ADC指令,加法指令必须把两个非压缩的BCD码相加,并把结果存放在AL寄存器中。本指令的调整步骤是:
(1)如AL寄存器的低4位在0一9之间,且AF位为0,则跳过第(2)步,执行第(3)步;
(2)如AL寄存器的低4位在十六进制数A — F之间或AF为1,则AL寄存器的内容加6,AH寄存器的内容加1,并将AF位置1。
(3)清除AL寄存器的高4位:
(4)AF位的值送CF位。
AAA指令除影响AF和CF标志外,其余标志位均无定义。
例,ADD AL,BL
AAA
如指令执行前,(AX) = 0535H,〔BL〕=39H,可见AL和BL寄存器的内容分别为5和9的ASCII。
35
0011 0101
39
0011 1001
+
0110 1110
第一条指令执行完后,(AL) = 6EH,AF=0;
第二条指令进行ASC调整的结果使(AX)=0604H,AF=1,CF=1。
2.AAS 减法的ASC调整指令
执行的操作,
(AL)〈— 把AL中的差调整到非压缩的BCD格式
(AH)〈— (AH) 一 调整产生的借位值这条指令之前必须执行SUB或SBB指令,减法指令必须把两个非压缩的BCD码相减,并把结果存放在AL寄存器中。本指令的调整步骤是;
(1)如从寄存器的低4位在0一9之间,且AF位为0,则跳过第(2)步,执行第(3)步。
(2)如从寄存器的低4位在十六进制数A—F之间或AF位为1,则把AL寄存器的内容减去6,AH寄存器的内容减1,并将AF位置1;
(3)清除AL寄存器的高4位;
(4)AF位的值送CP位。
AAS指令除影响AP和CF标志外,其余标志位均无定义
例,编写程序段实现下式
(DX) 〈— UPl十UP2一UP3
其中参加运算的数均为二位十进制数。如要求计算25十48一19,每个十进制数以非压缩BCD格式存入存储器,每个数占有一个字,所以(UP1)=0205H.(UP2)=0408H,(UP3)=0109H。可写出指令序列如下图所示。

3.AAM 乘法的ASC调整指令
执行的操作:
(AX) 〈— 把AL中的和调整到非压缩的BCD格式。
这条指令之前必须执行MUL指令把两个非压缩的BCD码相乘(此时要求其高4位为0),结果放在AL寄存器中。
本指令的调整方法是:把AL寄存器的内容除以0AH,商放在AH寄存器中,余数保存在AL寄存器中。本指令根据AL寄存器的内容设置条件码SF、ZF和PF,注意:OF,CF和AF位无定义。
刨 MUL AL,BL
AAM
如指令执行前,(AL)=07H,(BL)=09H
执行MUL后,(AL) = 3FH
执行AAM后,(AH)=06H,(AL)=03H
例,编写程序段实现下式
C 〈— A*B
其中A、B单元分别存放着二位用非压缩BCD码表示的十进制数34和56,因而(A)=04H,(A十1)=03H;(B)=06H,(B十1)=05H。二位十进制数乘法的算法如下:

因而结果应存放在以c为首地址的4个相继字节单元中,在计算过程中还应开辟以C0和C1为首地址的各三个字节单元作存放中间结果用。编制的程序段及说明如下;



最后得到(C)=04H,〔C十1〕=00H,(C十2)=09H,(C十3)=01H;即乘积为十进制的1904,结果正确。
4.AAD 除法的ASCII调整指令
前面所述的加法、减法和乘法的ASC调整指令都是用加法、减法和乘法指令对两个非压缩的BCD码运算以后,再使用AAA、AAS、AAM指令来对运算结果进行十进制调整的。除法的情况却不同,它是针对以下情况而设立的。
如果被除数是存放在AX寄存器中的二位非压缩BCD数。AH中存放十位数,AL中存放个位败,而且要求AH和AL中的高4位均为0。除数是一位非压缩的BCD数,同样要求高4位为0,在把这两个数用DIV指令相除以前,必须先用AAD指令把AX中的被除数调整成二进制数,并存放在AL寄存器中。因此,AAD指令执行的操作是:
(AL) 〈— 10*(AH)十(AL)
(AH) 〈— 0
本指令根据AL寄存器的结果设置SF、ZF和PF位,OF和CF和AF无定义。
例 AAD
如指令执行前(AX)=0604H,
则指令执行后(AX)=0040H
例 编写程序段实现:
C 〈— B/A的商
R 〈— B/A的余数其中B字单元中存放着用非压缩BCD码表示的二位十进制数53,A字节单元中存放着用非压缩BCD码表示的一位数3。除法过程可表示如下:

结果的商存放在字单元C中,余数存放在字节单元R中。编制的程序及说明如下:

最后得到(C)=07H,(C十1)=01H,(C+3)=02H,即商为17,余数为2,结果正确。
3.3.3 逻辑指令三、逻辑运算指令
AND 逻辑与
OR 逻辑或
NOT 逻辑非
XOR 异或
TEST 测试逻辑运算指令可以对字或字节执行逻辑运算。由于逻辑运算是按位操作的,因此一般来说,其操作数是位串而不是数。
1.AND 逻辑与指令
格式; AND DST,SRC
执行的操作:(DST) 〈一 (DST) ∧ (SRC)
2.oR 逻辑或指令
格式,OR DST,SRC
执行的操作:(DST) 〈— (DST)∨(SRC)
3.NOT 逻辑非指令
格式,NOT OPR
执行的操作:(OPR) 〈一 (OPR)
4,XOR 异或指令
格式,XOR DST,SRC
执行的操作:(DST) <一 (DST)  (SRC)
5.TEST 测试指令
格式,TEST OPRl,OPR2
执行的操作;(OPR1) ∧(OPR2)
注意:两个操作数相与的结果不保存,只根据其特征置条件码。
以上五种指令中,NOT不允许使用立即数,其它4条指令除非源操作数是立即数,至少有一个操作数必须存放在寄存器中,另一个操作数则可以使用任意寻址方式。
它们对标志位的影响情况是:NOT指令不影响标志位,其它4种指令将使CF和OF为0,AF位无定义,而SF、ZF和PF则根据运算结果设置。
这些指令对处理操作数的某些位很有用,例如可屏蔽某些位(将这些位置0),或使某些位置1或测试某些位等,下面举例说明:
例 要求屏蔽0、l两位,可用AND指令并设置常数0FCH:
MOV AL,0BFH
AND AL,0FCH
这两条指令执行的结果使(AL)=0BCH

所以用AND指令可以使操作数的某些位被屏蔽。只需要把AND指令的源操作数设置成一个立即数,并把需要屏蔽的位置为0,这样指令执行的结果就可把操作数的相应位置0,其它各位保持不变。
例,要求第5位置1,可用OR指令
MOV AL,43H
OR AL,20H
这两条指令执行后,(AL)=63H

所以用OR指令可以使操作数的某些位置1,其它位则保持不变。只需要把OR指令的源操作数设置为一个立即数,并把需要置1的位设为1,就可达到目的。
例.要测试操作数的某位是否为0,可用TEST指令,同样把TEST指令的源操作数设置成一个立即数,其中需要测试的位应设置为1。