Assembly Language Programming 汇编语言程序设计 主讲人 刘雪洁
第2章 80x86的指令系统 2.1 指令格式 2.2 寻址方式 2.3 数据传送类指令 2.4 算术运算类指令 2.5 位操作类指令 2.1 指令格式 2.2 寻址方式 2.3 数据传送类指令 2.4 算术运算类指令 2.5 位操作类指令 2.6 串操作类指令 2.7 控制转移类指令 2.8 处理机控制类指令
2.1 指令格式 计算机是通过执行指令序列来解决问题的。计算机的指令系统就是指该计算机能够执行的全部指令的集合。 指令的一般格式: 2.1 指令格式 计算机是通过执行指令序列来解决问题的。计算机的指令系统就是指该计算机能够执行的全部指令的集合。 指令的一般格式: [标号:] 操作符 OPD, OPS [;注释] 算术运算和位操作类指令的部分单操作数指令的格式: [标号:] 操作符 OPD [;注释]
2.2 寻址方式 2.2.1 立即寻址 2.2.2 寄存器寻址 2.2.3 直接寻址 2.2.4 寄存器间接寻址 2.2.5 变址寻址 2.2 寻址方式 2.2.1 立即寻址 2.2.2 寄存器寻址 2.2.3 直接寻址 2.2.4 寄存器间接寻址 2.2.5 变址寻址 2.2.6 基址加变址寻址 2.2.7 跨段问题 2.2.8 与转移地址有关的寻址方式
2.2.1 立即寻址 立即寻址方式中,指令操作码和操作数都在存储器代码段中。 立即数可以是用8位或16位二进制补码表示的有符号数。 2.2.1 立即寻址 立即寻址方式中,指令操作码和操作数都在存储器代码段中。 立即数可以是用8位或16位二进制补码表示的有符号数。 功能:常用于给寄存器赋初值,只能用于源操作数字段,且源操作数与目的操作数长度应一致。
【例】MOV AX, 10 执行后(AX)=? 该例中源操作数为立即寻址方式,立即数为10,存放在指令的下一单元。 图形表示: 执行:10→AX 执行后:(AX)=000AH
2.2.2 寄存器寻址 寄存器寻址方式的操作数在指令指明的寄存器中。 2.2.2 寄存器寻址 寄存器寻址方式的操作数在指令指明的寄存器中。 【例】下列程序执行后,(AX)=?,(BX)=? MOV AX,1234H MOV BX,5678H ADD AX,BX 该程序中MOV指令为数据传送指令操作符,ADD指令为加法指令操作符,三条指令皆为双操作数指令。第一、二条指令AX、BX皆为目的操作数地址,为寄存器寻址方式。第三条指令中,AX为目的操作数地址,BX为源操作数地址。源地址和目的地址皆为寄存器寻址方式。
图形表示: 执行:1234H→AX 5678H→BX (AX)+(BX)→AX 执行后:(AX)=68ACH,(BX)=5678H
2.2.3 直接寻址 汇编格式:①含有变量的地址表达式。 ②段寄存器名:[EA] 。 2.2.3 直接寻址 汇编格式:①含有变量的地址表达式。 ②段寄存器名:[EA] 。 功能:指令下一字单元的内容是操作数的有效(偏移)地址EA。 图形表示:
【例】寄存器和存储器内容为:(AX)=1212H,BUF为数据段定义的变量,其偏移地址是2000H,(DS)=3000H,(32000H)=4545H。 执行指令:MOV AX ,BUF(MOV AX , [2000H]) 执行后:(AX)=? 图形表示: 执行:(32000H)→AX 执行后:(AX)=4545H
2.2.4 寄存器间接寻址 寄存器间接寻址方式中,寄存器的内容为操作数的偏移地址EA,操作数在存储器中。 汇编格式:[R] 2.2.4 寄存器间接寻址 寄存器间接寻址方式中,寄存器的内容为操作数的偏移地址EA,操作数在存储器中。 汇编格式:[R] 功能:操作数存放在存储器,寄存器R存放操作数的偏移地址EA。
偏移地址EA计算方法如下: [SI] SI作间址寄存器。 [DI] DI作间址寄存器。 [BX] BX作间址寄存器。 [BP] BP作间址寄存器。 EA=
【例】寄存器和存储器内容分别为:(AX)=0,(BP)=0030H,(SS)=2000H,(20030H)=1234H 执行指令:MOV AX ,[BP] 执行后:(AX)=? 图形表示如下: 执行:(20030H)→AX 执行后:(AX)=1234H
2.2.5 变址寻址 变址寻址方式操作数的偏移地址EA为寄存器的内容加位移量,操作数在存储器中,又称为寄存器相对寻址。 2.2.5 变址寻址 变址寻址方式操作数的偏移地址EA为寄存器的内容加位移量,操作数在存储器中,又称为寄存器相对寻址。 汇编格式:X[R](X表示位移量,是8位或16位二进制补码表示的有符号数) 功能:操作数存放在存储器,寄存器R的内容加位移量X为操作数的偏移地址EA。 图形表示如下:
偏移地址EA计算方法如下:
【例】设执行前: (AX)=0040H,(BX)=0030H,(DS)=2000H,(20036H)=0050H 执行指令:ADD 6[BX],AX 执行后:(AX)=?,(BX)=?,(DS)=?, (20036H)=? 图形表示如下: 执行:(20036H)+(AX) →20036H 执行后:(AX)=0040H,(BX)=0030H,(DS)=2000H,(20036H)=0090H。
2.2.6 基址加变址寻址 基址加变址寻址方式中,操作数的偏移地址EA是指令中基址寄存器内容、变址寄存器内容、位移量X三项之和,操作数在存储器中。 汇编格式:X [BR+IR] 功能:操作数存放在存储器,BR的内容加IR的内容加位移量X是操作数的偏移地址EA。
图形表示: 操作数偏移地址EA计算方法如下
2.2.7 跨段问题 按前述规定:若选用BP作间址基址寄存器、变址寄存器或基址寄存器,则操作数在堆栈段,操作数的物理地址PA由堆栈段寄存器SS的内容左移4位与偏移地址EA相加后形成;否则,操作数在数据段,操作数的物理地址PA由数据段寄存器DS的内容左移4位与偏移EA相加后形成。该规定为系统默认状态。当要否定默认状态,到非约定段寻找操作数时,必须用跨段前缀指明操作数的段寄存器名。
汇编格式:段寄存器名:操作数地址。 功能:段寄存器名指明操作数属哪个段。 【例】 MOV AX,DS:[BP] MOV CX,SS:[SI] 该例中,DS:,SS:均为跨段前缀,此时默认状态无效,操作数的物理地址PA由段寄存器内容左移4位加偏移EA形成。上述2条指令的源操作数物理地址分别为: PA1 =(DS)左移4位+[BP] PA2 =(SS)左移4位+[SI
2.2.8 与转移地址有关的寻址方式 这种寻址方式用来确定转移指令及CALL指令的转向地址。 2.2.8 与转移地址有关的寻址方式 这种寻址方式用来确定转移指令及CALL指令的转向地址。 段内直接寻址:转向的有效地址是当前IP寄存器的内容和指令中指定的8位或16位位移量之和。 位移量 + EA IP寄存器 这种方式的转向有效地址用相对于当前IP值的位移量来表示,所以它是一种相对寻址方式。
指令中的位移量是转向的有效地址与当前IP值之差,所以当这一程序段在内存中的不同区域运行时,这种寻址方式的转移指令本身不会发生变化。这种寻址方式适用于条件转移及无条件转移指令,但当它用于条件转移指令时,位移量只允许8位,无条件转移指令在位移量为8位时称为短跳转,位移量为16位时称为近跳转。 例:JMP NEAR PTR PROGIA JMP SHORT QUEST 其中,PROGIA和QUEST均为转向的符号地址,在机器指令中,用位移量来表示。在汇编指令中,如果位移量为16位,则在符号地址前加NEAR PTR;如果位移量为8位,则在符号地址前加SHORT。
这种方式以及以下的两种段间寻址方式都不能用于条件转移指令,而JMP和CALL指令可以用四种寻址方式中的任何一种。 段内间接寻址:转向的有效地址是一个寄存器或是一个存储单元的内容。这个寄存器或存储单元的内容可以用数据寻址方式中除立即数以外的任何一种寻址方式取得,所得到的转向的有效地址用来取代IP寄存器的内容。 数据寻址方式 根据数据寻址方式计算出EA值 转向的有效地址 或 指令 存储单元 这种方式以及以下的两种段间寻址方式都不能用于条件转移指令,而JMP和CALL指令可以用四种寻址方式中的任何一种。
例:设(DS)=2000H,(BX)=1256H,位移量=20A1H,(232F7H)=3280H,(264E5H)=2450H. 指令:JMP BX 可求得转向地址为BX寄存器的内容,执行该指令后(IP)=1256H 指令:JMP TABLE[BX] 执行该指令后(IP)=(16d*(DS)+BX+位移量) =(20000+1256+20A1) =(232F7) =3280H
JMP FAR PTR NEXTROUTINT 其中,NEXTROUTINT为转向的符号地址,FAR PTR则是表示段间转移的操作符。 段间直接寻址:在指令中直接提供了转向段地址和偏移地址,所以只要用指令中指定的偏移地址取代IP寄存器的内容,用指令中指定的段地址取代CS寄存器的内容就完成了从一个段到别一个段的转移操作。 偏移地址 指令 段地址 IP寄存器 CS寄存器 指令的汇编语言格式可表示为: JMP FAR PTR NEXTROUTINT 其中,NEXTROUTINT为转向的符号地址,FAR PTR则是表示段间转移的操作符。
JMP DWORD PTR [INTERS+BX] 段间间接寻址:用存储器中的两个相继字的内容来取代IP和CS寄存器中的原始内容,以达到段间转移的目的。这里存储单元的地址是由指令指定除立即数方式和寄存器方式以外的任何一种数据寻址方式取得。 存储器中两个相继字 指令 IP 根据数据寻址方式计算出EA值 转向的有效地址 数据寻址方式 转向的有效地址 CS 指令的汇编语言格式可表示为: JMP DWORD PTR [INTERS+BX] 其中, [INTERS+BX]说明数据寻址方式为直接寻址方式,DWORD PTR为双字操作符,说明转向地址需要取双字为段间转移指令。
2.3 数据传送类指令 2.3.1 通用数据传送指令 2.3.2 堆栈操作指令 2.3.3 标志寄存器传送指令 2.3.4 地址传送指令 2.3 数据传送类指令 2.3.1 通用数据传送指令 2.3.2 堆栈操作指令 2.3.3 标志寄存器传送指令 2.3.4 地址传送指令 2.3.5 输入输出指令
2.3.1 通用数据传送指令 1.传送指令MOV 2.数据交换指令XCHG 3.查表转换指令 XLAT
1.传送指令MOV 语句格式:MOV OPD,OPS 功能:将源操作数传送入目的地址,源地址内容不变。即(OPS)→OPD。 注:CS不允许 做目的 操作数.
【例】存储器与寄存器间数据传送。 MOV AX,BUF ;BUF是变量,源操作数为直接寻址 MOV BH,[DI] ;源操作数为寄存器间接寻址 MOV DI,ES:3[SI] ;源操作数为变址寻址,使用跨段前缀 MOV BP,3[BX+SI] ;源操作数为基址加变址寻址 MOV BUFA,DL ;BUFA是一字节变量 MOV [BP],AX ;使用SS段寄存器 MOV DS:[BP],DL ;使用跨段前缀 MOV BUF,DS ;BUF是个字变量 MOV ES ,BUF
2.数据交换指令XCHG 语句格式:XCHG OPD,OPS 功能:将源地址与目的地址中的内容互换。即(OPD)→OPS,(OPS)→OPD。 【例2.9】寄存器与存储器之间数据交换。 MOV AX,5678H ;(AX)=5678H MOV BX,0FFFFH ;(BX)=0FFFFH XCHG AX,BX ;(AX)=0FFFFH,( BX)=5678H
3.查表转换指令 XLAT 语句格式:XLAT OPS或XLAT 功能:将(BX)为首址,(AL)为位移量的字节存储单元中的数据送AL寄存器。即([BX+AL])→AL。
2.3.2 堆栈操作指令 1.进栈指令PUSH 2.出栈指令POP
1.进栈指令PUSH 语句格式: PUSH OPS 功能:将寄存器、段寄存器或存储器中的一个字数据压入堆栈,堆栈指针减2。 即: ①(SP)-1→SP (OPS)15~8→[SP] ②(SP)-1→SP (OPS)7~0→[SP]
2.出栈指令POP 语句格式: POP OPD 功能: 将栈顶元素弹出送至某一寄存器、段寄存器(除CS外)或存储器,堆栈指针加2。 从POP指令功能可看出,该指令为PUSH指令的逆过程。 即: ①([SP])→(OPD)7~0 (SP)+1→SP ②([SP])→(OPD)15~8 (SP)+1→SP
2.3.3 标志寄存器传送指令 1.标志送AH指令LAHF 2.AH送标志指令SAHF 3.标志寄存器进栈指令PUSHF 2.3.3 标志寄存器传送指令 1.标志送AH指令LAHF 2.AH送标志指令SAHF 3.标志寄存器进栈指令PUSHF 4.标志寄存器出栈指令POPF
1.标志送AH指令LAHF 语句格式:LAHF 功能:将标志寄存器的低8位送入AH寄存器。 即(FLAGS)7-0→AH。该指令的执行对标志位无影响。 【例】标志寄存器传送。 执行前:(FLAGS)=0485H,(AX)=0FFFFH 执行指令:LAHF 执行后:(FLAGS)=0485H,(AX)=085FFH
2.AH送标志指令SAHF 语句格式:SAHF 功能:将AH的内容送入标志寄存器的低8位,高8位不变。即(AH) →FLAGS7-0。 从该指令功能可看出,SAHF为LAHF的逆过程。
3.标志寄存器进栈指令PUSHF 语句格式:PUSHF 功能:将标志寄存器的内容压入堆栈。即(FLAGS)→↓(SP)。
4.标志寄存器出栈指令POPF 功能: 将栈顶内容弹出送入标志寄存器中。即↑(SP)→FLAGS。 POPF指令与PUSHF指令互为逆过程。 【例】将标志寄存器的单步标志TF置位。 PUSHF ;(FLSGS)→↓(SP) POP AX ;(SP)→AX OR AX, 0100H ;设置D8=TF=1 PUSH AX ;(AX)→↓(SP) POPF;(SP)→↓FLAGS,即(AX)→↓FLAGS
2.3.4 地址传送指令 1.传送偏移地址指令 LEA 2.传送偏移地址及数据段首址指令LDS 3.传送偏移地址及附加数据段指令LES
1.传送偏移地址指令 LEA 语句格式: LEA OPD,OPS 功能:主存按源地址的寻址方式计算偏移地址,将偏移地址送入指定寄存器。 【例2.15】主存偏移地址的获取。 MOV BX,0100H ;(BX)=0100H MOV SI, 0210H ;(SI) =0210H LEA BX,1234[BX+SI] ;(BX)=1544H
2.传送偏移地址及数据段首址指令LDS 语句格式:LDS OPD,OPS 即(OPS)→OPD,(OPS+2)→DS。
3.传送偏移地址及附加数据段指令LES 语句格式:LES OPD,OPS 功能:将主存某字单元内容送指定寄存器。即(OPS)→OPD,(OPS+2)→ES。
2.3.5 输入输出指令 1.输入指令IN 2.输出指令OUT
1.输入指令IN 输入指令用来从指定的外设寄存器取信息送入累加器。它有四种形式: (1)语句格式:IN AL,PORT 功能:(PORT) →AL (2)语句格式:IN AX,PORT 功能:(PORT) →AX (3)语句格式:IN AL,DX 功能:([DX]) →AL (4)语句格式:IN AX,DX
2.输出指令OUT 输出指令用来把累加器的内容送往指定的外设存储器,它有四种形式: 功能:(AL) →PORT (1)语句格式:OUT PORT,AL 功能:(AL) →PORT (2)语句格式:OUT PORT,AX 功能:(AX) →PORT (3)语句格式:OUT DX,AL 功能:(AL) →[DX] (4)语句格式:OUT DX,AX 功能:(AX) →[DX]
在80x86中,所有I/0端口与CPU之间的通信都由IN和OUT指令来完成。其中IN完成从I/0到CPU的信息传送,而OUT则完成从CPU到I/0的信息传送。CPU只能用累加器(AL或AX)接收或发送信息。外部设备最多可有65536个I/0端口,端口号为0000H-FFFFH。其中前256个端口可以直接在指令中指定,当端口大于等256时,必须先把端口号放到DX寄存器中,然后再用IN或OUT来传送信息。 例:IN AX,28H MOV DA,AX 这两条指令把端口28的内容经过AX传送到存储单元DA中。 例:OUT 5,AL 这条指令从AL寄存器输出一个字节到端口5.
2.4 算术运算类指令 2.4.1 加法指令 2.4.2 减运算指令 2.4.3 乘运算指令 2.4.4 除运算指令 2.4 算术运算类指令 2.4.1 加法指令 2.4.2 减运算指令 2.4.3 乘运算指令 2.4.4 除运算指令 2.4.5 符号扩展指令 2.4.6 十进制调整指令
2.4.1 加法指令 1.加1指令 INC 2.加指令ADD 3.带进位加指令ADC
1.加1指令 INC 语句格式:INC OPD 功能:将目的操作数加1,结果送目的地址。即(OPD)+1→OPD。 INC指令是一个单操作数指令,操作数可以是寄存器或存储器操作数。 如:INC BX,即(BX)+1→BX。 加1指令可用于对计数器和地址指针进行调整。
2.加指令ADD 语句格式:ADD OPD, OPS 功能:将目的操作数与源操作数相加,结果存入目的地址中,源地址的内容不改变。 即(OPD)+(OPS)→OPD。 3.带进位加指令ADC 语句格式:ADC OPD,OPS 功能:将目的操作数加源操作数再加低位进位,结果送目的地址。 即(OPD)+(OPS)+CF → OPD。
【例】无符号双字加法运算。 MOV AX,4652H ;(AX)=4652H ADD AX,0F0F0H ;(AX)=3742H, CF=1 MOV DX,0234H ;(DX)=0234H ADC DX,0F0F0H ;(DX)=0F325H, CF=0
2.4.2 减运算指令 1.减1指令DEC 2.减指令SUB 3.带借位减指令 SBB 4.求补指令NEG 5.比较指令 CMP
1.减1指令DEC 语句格式:DEC OPD 功能:将目的操作数减1,结果送目的地址。即(OPD)-1→OPD。 DEC指令是一个单操作数指令,操作数可以是寄存器或存储器操作数。 如:DEC CX。即(CX)-1→CX。 减1指令DEC也一般用于对计数器和地址指针的调整。
2.减指令SUB 语句格式:SUB OPD,OPS 功能:目的操作数减源操作数,结果存于目的地址,源地址内容不变。 即(OPD)-(OPS)→OPD 【例】减法运算。 MOV AX ,5678H ;(AX)=5678H SUB AX ,1234H ;(AX)=4444H MOV BX ,3354H ;(BX)=3354H SUB BX ,3340H ;(BX)=0014H
3.带借位减指令 SBB 语句格式:SBB OPD ,OPS 功能:目的操作数减源操作数再减低位借位CF,结果送目的地址。 即(OPD)―(OPS)―CF → OPD 4.求补指令NEG 语句格式:NEG OPD 功能:将目的操作数的每一位求反(包括符号位)后加1,结果送目的地址。 即 0FFFF -(OPD)+1→OPD。
【例】求补运算。 MOV AX,0FF64H ;1111 1111 0110 0100 NEG AL ;(AX)=0FF9CH (1001 1100) SUB AL,9DH ;(AX)=0FFFFH CF=1 NEG AX ;(AX)=0001H DEC AL ;(AX)=0000H NEG AX ;(AX)=0000H
5.比较指令 CMP 语句格式:CMP OPD,OPS 功能:目的操作数减源操作数,结果只影响标志位,不送入目的地址。 即(OPD)-(OPS)。 【例】比较AL的内容数值大小。 CMP AL,50;(AL)-50 JB BELOW ;(AL)<50,转到BELOW处执行 SUB AL,50;(AL)>=50,(AL)-50→AL INC AH ;(AH)+1→AH BELOW: …
2.4.3 乘运算指令 1.无符号数乘法指令MUL 2.有符号乘指令IMUL
1.无符号数乘法指令MUL 语句格式: MUL OPS 功能: 若是字节数据相乘,(AL)与OPS相乘得到字数据存入AX中;若是字数据相乘,则(AX)与OPS相乘得到双字数据,高字存入DX、低字存入AX中。 即字节乘法:(AL)* (OPS) →AX, 字乘法:(AX) * (OPS) →DX,AX 【例】无符号数0A3H与11H相乘。 MOV AL,0A3H ;(AL)=0A3H MOV BL, 11H ;(BL)=11H MUL BL ;(AX)=0AD3H
2.有符号乘指令IMUL语句 格式:IMUL OPS 功能:字节乘法:(AL)*(OPS)→AX, 字乘法:(AX)*(OPS)→DX、AX。 IMUL指令除计算对象是带符号二进制数外,其他都与MUL一样,但计算结果不同。 【例】有符号数0B4H与11H相乘。 MOV AL,0B4H ;(AL)=B4H MOV BL,11H ;(BL)=11H IMUL BL ;(AX)=0FAF4H
2.4.4 除运算指令 1.无符号除指令DIV 2.有符号除指令IDIV
1.无符号除指令DIV 语句格式:DIV OPS 功能: 字节除法:(AX)/(OPS)→ AL(商)、AH(余数) 字除法:(DX、AX)/(OPS)→ AX(商)、DX(余数) 【例】写出实现无符号数0400H/0B4H运算的程序段。 MOV AX,0400H ;(AX)=0400H MOV BL,0B4H ;(BL)=0B4H DIV BL ;商(AL)=05H,余数(AH)=7CH
2.有符号除指令IDIV 语句格式:IDIV OPS 功能: 字节除法:(AX)/(OPS)→AL(商),AH(余数) 字除法:(DX,AX)/(OPS)→AX(商),DX(余数) 除法指令DIV和IDIV虽然对标志的影响未定义,但可产生溢出。 【例】写出实现有符号数0400H/0B4H运算的程序段。 MOV AX,0400H ;(AX)=0400H MOV BX,0B4H ;(BX)=0B4H IDIV BX ;(AL)=0F3H,(AH)=24H
2.4.5 符号扩展指令 1.字节转换成字指令CBW 2.将字转换成双字指令CWD
1.字节转换成字指令CBW 语句格式:CBW 功能:将AL中的符号位数据扩展至AH。 【例】将字节数据扩展成字数据。 MOV AL,0A5H ;(AL)=0A5H CBW ;(AX)=0FFA5H ADD AL,70H ;(AL)=25H CBW ;(AX)=0025H
2.将字转换成双字指令CWD 语句格式:CWD 功能:将AX中的符号位数据扩展至DX 。 【例】将字数据扩展成双字数据。 MOV DX, 0 ;(DX)=0 MOV AX, 0FFABH ;(AX)=0FFABH CWD ;(DX)=0FFFFH (AX)=0FFABH
2.4.6 十进制调整指令 1.压缩BCD码调整指令 2.非压缩BCD码调整指令
1.压缩BCD码调整指令 (1)加法的十进制调整指令DAA语句 格式:DAA 功能:如果AL寄存器中低4位大于9或辅助进位(AF)=1,则(AL)=(AL)+6且(AF)=1;如果(AL)>=0A0H或(CF)=1,则(AL)=(AL)+60H且(CF)=1。同时,SF、ZF、PF均有影响。 【例】压缩BCD码的加法运算。 MOV AL,68H ;(AL)=68H,表示压缩BCD码68 MOV BL,28H ;(BL)=28H,表示压缩BCD码28 ADD AL,BL ;二进制加法:(AL)=68H+28H=90H DAA ;十进制调整:(AL)=96H ;实现压缩BCD码加法:68+28=96
(2)减法的十进制调整指令DAS语句 格式:DAS 功能:如果(AF)=1或AL寄存器中低4位大于9,则(AL)=(AL)-6且(AF)=1;如果(AL)>=0A0H或(CF)=1,则(AL)=(AL)-60H且(CF)=1。同时SF、ZF、PF均受影响。 【例】压缩BCD码的减法运算。 MOV AL,67H ;(AL)=67H,表示压缩BCD码67 MOV BL,28H ;(BL)=28H,表示压缩BCD码28 SUB AL,BL ; (AL)=67H-28H=3FH DAS ;十进制调整:(AL)=39H ;实现压缩BCD码减法:67-28=39
2.非压缩BCD码调整指令 (1)加法的非压缩BCD码调整指令AAA 语句格式:AAA 功能:如果AL的低4位大于9或(AF)=1,则: (AL)=(AL)+6 (AH)=(AH)+1 (AF)=(CF)=1 且AL高4位清零。 否则:(CF)=(AF)=0 AL高4位清零。
(2)减法的非压缩BCD码调整指令AAS 语句格式:AAS 功能:如果AL的低4位大于9或(AF)=1,则:(AL)=(AL)-6 (AH)=(AH)-1 (AF)=(CF)=1 AL高4位清零。 否则:(CF)=(AF)=0 AL高4位清零。 其他标志位OF、PF、SF、ZF不确定。
(3)乘法的非压缩BCD码调整指令AAM 语句格式:AAM 功能:被调整的乘积在AX中,对AL按10取模,则: (AL)/0AH→AH(商):AL(余数) 其中AH为商,AL为余数,标志位AF、CF、OF、PF、SF、ZF受影响。
(4)除法的非压缩BCD码调整指令AAD 语句格式:AAD 功能:除法运算前,先调整被除数AX内容,使: (AL)=(AL)+(AH)*0AH (AH)=0 即把非压缩型十进制数变成二进制数。
2.5 位操作类指令 2.5.1 逻辑运算指令 2.5.2 移位指令
2.5.1 逻辑运算指令 1.求反指令NOT 2.逻辑乘指令AND 3.测试指令TEST 4.逻辑加指令OR 5.按位加指令XOR
1.求反指令NOT 语句格式:NOT OPD 功能:将目的地址中的内容逐位取反后送入目的地址。即(OPD)→OPD 【例】逻辑非运算。 MOV AX,878AH ;(AX)=878AH ; 1000 0111 1000 1010 B NOT AX, ;(AX)=7875H
2.逻辑乘指令AND 语句格式:AND OPD, OPS 功能:将目的操作数和源操作数进行逻辑乘运算,结果存目的地址。 即(OPD)∧(OPS)→OPD。 该指令用于清除目的操作数中与源操作数置0的对应位。说明:逻辑乘的运算法则为:1∧1=1,1∧0=0,0∧1=0,0∧0=0 【例】将AL中第3位和第7位清零。 MOV AL,0FFH AND AL,77H ;0111 0111 B
3.测试指令TEST 语句格式:TEST OPD,OPS 功能:源地址和目的地址的内容执行按位的逻辑乘运算,结果不送入目的地址。 即(OPD)∧(OPS)。 【例】测试AX中的第12位是否为0,不为0则 转L。 TEST AX,1000H ; 0001 0000 0000 0000B JNE L
4.逻辑加指令OR 语句格式:OR OPD,OPS 功能:将目的操作数和源操作数进行逻辑加运算,结果存目的地址。 即(OPD)∨(OPS)→OPD。 说明:逻辑加的运算法则为:1∨1=1,1∨0=1,0∨1=1,0∨0=0。 【例】将AL寄存器中第3位和第7位置1。 MOV AL,0 OR AL,88H
5.按位加指令XOR 语句格式: XOR OPD,OPS 功能:目的操作数与源操作数做按位加运算,结果送入目的地址。 即(OPD)⊕(OPS) →OPD。 说明:按位加的运算法则为;1⊕1=0,1⊕0=1,0⊕1=1,0⊕0=0。 【例】按位加运算。 MOV AL,45H ;(AL)=45H XOR AL,31H ;(AL)=74H
2.5.2 移位指令 移位指令包括算术移位指令、逻辑移位指令和循环移位指令,分别进行左移和右移操作。这些指令均有统一的语句格式: 2.5.2 移位指令 移位指令包括算术移位指令、逻辑移位指令和循环移位指令,分别进行左移和右移操作。这些指令均有统一的语句格式: [标号:]操作符 OPD,1 或 [标号:]操作符 OPD,CL 其功能为将目的操作数的所有位按操作符规定的方式移动1位或按寄存器CL规定的次数(0~255)移动,结果送入目的地址。目的操作数是8位(或16位)的寄存器数据或存储器数据。
1.算术左移和逻辑左移指令SAL(SHL) 语句格式:SAL OPD,1 或 SHL OPD,1 SAL OPD,CL 或 SHL OPD,CL 功能:将(OPD)向左移动CL指定的次数,最低位补入相应的0,CF的内容为最后移入位的值。 2.算术右移指令SAR 语句格式:SAR OPD,1或SAR OPD,CL 功能:将(OPD)向右移动CL指定的次数且最高位保持不变;CF的内容为最后移入位的值。 SAL/SHL SAR
【例】算术右移运算。 MOV BH,0F4H ; (BH)=0F4H,1111 0100B MOV CL, 2 ;(CL)=2 SAR BH, CL ;(BH)=0FDH,(CF)=0 该例语句“SAR BH,CL”实际上完成了(BH)/4→BH的运算,所以,用SAR指令可以实现对有符号数除2n的运算(n为移位次数)。
3.逻辑右移指令SHR 语句格式:SHR OPD,1或SHR OPD,CL 功能:将(OPD)向右移动CL规定的次数,最高位补入相应个数的0,CF的内容为最后移入位的值。
4.循环左移指令ROL 语句格式:ROL OPD,1或ROL LPD,CL 功能:将目的操作数的最高位与最低位连成一个环,将环中的所有位一起向左移动CL规定的次数。CF的内容为最后移入位的值。
语句格式: ROR OPD,1或ROR OPD,CL 功能:将目的操作数的最高位与最低位连成一个环,将环中的所有位一起向右移动CL规定的次数,CF的内容为最后移入位的值。 CF 7
6.带进位的循环左移指令RCL 语句格式: RCL OPD, 1 或 RCL OPD,CL 功能:将目的操作数连同CF标志一起向左循环移动CL规定的次数。
7.带进位的循环右移指令RCR 语句格式:RCR OPD,1 或 RCR OD,CL 功能:将目的操作数连同CF标志一起向右循环移动所规定的次数。
2.6 串操作类指令 串操作指令 : 数据传送类指令每次只能传送一个数据,若要传送大批数据就需要重复编程,这样就浪费了大量的时间和空间。为此8086提供了一组处理主存中连续存放数据串的指令,这就是串操作指令。
MOVS 串传送 CMPS 串比较 SCAS 串扫描 LODS 从串取 STOS 存入串 INS 串输入 OUTS 串输出 与上述基本指令配使用的前缀有: REP 重复 REPE/REPZ 相等/为零则重复 REPNE/REPNZ 不相等/不为零则重复
1.重复前缀指令REP、REPZ、REPNZ (1)REP :REP前缀用在MOVS、STOS 、LODS、INS和OUTS指令前。 格式:REP string primitive 其中string primitive可为MOVS,LODS等指令。 功能: (1)如果(CX)=0,则退出REP,否则往下执行。 (2)(CX)=(CX)-1 (3)执行其后的串指令 (4)重复(1)-(3)
(2)REPZ/REPE:该指令一般用在CMPS、SCAS指令前。 格式:REPE(或REPZ) string primitive 其中string primitive可为CMPS或SCAS指令。 功能: (1)如果(CX)=0或ZF=0时退出,否则往下执行。 (2)(CX)=(CX)-1 (3)执行其后的串指令 (4)重复(1)-(3) 与REP相比,除满足(CX)=0的条件可结束操作外,还增加了ZF=0的条件,也就是说,如果两数相等就可继续比较,如果遇到了两数不相等可提前结束操作。
(3)REPNZ/REPNE :该指令一般用在CMPS、SCAS指令前。 格式:REPE(或REPZ) string primitive 其中string primitive可为CMPS或SCAS指令。 功能: (1)如果(CX)=0或ZF=1时退出,否则往下执行。 (2)(CX)=(CX)-1 (3)执行其后的串指令 (4)重复(1)-(3) 与REP相比,除满足(CX)=0的条件可结束操作外,还增加了ZF=1的条件,也就是说,如果两数不相等就可继续比较,如果遇到了两数相等可提前结束操作。
2.传送指令MOVS 语句格式:① MOVS DST,SRC ② MOVSB——字节串传送 ③ MOVSW——字串传送 其中后两种明确注明是传送字节还是字,第一种格式则应在操作数中表明是字节还是字的操作.例如: MOVS ES:BYTE PTR[DI],DS:[SI] 功能:将以SI为指针的源串中的一个字节(或字)存储单元中的数据传送至以DI为指针的目的地址中去,并自动修改指针,使之指向下一个字节(或字)存储单元。 即:①(DS:[SI])→ES:[DI]。 ② 当DF=0时,(SI)和(DI)增量。 当DF=1时,(SI)和(DI)减量。
③当操作为字节操作时,(SI)、(DI)增减量为1,当操作为字操作时, (SI)、(DI)增减量为2。 ④当该指令与前缀REP联用时,则可将数据段中的整串数据传送到附加段中去,这里源串必须在数据段中,目的串必须在附加段中,但源串允许使用段跨越前缀来修改。在与REP联用时,还必须先把数据串的长度值送到计数寄存器中,以便控制指令结束。因此在执行该指令前,必做如下准备工作: I.把存放在数据段中的源串首地址(如反向传送则应是末地址)放入源变址寄存器中; II.把将要存放数据串的附加段中的目的串首址(反向传送时为末地址)放入目的变址寄存器; Ⅲ.把数据串长度放入计数寄存器; Ⅳ.建立方向标志。
例:在数据段中有一个字符串,其长度为17,要求把它们转送到附加段中的一个缓冲区中。 data segment mess1 db ‘personal computer$’ data ends extra segment mess2 db 17 dup(?) extra ends code segment assume cs:code,ds:data,es:extra … mov ax,data mov ds,ax mov ax,extra mov es,ax … lea si,mess1 lea di,mess2 mov cx,17 cld rep movsb code ends
3.串比较指令CMPS 语句格式:①CMPS SRC,DST ——需指定操作类型字 ②CMPSB——字节串比较 ③CMPSW——字串比较 功能:将SI所指的源串中的一个字节(或字)存储单元中的数据与DI所指的目的串中的一个字节(或字)存储单元中的数据相减,并根据相减的结果设置标志,但结果并不保存。 即:①([SI])-([DI])。 ② 修改串指针,使之指向串中的下一个元素。当DF=0时,(SI)和(DI)增量。当DF=1时,(SI)和(DI)减量。 ③当操作为字节操作时,(SI)、(DI)增减量为1,当操作为字操作时, (SI)、(DI)增减量为2。
4.串搜索指令SCAS 语句格式:① SCAS DST ② SCASB——字节串搜索 ③ SCASW——字串搜索 功能:AL(字节)或AX(字)中的内容与DI所指的目的串中的一个字节(或字)存储单元中的数据相减,根据相减结果设置标志位,结果不保存, 即:① 字节操作:(AL)-([DI]),字操作:(AX)-([DI])。 ② 修改指针使之指向串中的下一个元素。当DF=0时,(DI)增量。当DF=1时,(DI)减量。 ③当操作为字节操作时,(SI)、(DI)增减量为1,当操作为字操作时, (SI)、(DI)增减量为2。
当要求从一个字符串中查找一个指定的字符,可用指令REPNZ SCASB。 以上3,4两条串处理指令和REPE或REPNE相结合,可以用来比较两个数据串,或从一个字符串中查找一个指定的字符。 当要求从一个字符串中查找一个指定的字符,可用指令REPNZ SCASB。 当要求比较两个字符串,找出它们不相区配的位置,则可以使用指令REPE CMPSB。
5.从源串中取数指令LODS 语句格式:① LODS SRC ② LODSB——从字节串中取数 ③ LODSW——从字串中取数 功能:将SI所指的源串中的一个字节(或字)存储单元中的数据取出来送入AL(或AX)中。 即: ① 字节操作:([SI])→AL,字操作:([SI])→AX。 ② 修改指针SI,使它指向串中的下一个元素。当DF=0时,(SI)增量。当DF=1时,(SI)减量。 ③当操作为字节操作时,(SI)、(DI)增减量为1,当操作为字操作时, (SI)、(DI)增减量为2。
6.往目的串中存数指令STOS 语句格式:① STOS DST ② STOSB——往字节串中存数 ③ STOSW——往字串中存数 功能:将AL或AX中的数据送入DI所指的目的串中的字节(或字)存储单元中。 即: ① 字节操作:(AL)→[DI],字操作:(AX)→[DI]。 ② 修改指针DI,使之指向串中的下一个元素。当DF=0时,(DI)增量)。当DF=1时,(DI)减量。 ③当操作为字节操作时,(SI)、(DI)增减量为1,当操作为字操作时, (SI)、(DI)增减量为2。
对串处理指令,需注意: (1)串处理指令在不同的段之间传送或比较数据,如果需要在同一段内处理数据,可以在DS和ES中设置同样的地址,或者在源操作数字段使用段跨越前缀来实现。例如: MOVS [DI],ES:[SI] (2)当使用重复前缀时,(CX)是每次减1的,因此对于字指令来说,预置时设置的值应该是字的个数而不是字节数。
2.7 控制转移类指令 2.7.1 条件转移指令 2.7.2 无条件转移指令 2.7.3 循环指令 2.7.4 子程序调用指令 2.7 控制转移类指令 2.7.1 条件转移指令 2.7.2 无条件转移指令 2.7.3 循环指令 2.7.4 子程序调用指令 2.7.5 中断指令
2.7.1 条件转移指令 1.简单条件转移指令 2.无符号数条件转移指令 3. 有符号数条件转移指令 它们都有通用的语句格式和功能。 2.7.1 条件转移指令 1.简单条件转移指令 2.无符号数条件转移指令 3. 有符号数条件转移指令 它们都有通用的语句格式和功能。 语句格式:[ 标号:] 操作符 短标号 功能:如果条件满足, 则(IP)+位移量→IP。
1.简单条件转移指令
2.无符号数条件转移指令 【例】比较无符号数大小,将较大的数存放AX寄存器。 CMP AX, BX ;(AX)-(BX) JNB NEXT ;若AX>=BX,转移到NEXT XCHG AX,BX ;若AX<BX,交换 NEXT:…
3. 有符号数条件转移指令 【例】比较有符号数大小,将较大的数存放在AX寄存器。 CMP AX,BX ;(AX)-(BX) JNL NEXT ;若AX>=BX,转移到NEXT XCHG AX,BX ;若AX<BX,交换 NEXT:…
2.7.2 无条件转移指令 其中:段内直接短转移:JMP SHORT OPR(IP加8位位移量) 2.7.2 无条件转移指令 其中:段内直接短转移:JMP SHORT OPR(IP加8位位移量) 段内直接近转移:JMP NEAR PTR OPR(IP加16位位移量) 段内间接转移:JMP WORD PTR OPR 段间直接转移:JMP FAR PTR OPR 段间间接远转移:JMP DWORD PTR OPR 执行:(EA)->(IP),(EA+2)->CS
2.7.3 循环指令 1.循环指令LOOP 2.相等/为零循环指令LOOPE 3.不相等/不为零循环指令LOOPNE 2.7.3 循环指令 1.循环指令LOOP 2.相等/为零循环指令LOOPE 3.不相等/不为零循环指令LOOPNE 4.CX为零转移指令JCXZ
1.循环指令LOOP 语句格式: LOOP 短标号 功能:(CX)-1 ≠0,则程序转移(循环);否则,顺序执行。 说明:使用LOOP指令可代替两条指令: DEC CX JNE 短标号 2.相等/为零循环指令LOOPE 语句格式:① LOOPE 短标号 ② LOOPZ 短标号 功能:(CX)-1 ≠0且ZF=1,则程序转移(循环);否则,顺序执行。
3.不相等/不为零循环指令LOOPNE 语句格式:① LOOPNE 短标号 ② LOOPNZ 短标号 功能:(CX)-1≠0且ZF=0,则程序转移(循环);否则,顺序执行。 4.CX为零转移指令JCXZ 语句格式: JCXZ 短标号 功能:(CX)-1≠0,则程序转移(循环);否则,顺序执行。
例:有一串L个字符的字符串存储于首地址为ASCII_STR的存储区中,如要求在字符串中查找“空格”(ASCII码为20H),找到则继续执行,未找到则转到NOT_FOUND去执行。 MOV CX,L MOV SI,-1 MOV AL,20H NEXT:INC SI CMP AL,ASCII_STR[SI] LOOPNE NEXT JNZ NOT_FOUND … NOT_FOUND:
2.7.4 子程序调用指令 子程序结构相当于高级语言中的过程。为便于模块化程序设计,往往把程序中某些具有独立功能的部分编写成独立的程序模块,称为子程序。 1.子程序调用指令CALL (1)段内直接调用 格式:CALL DST 执行操作:PUSH (IP) (IP)<-(IP)+D16 DST给出转向地址,D16为机器指令中的位移量,是转向地址和返回地址之间的差值。
(2)段内间接调用 格式:CALL DST 执行操作:PUSH (IP) (IP)<-(EA) 指令中的DST可使用寄存器寻址方式或任一种存储器寻址方式,由指定的寄存器或存储单元的内容给出转向地址。 (3)段间直接调用 执行操作:PUSH (CS) PUSH (IP) (CS)<-DST指定段地址 (IP)<-DST指定偏移地址
EA是由DST的寻址方式确定的有效地址,可用任一种存储器寻址方式来取得。 2.返回指令RET (4)段间间接调用 格式:CALL DST 执行操作:PUSH (CS) PUSH (IP) (IP)<-(EA) (CS)<-(EA+2) EA是由DST的寻址方式确定的有效地址,可用任一种存储器寻址方式来取得。 2.返回指令RET (1)语句格式:RET ;(IP)<-POP() (2)语句格式:RET EXP; 在完成出栈操作后,还要修改堆栈指针
2.7.5 中断指令 有时系统运行或者程序运行期间在遇到某些特殊情况时,需要计算机自动执行一组专门的例行程序来进行处理,这种情况称为中断,所执行的这组程序称为中断例行程序或中断子程序。 当CPU响应一次中断时,也要把(IP)和(CS)入栈,同时为了全面保存现场信息,以便在中断处理结束时返回现场,还需要把反映现场状态的(FLAGS)入栈,然后才转到中断例行程序去执行。当从中断返回时,要恢复(IP)和(CS),也要恢复(FLAGS)。 中断例行程序的入口地址称为中断向量。
1.中断调用指令INT 语句格式:INT n;n为中断类型,0-255 功能:①(FLAGS)→↓(SP),0→ IF、TF。 ②(CS) →↓(SP),(4*n+2) → CS。 ③(IP) →↓(SP),(4*n) → IP。 2.中断返回指令IRET 语句格式:IRET 功能:①↑(SP)→IP ②↑(SP) →CS ③↑(SP) → FLAGS
2.8 处理机控制类指令 2.8.1 标志位设置指令 2.8.2 CPU状态控制指令
2.8.1 标志位设置指令 1.进位标志操作指令 CLC 进位标志清0指令 CMC 进位位求反指令 STC 进位标志置1指令 2.8.1 标志位设置指令 1.进位标志操作指令 CLC 进位标志清0指令 CMC 进位位求反指令 STC 进位标志置1指令 2.方向标志操作指令 CLD 方向标志清0指令 STD 方向标志置1指令 3.中断标志操作指令 CLI 中断标志清0指令 STI 中断标志置1指令
2.8.2 CPU状态控制指令 1.空操作指令NOP: 该指令不执行任何操作,其机器码占有一个字节单元,在调试程序时往往用这条指令占有一定的存储单元,以便在正式运行时用其他指令取代。 2.总线封锁前缀指令LOCK: 该指令是一种前缀,可与其他指令联合,用来维持总线的锁存信号,直到与其联合的指令执行完为止. 3.暂停指令HLT: 该指令可以使机器暂停工作,使处理机处于停机状态以等待一次外部中断的到来,中断结束后可继续执行下面的程序.
4.交权指令ESC: 这条指令在使用协处理机时,可指定由协处理器执行的指令. 5.等待指令WAIT: 该指令使处理机处于空转状态,它也可以用来等外部中断发生,但中断结束后仍返回WAIT指令继续等待.
本章小结 80x86与数据有关的寻址方式主要有:立即寻址、寄存器寻址、直接寻址、寄存器间接寻址、寄存器相对寻址、基址变址寻址、相对基址变址寻址等。 与转移地址有关的寻址方式主要有段内直接寻址、段内间接寻址、段间直接寻址和段间间接寻址。 80x86的指令系统可分为以下6组: 数据传送指令 串处理指令 算术指令 控制转移指令 逻辑指令 处理机控制指令 返回本章