汇编语言 程序设计
第 3章 指令系统和寻址方式
◆ 汇编指令格式
◆ 寻址方式
◆ 8086指令系统
◆ 80X86及 Pentium扩展指令
汇编语言 程序设计
3.1 汇编指令格式
计算机中的一条指令通常包含两部分:
依据操作数的个数划分,80X86CPU指令
系统中的指令格式最常用的有,双操作数指
令、单操作数指令和无操作数指令。
操作码 操作数
汇编语言 程序设计
1、双操作数指令汇编格式及操作规定
格式,[标号,] 操作符 OPD,OPS [; 注释 ]
操作规定:
( 1) OPD与 OPS应为同种操作类型且类型明确,即同为
字节类型或字类型。
( 2) OPD不能是立即数。
( 3) OPS和 OPD不能同时为存储器操作数,即:或者是
OPS和 OPD中至少有一个为寄存器操作数,或者
是 OPD为存储器操作数,OPS为立即数。
( 4)操作结束后,运算结果存入 OPD中,OPS内容不变。
汇编语言 程序设计
2、单操作数指令汇编格式及操作规定
格式,[标号,] 操作符 OPD [; 注释 ]
操作规定:
( 1) OPD类型必须明确即为字节类型或字类型, 不能
是模糊类型 。
( 2) 操作对象为目的操作数, 操作结束后结果存入
OPD中 。
( 3) OPD不能是立即数, 只能是寄存器操作数或存储
器操作数 。
汇编语言 程序设计
3、无操作数指令汇编格式及操作规定
格式,[标号,] 操作符 [; 注释 ]
操作规定,指令中只有操作码,不含操作数,这
种指令有两种可能:
( 1)无需任何操作数。如停机指令、空操作指令等。
( 2) 所需操作数是隐含指定的, 操作时取固定操作
数进行操作 。
返回
汇编语言 程序设计
3.2 寻址方式
寻找指令中所需操作数存放地址的方式或程序
转移时寻找转移地址的方式称为寻址方式, 因而寻
址方式分为两大类, 一类是数据寻址方式, 另一类
是转移地址寻址方式 。
由于 80X86指令涉及四种操作数:立即操作数、
寄存器操作数、存储器操作数和隐含操作数,因此,
数据寻址方式又可对应四种寻址方式,即:立即寻
址、寄存器寻址、存储器寻址和固定寻址。
汇编语言 程序设计
1、立即寻址
此寻址方式所提供的操作数直接包含在指令中,
它紧跟在指令操作码后面,存放在存储器代码段中。
立即操作数可以是 8位,也可以是 16位。
汇编格式,n (n是用 8位或 16位二进制补码表示的有符号数 )
【例 3.1】 MOV AX,1234H
立即寻址方式用来表示常数, 它常用于给寄存器
赋初值 。 需要强调的是, 立即寻址只能用于源操作
数, 不能用于目的操作数 。
汇编语言 程序设计
2、寄存器寻址
此寻址方式的操作数直接存放在由指令指明的寄存器中。
在汇编指令中直接书写寄存器名,如 16位寄存器操作数可以
是 AX,BX,CX,DX,SI,DI,BP,SP,DS,ES,SS,CS等; 8
位寄存器操作数可以是 AH,AL,BH,BL,CH,CL,DH,DL。
汇编格式,R ( 其中 R表示寄存器名 )
此寻址方式由于存取操作数直接从 CPU内部寄存器中获得,
不需访问存储器, 因而指令执行的速度快 。
寄存器寻址既可用于源操作数, 又可用于目的操作数, 应用
频率高 。
【 例 3.2】 MOV DS,AX
ADD CL,AH
汇编语言 程序设计
3、存储器寻址
存储器寻址方式的操作数都是存放在存储器中,一般是
数据段、附加段、堆栈段中的存储单元。指令中给出的是存
储单元的地址或产生存储单元地址的表达式。在汇编语言源
程序中,存储单元地址是采用逻辑地址的形式表示的,即:
段首址:段内偏移地址。段首址存放在某个段寄存器中,段
内偏移地址是指存放操作数的存储单元与段起始地址(段首
址)之间的距离(字节数),又可称为, 有效地址,,记作
EA。 有效地址 EA是由 3个地址分量的某种组合求得,这 3个地
址分量是:位移量,基址,变址 。
这 3个地址分量的不同组合, 使形成有效地址 EA的方法不同,
相应有以下 5种不同的存储器操作数寻址方式 。
汇编语言 程序设计
( 1)直接寻址
直接寻址是最简单的存储器寻址,这种寻址,操作数的有效地址 EA
由指令直接给出。它主要用于存取简单变量。
汇编格式,( a) [ 常量 ] ( b) 变量 或 含有变量的表达式
【 例 3.3】 MOV AL,[ 1000H ] MOV VAL,BX
对使用直接寻址方式需说明以下几点:
● 操作数默认存放在数据段中, 段寄存器 DS在指令格式无须指定 。
● 若操作数在代码段、堆栈段或附加段中,则在指令格式中必须指定相
应的段寄存器名。在操作数地址之前使用前缀指出段寄存器名,这种前缀
称为段超越前缀。
● 指令中操作数的 EA即可以是一个数字, 也可以是一个符号地址 。 当 EA
是一个数字时, 一定要注意立即寻址方式与直接寻址方式的区别 。
● 直接寻址方式适合于处理存储器的单个存储单元。
汇编语言 程序设计
( 2)寄存器间接寻址
此寻址方式中,操作数的有效地址 EA存放在 SI,DI,BX或 BP四个寄
存器之一中,即,EA=( BX) 或( BP) 或( SI) 或( DI)。
汇编格式,[ R ] ( 其中 R是寄存器 SI,DI,BX,BP之一 )
SI,DI,BX,BP在这里叫间址寄存器 。 若用 BX,SI或 DI间址寻址时, 则
操作数默认在数据段中, 且用 DS内容作为段首址, 操作数的物理地址为:
( BX)
PA= ( DS) × 16+ ( SI)
( DI)
【 例 3.4】 MOV DL,[ BX ]
若指令中使用 BP间址寻址时, 则操作数默认在堆栈段中, 且用 SS的内容
作为段首址, 操作数的物理地址为,PA= ( SS) × 16 + ( BP) 。
【 例 3.5】 MOV [ BP ], AX
汇编语言 程序设计
( 3)基址寻址
此寻址操作数的有效地址 EA是指令中指定的基址寄存器的内容与指令
中给出的位移量之和,即,EA=( BX)+ 位移量
( BP)
汇编格式,( a) Disp [ BX ] 或 Disp [ BP ]
( b) [ BX + Disp ] 或 [ BP + Disp ]
该寻址方式中若以 BX作为基址寄存器, 则操作数默认在数据段中;若以
BP作为基址寄存器, 则操作数默认在堆栈段中, 因而操作数的物理地址为:
PA= ( DS) × 16+ ( BX) + Disp
( SS) × 16+ ( BP) + Disp
若操作数不在默认段中, 则应使用段超越前缀明确指定 。
【 例 3.6】 MOV AX,[ BX+7CH ]
MOV AX,[ BP+COUNT ]
汇编语言 程序设计
( 4)变址寻址
变址寻址与基址寻址类似,其操作数的有效地址 EA是变址寄存器的
内容与位移量之和,即,EA=( SI)+ 位移量
( DI)
汇编格式,( a) Disp [ SI ] 或 Disp [ DI ]
( b) [ SI + Disp ] 或 [ DI + Disp ]
该寻址方式默认段是数据段, 因而操作数的物理地址为:
PA= ( DS) × 16+ ( SI) + Disp
( DI)
若操作数不在默认段中, 则应使用段超越前缀明确指定 。
【 例 3.7】 MOV DX,COUNT [ DI ]
MOV ES,3480H [ SI ],AX
汇编语言 程序设计
( 5)基址加变址寻址
此寻址方式中操作数的有效地址 EA是指令中的基址寄存器的内容、变址
寄存器的内容、位移量三个地址分量之和,即,EA=( BX)+( SI)+ 位移量
( BP) + ( DI)
汇编格式,( a) Disp [ BX 或 BP+ SI或 DI ]
( b) [ BX或 BP + SI或 DI+ Disp ]
该寻址方式中若基址寄存器采用 BX,则操作数默认在数据段中;
若基址寄存器采用 BP,则操作数默认在堆栈段中, 因而操作数的物理
地址为,PA= ( DS) × 16+ ( BX) + ( SI) + Disp
( DI)
( SS) × 16+ ( BP) + ( SI) + Disp
( DI)
汇编语言 程序设计
4,80X86扩充的寻址方式
上述讲的 8种 8086CPU的 16位寻址方式同样适用于 80X86CPU32位寻
址方式,在这 8种 32位寻址方式中,只不过是立即数、寄存器、存储器
有效地址扩充到 32位,而且任意 32位通用寄存器( EAX,EBX,ECX、
EDX,ESI,EDI,EBP,ESP) 均可作为间址寄存器、基址寄存器或变址
寄存器(变址寄存器 ESP除外)。
除此之外, 80X86CPU32位寻址方式还提供了两种仅适用于 32位 CPU的寻
址方式, 即:比例变址寻址和基址加比例变址寻址, 这两种寻址方式
均属于存储器寻址方式中的一种, 其操作数存放在存储器中 。
(1) 比例变址寻址
由变址寄存器的内容乘以比例因子再加上位移量而得到操作数有效
地址 EA的寻址方式称为比例变址寻址,
即,EA= [ 变址寄存器 ]× 比例因子+位移量 。
汇编格式,[ 变址寄存器 ]× 比例因子+位移量
汇编语言 程序设计
其中:变址寄存器是 EAX,EBX,ECX,EDX,ESI,EDI,EBP之一;
比例因子可以是 1,2,4,8;位移量可以是 0位,8位或 32位。
此寻址方式操作数默认在数据段, 若操作数不在默认的数据段中时,
则应使用段超越前缀明确指定 。
例如,MOV EAX,COUNT[ EDI*2 ]; COUNT是位移量, 2是比例因子
其中乘以比例因子的操作是在 CPU内部由硬件完成。
(2) 基址加比例变址寻址
由变址寄存器的内容乘以比例因子加上基址寄存器的内容再加上位
移量而得到操作数有效地址 EA的寻址方式称为基址加比例变址寻址 。
即,EA= [ 变址寄存器 ]× 比例因子+ [ 基址寄存器 ]+位移量 。
若基址寄存器采用 EBP,ESP时, 则操作数默认在 SS段中, 若基址寄存
器采用除 EBP,ESP以外的其他寄存器时, 则操作数默认在 DS段中 。 若
操作数不在相应的默认段中时, 则应使用段超越前缀明确指定 。
例如,MOV [ ESI*4+ EDX ],EAX ; 目的操作数在 DS段中
汇编语言 程序设计
5、转移地址寻址方式
转移地址寻址方式确定的是转移指令或调用指令转移后的地址。
可将转移地址寻址方式分为四种:段内直接寻址, 段内间接寻址, 段
间直接寻址和段间间接寻址 。
(1) 段内直接寻址
段内直接寻址又称为段内相对寻址 。 在此寻址方式下, 转移后的指令
与转移指令本身在同一代码段中 。 转移后指令的有效地址 EA= ( IP) +
位移量 。 若位移量为正, 则相对本指令向后转移, 若为负, 则相对本指
令向前转移 。
汇编格式,( a) SHORT 标号
( b) NEAR PTR 标号 其中:标号是符号地址。
例如,JMP SHORT NEXT
JMP NEAR PTR L1
汇编语言 程序设计
(2) 段内间接寻址
转移有效地址是一个字寄存器或是一个字存储单元的内容。这个字
寄存器或字存储单元的内容可以用数据寻址方式中的寄存器寻址或存储
器寻址获得,所得到的转移有效地址用来取代当前的 IP值实现段内间接
寻址。这种寻址方式只适用于 JMP和 CALL指令。
汇编格式,( a) R ( R为 16位通用寄存器 )
(b) 存储器寻址方式之一
若 JMP和 CALL指令采用格式 ( a), 即寄存器寻址, 则指令中指定的寄
存器内容便是转移地址, 当 CPU执行 JMP或 CALL指令时, 就将该寄存器的
内容装入 IP。
若 JMP和 CALL指令采用格式 ( b) 中的一种存储器寻址时, 则转移地址便
是字存储单元的内容, 当 CPU执行 JMP或 CALL指令时, 就将该字存储单元
的内容装入 IP。
汇编语言 程序设计
(3) 段间直接寻址
此寻址方式,转移后的指令与转移指令本身不在同一代码段中。转
移地址(即 IP和 CS值)由指令直接给出。
汇编格式,FAR PTR 标号
它只适用于 JMP和 CALL指令 。 例如,JMP L2( 标号 L2与本 JMP指令不
在同一代码段中 ) 。
( 4) 段间间接寻址
此寻址方式也只适用于 JMP和 CALL指令 。 转移后的指令与转移指令本
身不在同一代码段中 。 转移地址 ( 即 IP和 CS值 ) 由采用存储器寻址方式
之一确定的双字存储单元内容间接给出 。
汇编格式,存储器寻址方式之一
执行 JMP或 CALL指令时, 根据指令中指定的某种存储器寻址方式找到
内存的一个双字 ( 32位 ), 将高字内容装入 CS,将低字内容装入 IP,实
现段间转移 。
例如,JMP DWORD PTR [BX ] 返回
汇编语言 程序设计
3.3 8086指令系统
8086指令系统按功能可分为六大类:
( 1) 数据传送类指令 ( 2) 算术运算类指令
( 3) 位操作指令 ( 4) 串操作指令
( 5) 控制转移指令 ( 6) 处理器控制指令
8086指令按操作数个数可划分为三种类型:
( 1) 双操作数指令 ( 2) 单操作数指令 ( 3) 无操作数指令
学习汇编指令应从以下几方面着重理解掌握:
( 1) 学习指令格式;
( 2) 掌握指令中操作数的寻址方式及寻址方式的搭配规则;
( 3) 掌握指令的功能及指令执行后对条件码的影响;
( 4) 学习如何正确运用指令 。
汇编语言 程序设计
一,数据传送指令
1,通用数据传送指令
( 1) 传送指令 MOV
格式,MOV OPD,OPS
功能:把源操作数传送到目的操作数 。 即,OPD← ( OPS)
说明:
① 源操作数和目的操作数的操作类型必须明确且一致;当指令中只有一
个操作数的类型明确时, 另一个操作数被视为同一类型;当两操作数类型
均不明确时, 必须用, BYTE PTR”或, WORD PTR”将一个存储器操作数定
义为字节或字类型 。
② 指令执行后, 源操作数内容不变 。
③ 指令执行后, 对标志寄存器各位无影响 。
④ 源操作数可以是通用寄存器, 段寄存器, 存储器和立即数;目的操作
数也可以是通用寄存器, 段寄存器, 存储器, 但立即数, CS段寄存器不能
作为目的操作数 。 源操作数和目的操作数不能同时为存储器操作数 。
汇编语言 程序设计
用一条 MOV指令能实现:
(a) 立即数传送到通用寄存器或存储单元
如 MOV DL,’a’, MOV AX,1FA4H
(b) 寄存器之间的传送
如 MOV AX,BX, MOV AL,DH, MOV DS,AX
(c) 寄存器与存储单元之间的传送
如 MOV DL,BUFBYTE
MOV WORD PTR [BX+SI],AX
由于 MOV指令中只允许一个操作数在存储器中, 因此用一条 MOV指令无
法完成两个存储单元之间的数据传送, 但可以用二条指令来实现 。
【 例 3.9】 把 BUFWORD1字单元内容传送到 BUFWORD2字单元中, 可用以
下指令完成,MOV AX,BUFWORD1
MOV BUFWORD2,AX
汇编语言 程序设计
(2) 交换指令 XCHG
格式,XCHG OPD,OPS
功能:源操作数和目的操作数的内容相互交换 。
即,( OPD) ←→ ( OPS)
说明:该指令与 MOV指令相似, 但在功能上有两点区别,
其一, 该指令不允许使用立即数和段寄存器作为操作数;
其二, 该指令改变源操作数的内容 。
( 3) 查表转换指令 XLAT
格式,XLAT 或 XLAT OPS
功能:将 ( BX) 为首址 ( AL) 为位移量的字节存储单元中的数据
传送到 AL中 。 即,AL←([BX + AL])字节
汇编语言 程序设计
2,地址传送指令
地址传送指令主要用于将存储器操作数地址 ( 偏移地址,
段地址 ) 传送给指定的寄存器 。 它包括 3条指令,LEA,LDS和
LES。
( 1) 传送有效地址指令 LEA
格式,LEA REG16,OPS
功能:将源操作数的有效地址 EA传送给目的操作数指定的 16
位通用寄存器 。
说明:
① 源操作数必须是存储器操作数, 即 OPS采用存储器寻址;
目的操作数必须是一个 16位通用寄存器 。
② 本指令对标志位无影响 。
③ 该指令通常用来建立内存储器的寄存器指针 。
汇编语言 程序设计
( 2) 传送偏移地址及数据段首址指令 LDS
格式,LDS REG16,OPS
功能:将由源操作数确定的双字存储单元的内容传送给 DS及目的操
作数指定的 16位通用寄存器中, 其中高字单元的内容送给
DS,低字单元的内容送给 REG16。
说明,① 源操作数必须是双字存储器操作数, 即,OPS采用存储器
寻址, 寻找到相继 4个字节的存储单元, 低字单元中存放 偏
移地址, 高字单元中存放段首地址;目的操作数必须是 一
个 16位通用寄存器, 通常特定为 SI。
② 本指令不影响标志位 。
( 3) 传送偏移地址及附加段首址指令 LES
格式,LES REG16,OPS
功能:将由源操作数确定的双字存储单元的内容传送给 ES及目的操
作数指定的 16位通用寄存器中, 其中高字单元的内容送给
ES,低字单元的内容送给 REG16。
说明:同 LDS指令 。
汇编语言 程序设计
3,标志位传送指令
标志位传送指令有 4条指令, 即,LAHF,SAHF,PUSHF和 POPF。
( 1) 标志送 AH指令 LAHF
格式,LAHF
功能:将标志寄存器低 8位的内容送入 AH寄存器 。
即,AH←(FLAGS) 7-0,该指令的执行不影响标志位 。
( 2) AH标志送指令 SAHF
格式,SAHF
功能:将 AH寄存器的内容送入标志寄存器低 8位, 高 8位保持不变 。
该指令用于设置或恢复 SF,ZF,AF,PF,CF五个标志位,
该指令的执行只影响标志寄存器的低 8位, 对高 8位 ( 即 OF、
DF,IF,TF) 标志位无影响 。
从指令的功能上可看出, SAHF和 LAHF为互逆过程 。
汇编语言 程序设计
( 3) 标志进栈指令 PUSHF
格式,PUSHF
功能:将标志寄存器的内容压入堆栈 。
( 4) 标志出栈指令 POPF
格式,POPF
功能:将栈顶字单元内容弹出到标志寄存器中 。
该指令的执行影响标志位 。
PUSHF和 POPF互为逆过程 。
标志位传送指令中 SAHF和 POPF指令将直接影响标志寄存器的内
容 。 利用这一特性, 可以方便地改变标志寄存器中指定位的状态,
数据传送类指令还包括输入 / 输出专用指令, 在 PC机里所有 I/O
端口与 CPU之间的通信都由 IN和 OUT指令实现, 由 IN指令完成从 I/O
端口到 CPU的信息传送, 由 OUT指令完成从 CPU到 I/O端口的信息传送
。
汇编语言 程序设计
二, 算术运算指令
算术运算指令用来执行加, 减, 乘, 除四则运算 。 它包括无符号数, 有符
号数的二进制算术运算指令和十进制算术运算调整指令 。
1,二进制数算术运算指令
( 1) 加法运算指令
加法运算指令包括 ADD,ADC的 INC三条指令 。
① 加法指令 ADD
格式,ADD OPD,OPS
功能:将目的操作数与源操作数相加, 结果存入目的地址中, 而源
操作数不变 。 即,OPD← ( OPD) + ( OPS) 。
说明:该指令的源操作数或在通用寄存器或在存储单元中, 也可以是立
即数, 而目的操作数只能在通用寄存器或存储单元中, 不能是立即数,
且两操作数不能同时为存储器操作数;操作数可以是字节或字, 且两操
作数的类型明确并一致 。 该指令相加后, 根据得到的结果设置标志寄存
器的 OF,SF,ZF,CF,AF和 PF标志位 。
ADD指令执行后对标志位的影响及作用如下, 这里我们只重点说明 OF、
CF,SF和 ZF四个标志位 。
汇编语言 程序设计
OF,当两个有符号数相加时, 若两个操作数的符号相同, 而结
果的符号与之相反, 则 OF= 1,否则, 其余情况 OF= 0。
当 OF= 1时, 说明两个有符号数相加产生了溢出, 即和的
值超出了有符号数的有效范围 。 在把操作数视为有符号数
时, 可通过该标志了解加法结果是否正确 。
CF,运算过程中当最高位产生进位时, 则 CF= 1,否则, CF= 0。
当 CF= 1时, 说明运算结果超出了无符号数的表示范围 。
在把操作数视为无符号数时, 可通过该标志了解加法结果
是否正确 。
SF,运算结果的最高位为 1,则 SF= 1,否则, SF= 0。
ZF,运算结果为零时, 则 ZF= 1; 否则, ZF= 0。
汇编语言 程序设计
② 带进位加法指令 ADC
格式,ADC OPD,OPS
功能:与 ADD指令基本相同, 惟一区别是将该指令执行前的 CF值
加至目的操作数中 。 即,OPD← ( OPD) + ( OPS) + CF
说明:该指令与 ADD指令在功能上及结果对标志位影响上基本相
同 。 该指令主要用于多字节的加法运算 。
③ 加 1指令 INC
格式,INC OPD
功能:将目的操作数加 1后送回目的地址中, 并根据执行结果设
置标志位 OF,SF,ZF,AF,PF,但不影响 CF位 。
说明:该指令的操作数可以是字或字节且类型必须明确 。 其操作
数只能在通用寄存器或存储单元中, 不能是立即数 。 该指
令执行后对 OF,SF,ZF,AF,PF标志位的影响与 ADD指令
相同 。
INC主要用于计数器的计数或修改地址指针 。
汇编语言 程序设计
( 2) 减法运算指令
减法运算指令包括 SUB,SBB,DEC,NEG和 CMP五条指令 。
① 减法指令 SUB
格式,SUB OPD,OPS
功能:目的操作数减去源操作数, 其差值存入目的地址, 源操作
数不变, 即,OPD← ( OPD) - ( OPS) 。 并按相减的结果设
置标志位 OF,CF,SF,ZF,AF和 PF。
说明:该指令的源操作数和目的操作数可以在通用寄存器或存储
单元中, 但两者不能同时在存储器中, 立即数可作为源操作数, 而不
能作为目的操作数 。 两操作数可以是字节或字, 且类型明确一致 。
SUB指令执行后对标志位的影响与 ADD指令类似, 下面仅说明 CF和
OF两位的设置情况及作用:
OF:当两个有符号数相减时, 若两个操作数的符号相反, 而结果的
符号与减数相同, 则 OF= 1,否则, 其余情况 OF= 0。
OF= 1时, 说明有符号数减法溢出, 结果是错误的 。 OF位可用来
判断有符号数相减, 结果是否正确 。
CF:当两无符号数相减时, 若减数大于被减数, 则此时有借位,
CF= 1,否则 CF= 0,CF值反映了无符号数相减时是否有借位 。
汇编语言 程序设计
② 带借位减法指令 SBB
格式,SBB OPD,OPS
功能,SBB与 SUB指令基本相同, 惟一区别是:目的操作数除减去源
操作数外, 还要减去该指令执行前的 CF值 。
即,OPD← ( OPD) - ( OPS) - CF。 并按相减的结果设置标志
位 OF,CF,SF,ZF,AF和 PF。
说明:该指令与 SUB指令在功能上及结果对标志位的影响上基本相同 。
该指令在使用上类似于 ADC指令, 主要用于多字节减法运算 。
SUB和 SBB指令配合可以实现多倍精度数减法运算 。
③ 减 1指令 DEC
格式,DEC OPD
功能:将目的操作数减 1后送入目的地址中, 并根据执行结果设置标志
位 OF,SF,ZF,AF和 PF,但不影响 CF位 。 即 OPD← ( OPD) - 1。
说明:该指令的操作数可以是字节或字且类型必须明确;其操作数只
能在通用寄存器或存储单元中, 不能是立即数 。 该指令执行后
对 OF,SF,ZF,AF,PF的影响与 SUB指令相同 。
汇编语言 程序设计
④ 求负数指令 NEG
格式,NEG OPD
功能:用零减去目的操作数, 相减结果送回目的地址中 。
即,OPD← 0- ( OPD) =- ( OPD)
即求目的操作数的相反数 。
说明:
( a) 该指令是单操作数指令, OPD的用法与前面讲过的单操作数指
令,如 INC,DEC) 中的目的操作数相同 。
( b) NEG指令是对有符号数进行操作的, 由于机器中有符号数是用
补码表示的, 求一个操作数的负数, 就是求其补码, 因此,
NEG又叫求补指令, 即,OPD← ( OPD) + 1。
( c) 该指令执行后影响标志位 CF,OF,SF,ZF,AF和 PF。 其中:
OF,当字节操作数为- 128( 80H), 字操作数为- 32768
( 8000H), 执行 NEG指令后, 操作数无变化, 但溢出标志
位 OF置 1,其余情况 OF置 0。
CF,当操作数为零时, 求负数的结果仍为零, CF= 0,
其余情况 CF= 1
汇编语言 程序设计
⑤ 比较指令 CMP
格式,CMP OPD,OPS
功能:目的操作数减去源操作数, 结果只影响标志位, 不送入目的地址
即,( OPD) - ( OPS) 。
说明,CMP指令与 SUB指令一样执行减法操作, 但它不保存差值结果,
OPD和 OPS在操作前后值不变 。 CMP指令功能上, 使用方法上, 对
标志位的影响上均与 SUB指令基本相同 。
CMP指令常用于比较两个操作数的大小 。 执行 CMP指令后, 根据标志位
的设置情况判断两个数的大小关系 。
若两无符号数比较时:当 ZF= 0时, 则 OPD= OPS;
否则:当 CF= 0时, 则 OPD> OPS;
当 CF= 1时, 则 OPD< OPS。
若两有符号数比较时:当 ZF= 0时, 则 OPD= OPS;
否则:当 OF= SF时, 则 OPD> OPS;
当 OF≠SF 时, 则 OPD< OPS。
CMP指令后面常跟着条件转移指令, 根据比较结果产生不同的分支 。
汇编语言 程序设计
( 3) 乘法运算指令
乘法指令用于实现两个二进制操作数的乘法运算, 乘法指令区别无符号
数和有符号数, 所以它提供了两条指令,MUL和 IMUL。
① 无符号数乘法指令 MUL
格式,MUL OPS
功能:实现两个无符号数相乘 。
字节乘:当 OPS为字节操作数时, 将 ( AL) 乘以 ( OPS),
得到字乘积送入 AX中, 即,AX← ( AL) × ( OPS) 。
字乘,当 OPS为字操作数时, 将 ( AX) 乘以 ( OPS), 得到双
字乘积, 高字部分送入 DX中, 低字部分送入 AX中 。
即,DX,AX← ( AX) × ( OPS) 。
说明:
( a) MUL指令有两种操作类型, 即字节乘和字乘, MUL操作类型取决于
OPS的类型, OPS指定乘数, 它可以是字节或字, 但类型必须明确, 乘数可
以在通用寄存器或存储器中, 但不能是立即数 。
( b) MUL指令只影响 OF和 CF位 。
汇编语言 程序设计
若乘积的高一半 ( 即字节相乘时乘积中的 ( AH), 字相乘时乘积
中的 ( DX)) 为 0,则 OF= CF= 0,否则 OF= CF= 1。 MUL指令对其它标
志位不确定 。 当 CF= OF= 1时, 说明 AH或 DX中有乘积的有效数字, CF
= OF= 0时, 说明 AH或 DX中无乘积的有效数字, 也就是说字节乘以字
节积为字节或字乘以字积为字 。 编程时我们可以利用 OF和 CF位的设置
情况检查字节乘时乘积的结果是字节还是字, 字乘时乘积的结果是字
还是双字 。
② 有符号数乘法指令 IMUL
格式,IMUL OPS
功能:实现了两个有符号数相乘 。 其操作方法与 MUL指令相同 。
说明,IMUL指令也只影响 OF和 CF位, 对其它标志位不确定 。 若乘积
的高一半 ( 即 AH或 DX) 是低一半 ( 即 AL或 AX) 的符号扩展,
则 OF= CF= 0,否则, OF= CF= 1。 当 OF= CF= 1亦标志着 AH
或
DX中放有乘积的有效值, 即标志着 ( AH) 和 ( DX) 不是对应
的低半部分的符号扩展 。
汇编语言 程序设计
( 4) 除法运算指令
除法指令用于实现两个二进制操作数的除法运算, 包括无符号
数除法指令 DIV和有符号数除法指令 IDIV。
① 无符号数除法指令 DIV
格式,DIV OPS
功能:实现两无符号数除法运算, 商和余数均为无符号数 。
字节除:当 OPS为字节操作数时, 则以 ( AX) 为被除数, OPS为
除数, 将 ( AX) 除以 ( OPS), 得到的商送入 AL中, 余
数送入 AH中 。 即,( AX) /( OPS) → AL( 商 )
AH( 余数 )
字除, 当 OPS为字操作数时, 则以 ( DX,AX) 为被除数, OPS为
除数, 将 ( DX,AX) 除以 ( OPS), 得到的商送入 AX中
,
余数送入 DX中 。 即,( DX,AX) /( OPS) → AX( 商 )
DX( 余数
)
汇编语言 程序设计
说明:
( a) DIV指令有两种操作类型, 即字节除和字除, 其操
作类型取决于 OPS的类型, OPS指定除数, 它的类型必须明确
,它可以在通用寄存器或存储器中, 但不能是立即数 。 DIV
指令的被除数, 商和余数均采用隐含寻址方式, 当字节除时
,被除数隐含在 AX中, 商固定存入 AL中, 余数固定存入 AH中;当字除时, 被除数隐含在 DX,AX中, 商固定存入 AX中, 余
数固定存入 DX中 。
( b) DIV指令执行后, 标志寄存器中各标志位不确定,
但商可产生溢出 。 一般情况下, 当被除数的高一半 ( 即字节
除时为 ( AH), 字除时为 ( DX)) 大于除数时, 商就会产生
溢出 。 当 OPS为字节操作数时, 商的范围为 0- 255( 0FFH); 当 OPS为字操作数时, 商的范围为 0- 65535( 0FFFFH) 。
若商超出此范围, 则产生 0号中断 ( 除法出错中断 ), 转入
除法出错中断处理 。
汇编语言 程序设计
② 有符号数除法指令 IDIV
格式,IDIV OPS
功能:实现两有符号数除法运算, 该指令中的操作数, 商及余数均为
有符号数且用补码表示, 除此之外, 其余操作与 DIV完全相同 。
说明,( a) IDIV指令商的符号由被除数符号与除数符号异或运算而
得到, 余数的符号规定与被除数的符号相同 。
( b) 有符号数除法的商中, 最大的正数商是+ 127( 7FH) 或+ 32767
( 7FFFH), 最小的负数商是- 127( 81H) 或- 32767( 8001H) 。
当商超出此范围, 指令产生了溢出 。 一般情况下, 当被除数高一
半 ( AH或 DX) 的绝对值大于除数的绝对值时, 则可判断 IDIV指令
操作结果产生了溢出, 即产生 0号中断 。
③ 字节转换成字指令 CBW
格式,CBW
功能:将 ( AL) 的符号位扩展到 AH中 。
④ 字转换成双字指令 CWD
格式,CWD
功能:将 ( AX) 的符号位扩展到 DX中 。
汇编语言 程序设计
2,十进制算术运算调整指令
十进制算术运算调整指令又称为 BCD码调整指令 。 当用计算机进行十
进制算术运算时, 可以先将操作数作十 → 二进制转换, 然后作二进制数算
术运算, 再将结果作二 → 十进制转换 。 为了方便十进制数的运算, 8086系
统提供了一组十进制算术运算调整指令, 用于将运算后的二进制数调整为
BCD码 。 该类指令分为压缩 BCD码调整指令和非压缩 BCD码调整指令 。
注意:十进制调整指令不能单独使用, 必须与加, 减, 乘, 除二进制指
令配合使用才能进行十进制调整, 十进制调整指令形式上均为无操作数指
令, 其操作对象隐含在 AX中 。
( 1) 非压缩 BCD码调整指令
① 非压缩 BCD码加法调整指令 AAA。
格式,AAA
功能:将 AL中的和调整为非压缩 BCD码并送回 AL。 具体调整方法如下:
若二进制相加后 ( 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不确定 。
说明:在使用 AAA指令前, 必须执行 ADD,ADC或 INC指令把非压缩 BCD相
加, 且把和存放在 AL中 。
汇编语言 程序设计
② 非压缩 BCD码减法调整指令 AAS。
格式,AAS
功能:将 AL中的差调整为非压缩 BCD码并送回 AL,向高位的借位在 AH和
CF中 。 具体调整方法如下:
若二进制相减后 ( 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不确定 。
说明:在使用 AAS指令前, 必须执行 SUB,SBB或 DEC指令把非压缩 BCD相
减, 且把差存放在 AL中 。
③ 非压缩 BCD码乘法调整指令 AAM。
格式,AAM
功能:将 AL中的积调整为非压缩 BCD码并送回 AX。 具体调整方法是:
把 AL寄存器的内容除以 0AH,并把商放在 AH寄存器中, 余数放
在 AL寄存器中 。
④ 非压缩 BCD码除法调整指令 AAD。
格式, AAD
功能:除法运算前, 先调整被除数 AX内容,
使,AL← ( AH) * 0AH +( AL),AH← 0
汇编语言 程序设计
( 2) 压缩 BCD码调整指令
① 压缩 BCD码加法调整指令 DAA。
格式,DAA
功能:将 AL中的和调整为压缩 BCD码并送回 AL。 本指令执行之前必须先
执行 ADD或 ADC指令, 把两个压缩 BCD码相加, 且和存放在 AL寄存
器中 。 具体调整方法是:
若 ( AL) 的低 4位大于 9或 AF=1,则,AL← ( AL) + 06H,并使 AF=1;
若 ( AL) 的高 4位大于 9或 CF=1,则,AL← ( AL) + 60H,并使 CF=1;
其余情况 AL内容不变 。
说明,DAA指令影响 CF,ZF,SF,AF和 PF,对 OF无定义 。
② 压缩 BCD码减法调整指令 DAS。
格式,DAS
功能:将 AL中的差调整为压缩 BCD码并送回 AL。 本指令执行之前必须先
执行 SUB或 SBB指令, 把两个压缩 BCD码相减, 且差存放在 AL寄存
器中 。 具体调整方法是:
若 ( AL) 的低 4位大于 9或 AF=1,则,AL← ( AL) - 06H,并使 AF=1;
若 ( AL) 的高 4位大于 9或 CF=1,则,AL← ( AL) - 60H,并使 CF=1;
其余情况 AL内容不变 。
说明,DAS指令影响 CF,ZF,SF,AF和 PF,对 OF无定义 。
汇编语言 程序设计
三, 位操作指令
8086提供的位操作指令包括逻辑运算指令和移位指令, 这类指令可直
接对寄存器或存储器中的位进行操作 。
1,逻辑运算指令
逻辑运算指令包括,AND指令, OR指令, XOR指令, TEST指令和 NOT指
令, 其中前四种指令是双操作数指令, 符合双操作数指令的一般规律,
这四条指令执行后将使 CF和 OF位为 0,AF位不确定, 而 SF,ZF和 PF位则根
据运算结果设置; NOT指令是单操作数指令, 符合单操作数指令的一般规
律, 它的执行不影响标志位 。
( 1) 逻辑与指令
格式,AND OPD,OPS
功能:将目的操作数与源操作数按位相与, 结果送目的操作数 。
即,OPD← ( OPD) ∧ ( OPS) 。
说明,①, 与, 的运算原则是,1∧ 1=1,0∧ 1=0,1∧ 0=0,0∧ 0=0。
② AND指令常用于,
(a)使一个操作数中的若干位保持不变, 而若干位清为 0的场合 。
( b) 某一操作数, 自己和自己相, 与,, 操作数不变, 但可以使
进
位标志 CF清 0。
汇编语言 程序设计
( 2) 逻辑或指令
格式,OR OPD,OPS
功能:将目的操作数与源操作数按位相或, 结果送目的操作数 。
即,OPD← ( OPD) ∨ ( OPS) 。
说明:
①, 或, 操作的运算原则是,1∨ 1=1,0∨ 1=1,1∨ 0=1,0∨ 0=0
。
② OR指令常用于:
(a) 使一个操作数中的若干位保持不变, 而另外若干位置 1的
场合 。 这时, 要保持不变的这些位与, 0” 相或;而要置 1
的这些位与, 1” 相或 。
(b) 某一操作数, 自己和自己相, 或,, 操作数不变, 但可以
使进位标志 CF清 0。
( 3) 逻辑异或指令
格式,XOR OPD,OPS
功能:将目的操作数与源操作数按位相异或, 结果送目的操作数 。
即,OPD← ( OPD) ⊕ ( OPS) 。
汇编语言 程序设计
说明:
①, 异或, 操作的运算原则是,1⊕ 1=0,0⊕ 0=0,0⊕ 1=1,1⊕ 0=1。
② XOR指令常用于:
(a) 使一个操作数中的若干位保持不变, 而另外若干位取反的场
合 。 这时, 要保持不变的这些位与, 0” 相异或;而要取反的
那些位与, 1” 相异或 。
(b) 使某一操作数清 0。 由于一个操作数自身做, 异或, 时, 每一
位都相同,, 异或, 结果必为 0,且使进位标志也为 0。 因此这
是使操作数的初值置 0的常用的有效的方法 。
如指令 XOR AX,AX使 AX清 0。
(c) 测试某一操作数是否与另一确定的操作数相等 。 这种操作在
检查地址是否匹配时是常用的 。
( 4) 测试指令
格式,TEST OPD,OPS
功能:目的操作数与源操作数按位相与, 结果反映在标志位上,
但不送回目的操作数 。 即,( OPD) ∧ ( OPS) 。
汇编语言 程序设计
说明:
① 该指令完成与 AND指令相同的操作, 但 TEST指令不改变目的操
作数的值 。
② TEST指令常用于:在不希望改变原有的操作数的情况下, 用来
检测某一位或某几位的条件是否满足 。 编程时常与条件转移指
令一起使用, 可在 TEST指令后面加上条件转移指令, 来测试操
作数某位是否为 1,或者是否为 0。
( 5) 逻辑非指令
格式,NOT OPD
功能:将目的操作数各位取反, 结果送目的操作数 。
即,OPD← ( OPD) 。
说明:若将整个操作数取反, 则应使用 NOT指令, 若只需将操作数
的一部分位取反, 则应使用 XOR指令 。
总之, 逻辑运算指令对字或字节执行按位操作, 主要用于将字或
字节的指定位进行置, 1”, 清, 0”, 取反的操作, 测试字或字节指定的
位, 以及对字, 字节数据进行拆分与拼装操作 。
汇编语言 程序设计
2,移位指令
移位指令包括逻辑移位指令, 算术移位指令和循环移位指令 。 这些指
令都对目的操作数按操作符规定的方式向左或向右移动指定位数的操作 。
( 1) 逻辑左移指令
格式,SHL OPD,COUNT
功能:将目的操作数向左移动 COUNT指定的位数, 每左移一位, 最低位
补 0,最高位送 CF。
( 2) 逻辑右移指令
格式,SHR OPD,COUNT
功能:将目的操作数向右移动 COUNT指定的位数, 每右移一位, 最高位
补 0,最低位送 CF。
( 3) 算术左移指令
格式,SAL OPD,COUNT
功能,SAL指令与 SHL指令的功能完全相同 。
( 4) 算术右移指令
格式,SAR OPD,COUNT
功能:将目的操作数向右移动 COUNT指定的位数, 每右移一位, 最高位
均保持不变, 最低位送 CF。
汇编语言 程序设计
( 5) 循环左移指令 ROL
格式,ROL OPD,COUNT
功能:将目的操作数向左循环移位 COUNT指定的位数, 每左移一位,
左移前的最高送最低位以及 CF。
( 6) 循环右移指令 ROR
格式,ROR OPD,COUNT
功能:将目的操作数向右循环移位 COUNT指定的位数, 每右移一位,
右移前的最低送最高位以及 CF。
( 7) 带进位的循环左移指令 RCL
格式,RCL OPD,COUNT
功能:将目的操作数连同 CF位一起向左循环移位 COUNT指定的位数,
每左移一位, 左移前的 CF送最低位, 左移前的最高位送 CF。
( 8) 带进位的循环右移指令 RCR
格式,RCR OPD,COUNT
功能:将目的操作数连同 CF位一起向右循环移位 COUNT指定的位数,
每右移一位, 右移前的 CF送最高位, 右移前的最低送 CF。
汇编语言 程序设计
四, 处理器控制 指令
1,标志位操作指令
( 1) 清除进位标志指令 ( 2) 进位标志置位指令
CLC ; 置 CF= 0 STC ; 置 CF= 1
( 3) 进位标志取反指令
CMC ; CF取反
( 4) 清除方向标志指令 ( 5) 方向标志置位指令
CLD ; 置 DF= 0 STD ; 置 DF= 1
( 6) 清除中断标志指令 ( 7) 中断标志置位指令
CLI ; 置 IF= 0 STI ; 置 IF= 1
2,处理器控制指令
( 1) 空操作指令
格式,NOP 功能,CPU执行一次空操作 。
( 2) 暂停指令
格式,HLT 功能:使 CPU进入暂停状态, 不进行任何操作 。
( 3) 等待指令
格式,WAIT 功能:使 CPU处于等待状态 。 返回
汇编语言 程序设计
3.4,80X86及 Pentium扩展指令
80x86及 Pentium处理器的指令系统都包括了各自前期处理器的全部
指令, 并在此基础上对前期处理器的指令系统进行了增强和扩展 。
1,80286增强和扩展指令
80286指令系统除了包括所有的 8086指令及对上述部分指令进行了功能
扩展之外, 还新增了一些指令, 并在原有工作模式基础上增加了一种新
的工作模式, 即保护虚地址模式 。
(1) 80286工作模式
( a) 实地址模式 。 80286系统上电启动后, 就进入了实地址模式, 在此
模式下, 80286与 8086在目标代码一级是向上兼容的, 存储器最大的可访
问空间为 1MB,CPU产生 20位物理地址的方法, 段的结构以及存储区中专
用单元和保留单元均与 8086相同 。 在实地址模式下, 用 LMSW指令设置机
器状态字 MSW中的 PE标志, 可进入保护虚地址模式 。
( b) 保护虚地址模式 。 该工作模式是集实地址模式的能力, 存储器管理,
对虚拟存储器的支持和对地址空间的保护为一体而建立起来的一种特殊
工作方式 。 保护虚地址模式下的寄存器功能, 指令功能及寻址方式等与
实模式相同, 8086的程序及 80286在实地址模式下的程序都可以在保护虚
地址模式下运行 。
汇编语言 程序设计
(2) 80286扩展指令
( a) 堆栈操作指令
① PUSH 16位立即数
将 16位立即数压入堆栈, 该指令不影响状态标志位 。 该指令中立即
数如果给出的数不够 16位, 则自动扩展为 16位后压入堆栈 。
② PUSHA
将所有通用寄存器 AX,CX,DX,BX,SP,BP,SI,DI的内容按顺序
压入堆栈, 入栈的 SP值是执行该指令之前 SP的值, 在执行完本指令后
,SP值减 16。
③ POPA
将栈顶的内容顺序弹至 DI,SI,BP,SP,BX,DX,CX,AX( 次序
与 PUSHA指令相反 ) 。 SP中的值是堆栈中所有通用寄存器弹出后, 堆
栈指针实际指向的值 ( 不是栈中保存的 SP值 ), 也即该指令执行后 SP
的值, 可以通过加 16来恢复 。 PUSHA及 POPA均不影响状态标志位 。
汇编语言 程序设计
(b) 有符号整数乘法指令 。
① IMUL 16位寄存器, 立即数
将 16位通用寄存器中的有符号数作为被乘数, 与有符号立即数相乘
,乘积送回通用寄存器 。 若乘积超出字有符号数的表示范围
( -32768--+32767), 除丢失溢出部分外, 并将 OF及 CF置为 1;否则
,将 OF及 CF置为 0。
② IMUL 16位寄存器, 16位寄存器, 立即数
该指令与上一条指令功能类似, 区别仅在于将 16位存储器操作数作
为被乘数与立即数相乘, 结果送 16位寄存器 。
( c) 移位指令 。
8086中有 8条移位指令, 移位计数使用 CL或 1表示, 且规定当移位次
数大于 1时, 必须使用 CL。 在 80286中, 则修改了上述的限制, 当移位
次数为, 1~31次时, 允许使用立即数 。 例如,ROR BX,7。
汇编语言 程序设计
2,80386增强和扩展指令
80386微处理器是 Intel公司 80x86发展史上的里程碑, 它不但兼
容 8086,80186,80286微处理器, 而且也为后来的 80486,Pentium
,Pentium Pro的发展打下了坚实的基础 。
80386指令系统包括了所有 80286指令, 并对 80286的部分指令进
行了功能扩充, 还新增了一些指令, 特别指出的是, 80386提供了
32位寻址方式, 可对 32位数据直接操作 。 所有 16位指令均可扩充为
32位指令 。 80386有 8个 32位通用寄存器,EAX,ECX,EDX,EBX,
ESP,EBP,ESI,EDI。 它们分别是原来的 16位通用寄存器 AX,CX,
DX,BX,SP,BP,SI,DI的扩展 。 对于数据段寄存器, 80386在原
有基础上增加了两个,FS和 GS。
80386有实地址模式, 保护虚地址模式和虚拟 8086模式三种工作
方式, 在 DOS环境中只能运行实模式, 可做为超高速 8086芯片使用
。
80386的标志寄存器扩展到了 32位, 其中某些位没有定义 。 80386
在实地址模式下有 9个标志位可用, 在保护虚地址模式下有 13个标志
位可用, 扩展后的标志寄存器称为 EFLAGS。
汇编语言 程序设计
(1) 数据传送指令
( a) MOVSX 寄存器, 寄存器 /存储器
将源操作数传送到目的操作数中 。 目的操作可以是 16位或 32位寄
存器;源操作数可以是寄存器或存储器操作数, 其位数应小于或等
于目的操作数的位数 。 当源操作数的位数少于目的操作数时, 目的
操作数的高位用源操作数的符号位填补 。, 此指令适用于有符号数
的传送与扩展 。 该指令不影响状态标志位 。
( b) MOVZX 寄存器, 寄存器 /存储器
与 MOVSX功能基本相同, 惟一区别在于, 当源操作数的位数少于
目的操作数位数时, 目的操作数的高位用, 0” 填补 。 该指令适用于
无符号数的传送与扩展 。
汇编语言 程序设计
(2) 堆栈操作指令
( a) PUSH 32位立即数
将 32位立即数压入堆栈 。 该指令执行后 SP的值将减 4。 通常使用以下
方法来区别操作数是 8位, 16位还是 32位立即数,PUSH 23H,PUSHW
14H,PUSHD 45H。
( b) PUSHAD
将所有通用寄存器 EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI的内
容顺序压入堆栈, 其中压入堆栈的 ESP是该指令执行前 ESP的值 。 执行
该指令后, ESP值减 32。
( c) POPAD
将当前栈顶内容顺序弹至 EDI,ESI,EBP,ESP,EBX,EDX,ECX,
EAX( 次序与 PUSHAD指令相反 ), 但是最终 ESP的值为弹出操作对堆栈
指针调整后的值 ( 而不是堆栈中保存的 ESP的值 ) 。 即执行该指令后
ESP的值, 可以通过增加 32来恢复 。
( d) PUSHFD
将 32位标志寄存器 EFLAGS的内容压入堆栈 。
( e) POPFD
将当前栈顶的 4字节内容弹至 EFLAGS寄存器 。
上述堆栈操作指令中, 除 POPFD以外, 其余均不影响状态标志位 。
汇编语言 程序设计
(3) 地址传送指令
( a) LFS 寄存器, 存储器
将源操作数所指存储单元的 4字节或 6字节内容送指定的寄存器及段
寄存器 FS。
当目的操作数为 16位寄存器时, 将 4字节的存储器操作数中的低两字
节送指定寄存器, 高两字节送段寄存器 FS; 当目的操作数为 32位寄存
器时, 将 6字节的存储器操作数中的低 4字节送指定寄存器, 高两字节
送段寄存器 FS。 该指令不影响状态标志位 。
( b) LGS 寄存器, 存储器
该指令与 LFS指令功能基本相同, 惟一区别是该指令所涉及的段寄存
器为 GS。
( c) LSS 寄存器, 存储器
该指令与 LFS指令功能基本相同, 惟一区别是该指令所涉及的段寄存
器为 SS。
汇编语言 程序设计
(4) 有符号数乘法指令
( a) IMUL 寄存器, 寄存器 /存储器
将 16位或 32位通用寄存器中的有符号数作为被乘数, 相同位数通用
寄存器或存储单元中的有符号数作为乘数, 乘积送目的操作数 。 若乘
积溢出, 溢出位部分将丢失, 且将 OF及 CF置 1,否则将 OF及 CF置 0。
注意:目的操作数的位数必须与源操作数位相同 。
( b) IMUL 寄存器, 寄存器/存储器, 立即数
与前一指令功能基本相同, 惟一区别是寄存器 /存储器为被乘数, 立
即数为乘数, 乘积存放在第一个操作数中 。
(5) 符号扩展指令
( a) CWDE
将 AX中 16位有符号数的符号位扩展到 EAX的高 16位中, 即把 AX的 16位
有符号数扩展为 32位后, 送 EAX。
( b) CDQ
将 EAX中 32位有符号数扩展到 EDX,EAX寄存器对中, 使之成为 64位有
符号数, 即将 EAX中的符号位扩展到 EDX中 。
汇编语言 程序设计
(6) 位操作指令
( a) 位测试及设置指令
① BT 寄存器 /存储器地址, 寄存器 /立即数
第一操作数指定要测试的内容, 第二操作数指定要测试的位, 将被
测内容的指定测试位的值送 CF,其他状态标志不确定 。
② BTC 寄存器 /存储器地址, 寄存器 /立即数
该指令在 BT指令功能的基础上, 将被测位取反 。
③ BTR 寄存器 /存储器, 寄存器 /立即数
该指令在 BT指令功能的基础上, 将被测位清 0。
④ BTS 寄存器 /存储器, 寄存器 /立即数
该指令在 BT指令功能基础上, 将被测位置 1。
( b) 位扫描指令 。
① BSF 寄存器, 寄存器 /存储器
对第二操作数从最低位到最高位进行扫描, 将首先扫描到的, 1” 的
位号送第一操作数, 且使 ZF置 0。 若第二操作数的各位均为 0,则第一
操作数的值不确定, 且使 ZF置 1。 其他状态标志位不确定 。
② BSR 寄存器, 寄存器 /存储器
与 BSF指令功能基本相同, 惟一区别是该指令是从最高位到最低位
进行扫描 。
汇编语言 程序设计
(7) 移位指令
80386中增加了一组新的移动多位的指令 。 它们可以把指定的一组
位左移或右移到一 个操作数中去 。
( a) SHLD 寄存器 /存储器, 寄存器, CL/立即数
将第一操作数左移若干位,空出位用第二操作数高位部分填补, 但
第二操作数内容不变, CF标志位中保留第一操作数最后的移出位 。 若
仅移一位, 当 CF值与移位后的第一操作数的符号位不一致时, OF置 1
,否则, OF置 0。
( b) SHRD 寄存器 /存储器, 寄存器, CL/立即数
将第一操作数右移若干位, 空出位用第二操作数低位部分填补, 指
令执行后, 第二操作数内容不变, CF标志位保留第一操作数最后的移
出位 。
(8) 条件设置指令
这是 80386特有的指令用于测试指定的标志位所处的状态, 并根据
测试结果, 将指定的一个 8位寄存器或内存单元置 1或置 0。
指令格式,SET 条件 寄存器/存储器
说明:条件是指令助记符的一部分, 用于指定要测试的标志位 。
汇编语言 程序设计
3,80486新增指令
80486指令系统与 80386指令系统的差异不大, 仅仅是在 80386指令系
统的基础上新增了几条指令 。
( 1) 字节交换指令
格式,BSWAP 寄存器
功能:将 32位通用寄存器以字节为单位进行高低字节的交换, 即对
指定寄存器的 32位操作数的位 31- 24与位 7- 0,位 23- 16与位 15- 8交
换 。 该指令不影响状态标志位 。
( 2) 互换并相加指令
格式,XADD 寄存器 /存储器, 寄存器
功能:将第一操作数与第二操作数内容互换, 并将两者之和送第
一操作数 。 该指令对状态标志位的影响与 ADD指令相同 。
(3) 比较并交换指令
格式,CMPXCHG 寄存器 /存储器, 寄存器
功能:将第一操作数内容与对应长度累加器内容作比较, 若相等, 则
使 ZF置 1,且将第二操作数内容送第一操作数;否则使 ZF清 0,且第一
操作数送对应累加器 。 若 ( ESI) = ( EAX), 则 ZF=1,且将 ( EBX) 送
ESI; 否则 ZF=0,且将 ( ESI) 送 EAX。
汇编语言 程序设计
(4) Cache管理指令
(a) 使整个片内 Cache无效指令
格式,INVD
该指令用于将 CPU内部 Cache的内容无效 。 其具体的操作是刷新内
部 Cache,并分配一个专用总线周期刷新外部 Cache,执行该指令不
会将外部 Cache中的数据写回主存, 即 Cache中数据自然丢失 。
( b) 写回并使 Cache无效指令
格式,WBINVD
该指令功能与 INVD相似, 具体操作是刷新内部 Cache。 并分配一
个专用总线周期将外部 Cache的数据写回主存, 并在此后的一个专用
总线周期将外部 Cache刷新 。
( c) 使 TLB无效指令
格式,INVLPG
该指令使页式管理机构内的高速缓冲器 TLB中的某一项作废 。
若 TLB中含有一个存储器操作数映像的有效项, 则该 TLB项被标记为
无效 。
汇编语言 程序设计
4,Pentium新增指令
与 80486相比, Pentium新增了几条指令, 但某些新增的指令是否
有效与 Pentium的型号有关, 可利用处理器特征识别指令 CPUID判别
处理器是否支持某些新增指令 。
(1) 8字节比较交换指令
格式,CMPXCHG8B 存储器
功能:将 EDX,EAX中的 8字节值与指定的 8字节存储器操作数相比较
,若相等, 则使 ZF置 1,且将 ECX,EBX中的值送指定的 8字节存储单
元替换原有存储器操作数;否则使 ZF=0,且将指定的 8字节存储器操
作数送 EDX,EAX。
(2) 处理器特征识别指令
格式,CPUID
功能:根据 EAX中的参数, 将处理器的说明信息送 EAX,特征标志字
送 EDX。
汇编语言 程序设计
(3) 读时间标记计数器指令
格式,RDTSC
功能:将 Pentium中的 64位时间标记计数器的高 32位送 EDX,低 32
位送 EAX。 该计数器随每一个时钟递增, 在 Reset后该计数器被置 0
。 利用该计数器可检测程序运行性能 。
(4) 读模型专用寄存器指令
格式,RDMSR
功能:将 ECX所指定的模型专用寄存器的内容送 EDX,EAX,具体
来说, 高 32位送 EDX,低 32位送 EAX。 若所指定的模型寄存器不是 64
位, 则 EDX,EAX中的对应位无定义 。
(5) 写模型专用寄存器指令
格式,WRMSP
功能:将 EDX,EAX的内容送到由 ECX指定的模型专用寄存器 。 具
体来说, EDX和 EAX的内容分别作为高 32位和低 32位 。 若指定的模型
寄存器有未定义或保留的位, 则这些位的内容不变 。
返回
第 3章 指令系统和寻址方式
◆ 汇编指令格式
◆ 寻址方式
◆ 8086指令系统
◆ 80X86及 Pentium扩展指令
汇编语言 程序设计
3.1 汇编指令格式
计算机中的一条指令通常包含两部分:
依据操作数的个数划分,80X86CPU指令
系统中的指令格式最常用的有,双操作数指
令、单操作数指令和无操作数指令。
操作码 操作数
汇编语言 程序设计
1、双操作数指令汇编格式及操作规定
格式,[标号,] 操作符 OPD,OPS [; 注释 ]
操作规定:
( 1) OPD与 OPS应为同种操作类型且类型明确,即同为
字节类型或字类型。
( 2) OPD不能是立即数。
( 3) OPS和 OPD不能同时为存储器操作数,即:或者是
OPS和 OPD中至少有一个为寄存器操作数,或者
是 OPD为存储器操作数,OPS为立即数。
( 4)操作结束后,运算结果存入 OPD中,OPS内容不变。
汇编语言 程序设计
2、单操作数指令汇编格式及操作规定
格式,[标号,] 操作符 OPD [; 注释 ]
操作规定:
( 1) OPD类型必须明确即为字节类型或字类型, 不能
是模糊类型 。
( 2) 操作对象为目的操作数, 操作结束后结果存入
OPD中 。
( 3) OPD不能是立即数, 只能是寄存器操作数或存储
器操作数 。
汇编语言 程序设计
3、无操作数指令汇编格式及操作规定
格式,[标号,] 操作符 [; 注释 ]
操作规定,指令中只有操作码,不含操作数,这
种指令有两种可能:
( 1)无需任何操作数。如停机指令、空操作指令等。
( 2) 所需操作数是隐含指定的, 操作时取固定操作
数进行操作 。
返回
汇编语言 程序设计
3.2 寻址方式
寻找指令中所需操作数存放地址的方式或程序
转移时寻找转移地址的方式称为寻址方式, 因而寻
址方式分为两大类, 一类是数据寻址方式, 另一类
是转移地址寻址方式 。
由于 80X86指令涉及四种操作数:立即操作数、
寄存器操作数、存储器操作数和隐含操作数,因此,
数据寻址方式又可对应四种寻址方式,即:立即寻
址、寄存器寻址、存储器寻址和固定寻址。
汇编语言 程序设计
1、立即寻址
此寻址方式所提供的操作数直接包含在指令中,
它紧跟在指令操作码后面,存放在存储器代码段中。
立即操作数可以是 8位,也可以是 16位。
汇编格式,n (n是用 8位或 16位二进制补码表示的有符号数 )
【例 3.1】 MOV AX,1234H
立即寻址方式用来表示常数, 它常用于给寄存器
赋初值 。 需要强调的是, 立即寻址只能用于源操作
数, 不能用于目的操作数 。
汇编语言 程序设计
2、寄存器寻址
此寻址方式的操作数直接存放在由指令指明的寄存器中。
在汇编指令中直接书写寄存器名,如 16位寄存器操作数可以
是 AX,BX,CX,DX,SI,DI,BP,SP,DS,ES,SS,CS等; 8
位寄存器操作数可以是 AH,AL,BH,BL,CH,CL,DH,DL。
汇编格式,R ( 其中 R表示寄存器名 )
此寻址方式由于存取操作数直接从 CPU内部寄存器中获得,
不需访问存储器, 因而指令执行的速度快 。
寄存器寻址既可用于源操作数, 又可用于目的操作数, 应用
频率高 。
【 例 3.2】 MOV DS,AX
ADD CL,AH
汇编语言 程序设计
3、存储器寻址
存储器寻址方式的操作数都是存放在存储器中,一般是
数据段、附加段、堆栈段中的存储单元。指令中给出的是存
储单元的地址或产生存储单元地址的表达式。在汇编语言源
程序中,存储单元地址是采用逻辑地址的形式表示的,即:
段首址:段内偏移地址。段首址存放在某个段寄存器中,段
内偏移地址是指存放操作数的存储单元与段起始地址(段首
址)之间的距离(字节数),又可称为, 有效地址,,记作
EA。 有效地址 EA是由 3个地址分量的某种组合求得,这 3个地
址分量是:位移量,基址,变址 。
这 3个地址分量的不同组合, 使形成有效地址 EA的方法不同,
相应有以下 5种不同的存储器操作数寻址方式 。
汇编语言 程序设计
( 1)直接寻址
直接寻址是最简单的存储器寻址,这种寻址,操作数的有效地址 EA
由指令直接给出。它主要用于存取简单变量。
汇编格式,( a) [ 常量 ] ( b) 变量 或 含有变量的表达式
【 例 3.3】 MOV AL,[ 1000H ] MOV VAL,BX
对使用直接寻址方式需说明以下几点:
● 操作数默认存放在数据段中, 段寄存器 DS在指令格式无须指定 。
● 若操作数在代码段、堆栈段或附加段中,则在指令格式中必须指定相
应的段寄存器名。在操作数地址之前使用前缀指出段寄存器名,这种前缀
称为段超越前缀。
● 指令中操作数的 EA即可以是一个数字, 也可以是一个符号地址 。 当 EA
是一个数字时, 一定要注意立即寻址方式与直接寻址方式的区别 。
● 直接寻址方式适合于处理存储器的单个存储单元。
汇编语言 程序设计
( 2)寄存器间接寻址
此寻址方式中,操作数的有效地址 EA存放在 SI,DI,BX或 BP四个寄
存器之一中,即,EA=( BX) 或( BP) 或( SI) 或( DI)。
汇编格式,[ R ] ( 其中 R是寄存器 SI,DI,BX,BP之一 )
SI,DI,BX,BP在这里叫间址寄存器 。 若用 BX,SI或 DI间址寻址时, 则
操作数默认在数据段中, 且用 DS内容作为段首址, 操作数的物理地址为:
( BX)
PA= ( DS) × 16+ ( SI)
( DI)
【 例 3.4】 MOV DL,[ BX ]
若指令中使用 BP间址寻址时, 则操作数默认在堆栈段中, 且用 SS的内容
作为段首址, 操作数的物理地址为,PA= ( SS) × 16 + ( BP) 。
【 例 3.5】 MOV [ BP ], AX
汇编语言 程序设计
( 3)基址寻址
此寻址操作数的有效地址 EA是指令中指定的基址寄存器的内容与指令
中给出的位移量之和,即,EA=( BX)+ 位移量
( BP)
汇编格式,( a) Disp [ BX ] 或 Disp [ BP ]
( b) [ BX + Disp ] 或 [ BP + Disp ]
该寻址方式中若以 BX作为基址寄存器, 则操作数默认在数据段中;若以
BP作为基址寄存器, 则操作数默认在堆栈段中, 因而操作数的物理地址为:
PA= ( DS) × 16+ ( BX) + Disp
( SS) × 16+ ( BP) + Disp
若操作数不在默认段中, 则应使用段超越前缀明确指定 。
【 例 3.6】 MOV AX,[ BX+7CH ]
MOV AX,[ BP+COUNT ]
汇编语言 程序设计
( 4)变址寻址
变址寻址与基址寻址类似,其操作数的有效地址 EA是变址寄存器的
内容与位移量之和,即,EA=( SI)+ 位移量
( DI)
汇编格式,( a) Disp [ SI ] 或 Disp [ DI ]
( b) [ SI + Disp ] 或 [ DI + Disp ]
该寻址方式默认段是数据段, 因而操作数的物理地址为:
PA= ( DS) × 16+ ( SI) + Disp
( DI)
若操作数不在默认段中, 则应使用段超越前缀明确指定 。
【 例 3.7】 MOV DX,COUNT [ DI ]
MOV ES,3480H [ SI ],AX
汇编语言 程序设计
( 5)基址加变址寻址
此寻址方式中操作数的有效地址 EA是指令中的基址寄存器的内容、变址
寄存器的内容、位移量三个地址分量之和,即,EA=( BX)+( SI)+ 位移量
( BP) + ( DI)
汇编格式,( a) Disp [ BX 或 BP+ SI或 DI ]
( b) [ BX或 BP + SI或 DI+ Disp ]
该寻址方式中若基址寄存器采用 BX,则操作数默认在数据段中;
若基址寄存器采用 BP,则操作数默认在堆栈段中, 因而操作数的物理
地址为,PA= ( DS) × 16+ ( BX) + ( SI) + Disp
( DI)
( SS) × 16+ ( BP) + ( SI) + Disp
( DI)
汇编语言 程序设计
4,80X86扩充的寻址方式
上述讲的 8种 8086CPU的 16位寻址方式同样适用于 80X86CPU32位寻
址方式,在这 8种 32位寻址方式中,只不过是立即数、寄存器、存储器
有效地址扩充到 32位,而且任意 32位通用寄存器( EAX,EBX,ECX、
EDX,ESI,EDI,EBP,ESP) 均可作为间址寄存器、基址寄存器或变址
寄存器(变址寄存器 ESP除外)。
除此之外, 80X86CPU32位寻址方式还提供了两种仅适用于 32位 CPU的寻
址方式, 即:比例变址寻址和基址加比例变址寻址, 这两种寻址方式
均属于存储器寻址方式中的一种, 其操作数存放在存储器中 。
(1) 比例变址寻址
由变址寄存器的内容乘以比例因子再加上位移量而得到操作数有效
地址 EA的寻址方式称为比例变址寻址,
即,EA= [ 变址寄存器 ]× 比例因子+位移量 。
汇编格式,[ 变址寄存器 ]× 比例因子+位移量
汇编语言 程序设计
其中:变址寄存器是 EAX,EBX,ECX,EDX,ESI,EDI,EBP之一;
比例因子可以是 1,2,4,8;位移量可以是 0位,8位或 32位。
此寻址方式操作数默认在数据段, 若操作数不在默认的数据段中时,
则应使用段超越前缀明确指定 。
例如,MOV EAX,COUNT[ EDI*2 ]; COUNT是位移量, 2是比例因子
其中乘以比例因子的操作是在 CPU内部由硬件完成。
(2) 基址加比例变址寻址
由变址寄存器的内容乘以比例因子加上基址寄存器的内容再加上位
移量而得到操作数有效地址 EA的寻址方式称为基址加比例变址寻址 。
即,EA= [ 变址寄存器 ]× 比例因子+ [ 基址寄存器 ]+位移量 。
若基址寄存器采用 EBP,ESP时, 则操作数默认在 SS段中, 若基址寄存
器采用除 EBP,ESP以外的其他寄存器时, 则操作数默认在 DS段中 。 若
操作数不在相应的默认段中时, 则应使用段超越前缀明确指定 。
例如,MOV [ ESI*4+ EDX ],EAX ; 目的操作数在 DS段中
汇编语言 程序设计
5、转移地址寻址方式
转移地址寻址方式确定的是转移指令或调用指令转移后的地址。
可将转移地址寻址方式分为四种:段内直接寻址, 段内间接寻址, 段
间直接寻址和段间间接寻址 。
(1) 段内直接寻址
段内直接寻址又称为段内相对寻址 。 在此寻址方式下, 转移后的指令
与转移指令本身在同一代码段中 。 转移后指令的有效地址 EA= ( IP) +
位移量 。 若位移量为正, 则相对本指令向后转移, 若为负, 则相对本指
令向前转移 。
汇编格式,( a) SHORT 标号
( b) NEAR PTR 标号 其中:标号是符号地址。
例如,JMP SHORT NEXT
JMP NEAR PTR L1
汇编语言 程序设计
(2) 段内间接寻址
转移有效地址是一个字寄存器或是一个字存储单元的内容。这个字
寄存器或字存储单元的内容可以用数据寻址方式中的寄存器寻址或存储
器寻址获得,所得到的转移有效地址用来取代当前的 IP值实现段内间接
寻址。这种寻址方式只适用于 JMP和 CALL指令。
汇编格式,( a) R ( R为 16位通用寄存器 )
(b) 存储器寻址方式之一
若 JMP和 CALL指令采用格式 ( a), 即寄存器寻址, 则指令中指定的寄
存器内容便是转移地址, 当 CPU执行 JMP或 CALL指令时, 就将该寄存器的
内容装入 IP。
若 JMP和 CALL指令采用格式 ( b) 中的一种存储器寻址时, 则转移地址便
是字存储单元的内容, 当 CPU执行 JMP或 CALL指令时, 就将该字存储单元
的内容装入 IP。
汇编语言 程序设计
(3) 段间直接寻址
此寻址方式,转移后的指令与转移指令本身不在同一代码段中。转
移地址(即 IP和 CS值)由指令直接给出。
汇编格式,FAR PTR 标号
它只适用于 JMP和 CALL指令 。 例如,JMP L2( 标号 L2与本 JMP指令不
在同一代码段中 ) 。
( 4) 段间间接寻址
此寻址方式也只适用于 JMP和 CALL指令 。 转移后的指令与转移指令本
身不在同一代码段中 。 转移地址 ( 即 IP和 CS值 ) 由采用存储器寻址方式
之一确定的双字存储单元内容间接给出 。
汇编格式,存储器寻址方式之一
执行 JMP或 CALL指令时, 根据指令中指定的某种存储器寻址方式找到
内存的一个双字 ( 32位 ), 将高字内容装入 CS,将低字内容装入 IP,实
现段间转移 。
例如,JMP DWORD PTR [BX ] 返回
汇编语言 程序设计
3.3 8086指令系统
8086指令系统按功能可分为六大类:
( 1) 数据传送类指令 ( 2) 算术运算类指令
( 3) 位操作指令 ( 4) 串操作指令
( 5) 控制转移指令 ( 6) 处理器控制指令
8086指令按操作数个数可划分为三种类型:
( 1) 双操作数指令 ( 2) 单操作数指令 ( 3) 无操作数指令
学习汇编指令应从以下几方面着重理解掌握:
( 1) 学习指令格式;
( 2) 掌握指令中操作数的寻址方式及寻址方式的搭配规则;
( 3) 掌握指令的功能及指令执行后对条件码的影响;
( 4) 学习如何正确运用指令 。
汇编语言 程序设计
一,数据传送指令
1,通用数据传送指令
( 1) 传送指令 MOV
格式,MOV OPD,OPS
功能:把源操作数传送到目的操作数 。 即,OPD← ( OPS)
说明:
① 源操作数和目的操作数的操作类型必须明确且一致;当指令中只有一
个操作数的类型明确时, 另一个操作数被视为同一类型;当两操作数类型
均不明确时, 必须用, BYTE PTR”或, WORD PTR”将一个存储器操作数定
义为字节或字类型 。
② 指令执行后, 源操作数内容不变 。
③ 指令执行后, 对标志寄存器各位无影响 。
④ 源操作数可以是通用寄存器, 段寄存器, 存储器和立即数;目的操作
数也可以是通用寄存器, 段寄存器, 存储器, 但立即数, CS段寄存器不能
作为目的操作数 。 源操作数和目的操作数不能同时为存储器操作数 。
汇编语言 程序设计
用一条 MOV指令能实现:
(a) 立即数传送到通用寄存器或存储单元
如 MOV DL,’a’, MOV AX,1FA4H
(b) 寄存器之间的传送
如 MOV AX,BX, MOV AL,DH, MOV DS,AX
(c) 寄存器与存储单元之间的传送
如 MOV DL,BUFBYTE
MOV WORD PTR [BX+SI],AX
由于 MOV指令中只允许一个操作数在存储器中, 因此用一条 MOV指令无
法完成两个存储单元之间的数据传送, 但可以用二条指令来实现 。
【 例 3.9】 把 BUFWORD1字单元内容传送到 BUFWORD2字单元中, 可用以
下指令完成,MOV AX,BUFWORD1
MOV BUFWORD2,AX
汇编语言 程序设计
(2) 交换指令 XCHG
格式,XCHG OPD,OPS
功能:源操作数和目的操作数的内容相互交换 。
即,( OPD) ←→ ( OPS)
说明:该指令与 MOV指令相似, 但在功能上有两点区别,
其一, 该指令不允许使用立即数和段寄存器作为操作数;
其二, 该指令改变源操作数的内容 。
( 3) 查表转换指令 XLAT
格式,XLAT 或 XLAT OPS
功能:将 ( BX) 为首址 ( AL) 为位移量的字节存储单元中的数据
传送到 AL中 。 即,AL←([BX + AL])字节
汇编语言 程序设计
2,地址传送指令
地址传送指令主要用于将存储器操作数地址 ( 偏移地址,
段地址 ) 传送给指定的寄存器 。 它包括 3条指令,LEA,LDS和
LES。
( 1) 传送有效地址指令 LEA
格式,LEA REG16,OPS
功能:将源操作数的有效地址 EA传送给目的操作数指定的 16
位通用寄存器 。
说明:
① 源操作数必须是存储器操作数, 即 OPS采用存储器寻址;
目的操作数必须是一个 16位通用寄存器 。
② 本指令对标志位无影响 。
③ 该指令通常用来建立内存储器的寄存器指针 。
汇编语言 程序设计
( 2) 传送偏移地址及数据段首址指令 LDS
格式,LDS REG16,OPS
功能:将由源操作数确定的双字存储单元的内容传送给 DS及目的操
作数指定的 16位通用寄存器中, 其中高字单元的内容送给
DS,低字单元的内容送给 REG16。
说明,① 源操作数必须是双字存储器操作数, 即,OPS采用存储器
寻址, 寻找到相继 4个字节的存储单元, 低字单元中存放 偏
移地址, 高字单元中存放段首地址;目的操作数必须是 一
个 16位通用寄存器, 通常特定为 SI。
② 本指令不影响标志位 。
( 3) 传送偏移地址及附加段首址指令 LES
格式,LES REG16,OPS
功能:将由源操作数确定的双字存储单元的内容传送给 ES及目的操
作数指定的 16位通用寄存器中, 其中高字单元的内容送给
ES,低字单元的内容送给 REG16。
说明:同 LDS指令 。
汇编语言 程序设计
3,标志位传送指令
标志位传送指令有 4条指令, 即,LAHF,SAHF,PUSHF和 POPF。
( 1) 标志送 AH指令 LAHF
格式,LAHF
功能:将标志寄存器低 8位的内容送入 AH寄存器 。
即,AH←(FLAGS) 7-0,该指令的执行不影响标志位 。
( 2) AH标志送指令 SAHF
格式,SAHF
功能:将 AH寄存器的内容送入标志寄存器低 8位, 高 8位保持不变 。
该指令用于设置或恢复 SF,ZF,AF,PF,CF五个标志位,
该指令的执行只影响标志寄存器的低 8位, 对高 8位 ( 即 OF、
DF,IF,TF) 标志位无影响 。
从指令的功能上可看出, SAHF和 LAHF为互逆过程 。
汇编语言 程序设计
( 3) 标志进栈指令 PUSHF
格式,PUSHF
功能:将标志寄存器的内容压入堆栈 。
( 4) 标志出栈指令 POPF
格式,POPF
功能:将栈顶字单元内容弹出到标志寄存器中 。
该指令的执行影响标志位 。
PUSHF和 POPF互为逆过程 。
标志位传送指令中 SAHF和 POPF指令将直接影响标志寄存器的内
容 。 利用这一特性, 可以方便地改变标志寄存器中指定位的状态,
数据传送类指令还包括输入 / 输出专用指令, 在 PC机里所有 I/O
端口与 CPU之间的通信都由 IN和 OUT指令实现, 由 IN指令完成从 I/O
端口到 CPU的信息传送, 由 OUT指令完成从 CPU到 I/O端口的信息传送
。
汇编语言 程序设计
二, 算术运算指令
算术运算指令用来执行加, 减, 乘, 除四则运算 。 它包括无符号数, 有符
号数的二进制算术运算指令和十进制算术运算调整指令 。
1,二进制数算术运算指令
( 1) 加法运算指令
加法运算指令包括 ADD,ADC的 INC三条指令 。
① 加法指令 ADD
格式,ADD OPD,OPS
功能:将目的操作数与源操作数相加, 结果存入目的地址中, 而源
操作数不变 。 即,OPD← ( OPD) + ( OPS) 。
说明:该指令的源操作数或在通用寄存器或在存储单元中, 也可以是立
即数, 而目的操作数只能在通用寄存器或存储单元中, 不能是立即数,
且两操作数不能同时为存储器操作数;操作数可以是字节或字, 且两操
作数的类型明确并一致 。 该指令相加后, 根据得到的结果设置标志寄存
器的 OF,SF,ZF,CF,AF和 PF标志位 。
ADD指令执行后对标志位的影响及作用如下, 这里我们只重点说明 OF、
CF,SF和 ZF四个标志位 。
汇编语言 程序设计
OF,当两个有符号数相加时, 若两个操作数的符号相同, 而结
果的符号与之相反, 则 OF= 1,否则, 其余情况 OF= 0。
当 OF= 1时, 说明两个有符号数相加产生了溢出, 即和的
值超出了有符号数的有效范围 。 在把操作数视为有符号数
时, 可通过该标志了解加法结果是否正确 。
CF,运算过程中当最高位产生进位时, 则 CF= 1,否则, CF= 0。
当 CF= 1时, 说明运算结果超出了无符号数的表示范围 。
在把操作数视为无符号数时, 可通过该标志了解加法结果
是否正确 。
SF,运算结果的最高位为 1,则 SF= 1,否则, SF= 0。
ZF,运算结果为零时, 则 ZF= 1; 否则, ZF= 0。
汇编语言 程序设计
② 带进位加法指令 ADC
格式,ADC OPD,OPS
功能:与 ADD指令基本相同, 惟一区别是将该指令执行前的 CF值
加至目的操作数中 。 即,OPD← ( OPD) + ( OPS) + CF
说明:该指令与 ADD指令在功能上及结果对标志位影响上基本相
同 。 该指令主要用于多字节的加法运算 。
③ 加 1指令 INC
格式,INC OPD
功能:将目的操作数加 1后送回目的地址中, 并根据执行结果设
置标志位 OF,SF,ZF,AF,PF,但不影响 CF位 。
说明:该指令的操作数可以是字或字节且类型必须明确 。 其操作
数只能在通用寄存器或存储单元中, 不能是立即数 。 该指
令执行后对 OF,SF,ZF,AF,PF标志位的影响与 ADD指令
相同 。
INC主要用于计数器的计数或修改地址指针 。
汇编语言 程序设计
( 2) 减法运算指令
减法运算指令包括 SUB,SBB,DEC,NEG和 CMP五条指令 。
① 减法指令 SUB
格式,SUB OPD,OPS
功能:目的操作数减去源操作数, 其差值存入目的地址, 源操作
数不变, 即,OPD← ( OPD) - ( OPS) 。 并按相减的结果设
置标志位 OF,CF,SF,ZF,AF和 PF。
说明:该指令的源操作数和目的操作数可以在通用寄存器或存储
单元中, 但两者不能同时在存储器中, 立即数可作为源操作数, 而不
能作为目的操作数 。 两操作数可以是字节或字, 且类型明确一致 。
SUB指令执行后对标志位的影响与 ADD指令类似, 下面仅说明 CF和
OF两位的设置情况及作用:
OF:当两个有符号数相减时, 若两个操作数的符号相反, 而结果的
符号与减数相同, 则 OF= 1,否则, 其余情况 OF= 0。
OF= 1时, 说明有符号数减法溢出, 结果是错误的 。 OF位可用来
判断有符号数相减, 结果是否正确 。
CF:当两无符号数相减时, 若减数大于被减数, 则此时有借位,
CF= 1,否则 CF= 0,CF值反映了无符号数相减时是否有借位 。
汇编语言 程序设计
② 带借位减法指令 SBB
格式,SBB OPD,OPS
功能,SBB与 SUB指令基本相同, 惟一区别是:目的操作数除减去源
操作数外, 还要减去该指令执行前的 CF值 。
即,OPD← ( OPD) - ( OPS) - CF。 并按相减的结果设置标志
位 OF,CF,SF,ZF,AF和 PF。
说明:该指令与 SUB指令在功能上及结果对标志位的影响上基本相同 。
该指令在使用上类似于 ADC指令, 主要用于多字节减法运算 。
SUB和 SBB指令配合可以实现多倍精度数减法运算 。
③ 减 1指令 DEC
格式,DEC OPD
功能:将目的操作数减 1后送入目的地址中, 并根据执行结果设置标志
位 OF,SF,ZF,AF和 PF,但不影响 CF位 。 即 OPD← ( OPD) - 1。
说明:该指令的操作数可以是字节或字且类型必须明确;其操作数只
能在通用寄存器或存储单元中, 不能是立即数 。 该指令执行后
对 OF,SF,ZF,AF,PF的影响与 SUB指令相同 。
汇编语言 程序设计
④ 求负数指令 NEG
格式,NEG OPD
功能:用零减去目的操作数, 相减结果送回目的地址中 。
即,OPD← 0- ( OPD) =- ( OPD)
即求目的操作数的相反数 。
说明:
( a) 该指令是单操作数指令, OPD的用法与前面讲过的单操作数指
令,如 INC,DEC) 中的目的操作数相同 。
( b) NEG指令是对有符号数进行操作的, 由于机器中有符号数是用
补码表示的, 求一个操作数的负数, 就是求其补码, 因此,
NEG又叫求补指令, 即,OPD← ( OPD) + 1。
( c) 该指令执行后影响标志位 CF,OF,SF,ZF,AF和 PF。 其中:
OF,当字节操作数为- 128( 80H), 字操作数为- 32768
( 8000H), 执行 NEG指令后, 操作数无变化, 但溢出标志
位 OF置 1,其余情况 OF置 0。
CF,当操作数为零时, 求负数的结果仍为零, CF= 0,
其余情况 CF= 1
汇编语言 程序设计
⑤ 比较指令 CMP
格式,CMP OPD,OPS
功能:目的操作数减去源操作数, 结果只影响标志位, 不送入目的地址
即,( OPD) - ( OPS) 。
说明,CMP指令与 SUB指令一样执行减法操作, 但它不保存差值结果,
OPD和 OPS在操作前后值不变 。 CMP指令功能上, 使用方法上, 对
标志位的影响上均与 SUB指令基本相同 。
CMP指令常用于比较两个操作数的大小 。 执行 CMP指令后, 根据标志位
的设置情况判断两个数的大小关系 。
若两无符号数比较时:当 ZF= 0时, 则 OPD= OPS;
否则:当 CF= 0时, 则 OPD> OPS;
当 CF= 1时, 则 OPD< OPS。
若两有符号数比较时:当 ZF= 0时, 则 OPD= OPS;
否则:当 OF= SF时, 则 OPD> OPS;
当 OF≠SF 时, 则 OPD< OPS。
CMP指令后面常跟着条件转移指令, 根据比较结果产生不同的分支 。
汇编语言 程序设计
( 3) 乘法运算指令
乘法指令用于实现两个二进制操作数的乘法运算, 乘法指令区别无符号
数和有符号数, 所以它提供了两条指令,MUL和 IMUL。
① 无符号数乘法指令 MUL
格式,MUL OPS
功能:实现两个无符号数相乘 。
字节乘:当 OPS为字节操作数时, 将 ( AL) 乘以 ( OPS),
得到字乘积送入 AX中, 即,AX← ( AL) × ( OPS) 。
字乘,当 OPS为字操作数时, 将 ( AX) 乘以 ( OPS), 得到双
字乘积, 高字部分送入 DX中, 低字部分送入 AX中 。
即,DX,AX← ( AX) × ( OPS) 。
说明:
( a) MUL指令有两种操作类型, 即字节乘和字乘, MUL操作类型取决于
OPS的类型, OPS指定乘数, 它可以是字节或字, 但类型必须明确, 乘数可
以在通用寄存器或存储器中, 但不能是立即数 。
( b) MUL指令只影响 OF和 CF位 。
汇编语言 程序设计
若乘积的高一半 ( 即字节相乘时乘积中的 ( AH), 字相乘时乘积
中的 ( DX)) 为 0,则 OF= CF= 0,否则 OF= CF= 1。 MUL指令对其它标
志位不确定 。 当 CF= OF= 1时, 说明 AH或 DX中有乘积的有效数字, CF
= OF= 0时, 说明 AH或 DX中无乘积的有效数字, 也就是说字节乘以字
节积为字节或字乘以字积为字 。 编程时我们可以利用 OF和 CF位的设置
情况检查字节乘时乘积的结果是字节还是字, 字乘时乘积的结果是字
还是双字 。
② 有符号数乘法指令 IMUL
格式,IMUL OPS
功能:实现了两个有符号数相乘 。 其操作方法与 MUL指令相同 。
说明,IMUL指令也只影响 OF和 CF位, 对其它标志位不确定 。 若乘积
的高一半 ( 即 AH或 DX) 是低一半 ( 即 AL或 AX) 的符号扩展,
则 OF= CF= 0,否则, OF= CF= 1。 当 OF= CF= 1亦标志着 AH
或
DX中放有乘积的有效值, 即标志着 ( AH) 和 ( DX) 不是对应
的低半部分的符号扩展 。
汇编语言 程序设计
( 4) 除法运算指令
除法指令用于实现两个二进制操作数的除法运算, 包括无符号
数除法指令 DIV和有符号数除法指令 IDIV。
① 无符号数除法指令 DIV
格式,DIV OPS
功能:实现两无符号数除法运算, 商和余数均为无符号数 。
字节除:当 OPS为字节操作数时, 则以 ( AX) 为被除数, OPS为
除数, 将 ( AX) 除以 ( OPS), 得到的商送入 AL中, 余
数送入 AH中 。 即,( AX) /( OPS) → AL( 商 )
AH( 余数 )
字除, 当 OPS为字操作数时, 则以 ( DX,AX) 为被除数, OPS为
除数, 将 ( DX,AX) 除以 ( OPS), 得到的商送入 AX中
,
余数送入 DX中 。 即,( DX,AX) /( OPS) → AX( 商 )
DX( 余数
)
汇编语言 程序设计
说明:
( a) DIV指令有两种操作类型, 即字节除和字除, 其操
作类型取决于 OPS的类型, OPS指定除数, 它的类型必须明确
,它可以在通用寄存器或存储器中, 但不能是立即数 。 DIV
指令的被除数, 商和余数均采用隐含寻址方式, 当字节除时
,被除数隐含在 AX中, 商固定存入 AL中, 余数固定存入 AH中;当字除时, 被除数隐含在 DX,AX中, 商固定存入 AX中, 余
数固定存入 DX中 。
( b) DIV指令执行后, 标志寄存器中各标志位不确定,
但商可产生溢出 。 一般情况下, 当被除数的高一半 ( 即字节
除时为 ( AH), 字除时为 ( DX)) 大于除数时, 商就会产生
溢出 。 当 OPS为字节操作数时, 商的范围为 0- 255( 0FFH); 当 OPS为字操作数时, 商的范围为 0- 65535( 0FFFFH) 。
若商超出此范围, 则产生 0号中断 ( 除法出错中断 ), 转入
除法出错中断处理 。
汇编语言 程序设计
② 有符号数除法指令 IDIV
格式,IDIV OPS
功能:实现两有符号数除法运算, 该指令中的操作数, 商及余数均为
有符号数且用补码表示, 除此之外, 其余操作与 DIV完全相同 。
说明,( a) IDIV指令商的符号由被除数符号与除数符号异或运算而
得到, 余数的符号规定与被除数的符号相同 。
( b) 有符号数除法的商中, 最大的正数商是+ 127( 7FH) 或+ 32767
( 7FFFH), 最小的负数商是- 127( 81H) 或- 32767( 8001H) 。
当商超出此范围, 指令产生了溢出 。 一般情况下, 当被除数高一
半 ( AH或 DX) 的绝对值大于除数的绝对值时, 则可判断 IDIV指令
操作结果产生了溢出, 即产生 0号中断 。
③ 字节转换成字指令 CBW
格式,CBW
功能:将 ( AL) 的符号位扩展到 AH中 。
④ 字转换成双字指令 CWD
格式,CWD
功能:将 ( AX) 的符号位扩展到 DX中 。
汇编语言 程序设计
2,十进制算术运算调整指令
十进制算术运算调整指令又称为 BCD码调整指令 。 当用计算机进行十
进制算术运算时, 可以先将操作数作十 → 二进制转换, 然后作二进制数算
术运算, 再将结果作二 → 十进制转换 。 为了方便十进制数的运算, 8086系
统提供了一组十进制算术运算调整指令, 用于将运算后的二进制数调整为
BCD码 。 该类指令分为压缩 BCD码调整指令和非压缩 BCD码调整指令 。
注意:十进制调整指令不能单独使用, 必须与加, 减, 乘, 除二进制指
令配合使用才能进行十进制调整, 十进制调整指令形式上均为无操作数指
令, 其操作对象隐含在 AX中 。
( 1) 非压缩 BCD码调整指令
① 非压缩 BCD码加法调整指令 AAA。
格式,AAA
功能:将 AL中的和调整为非压缩 BCD码并送回 AL。 具体调整方法如下:
若二进制相加后 ( 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不确定 。
说明:在使用 AAA指令前, 必须执行 ADD,ADC或 INC指令把非压缩 BCD相
加, 且把和存放在 AL中 。
汇编语言 程序设计
② 非压缩 BCD码减法调整指令 AAS。
格式,AAS
功能:将 AL中的差调整为非压缩 BCD码并送回 AL,向高位的借位在 AH和
CF中 。 具体调整方法如下:
若二进制相减后 ( 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不确定 。
说明:在使用 AAS指令前, 必须执行 SUB,SBB或 DEC指令把非压缩 BCD相
减, 且把差存放在 AL中 。
③ 非压缩 BCD码乘法调整指令 AAM。
格式,AAM
功能:将 AL中的积调整为非压缩 BCD码并送回 AX。 具体调整方法是:
把 AL寄存器的内容除以 0AH,并把商放在 AH寄存器中, 余数放
在 AL寄存器中 。
④ 非压缩 BCD码除法调整指令 AAD。
格式, AAD
功能:除法运算前, 先调整被除数 AX内容,
使,AL← ( AH) * 0AH +( AL),AH← 0
汇编语言 程序设计
( 2) 压缩 BCD码调整指令
① 压缩 BCD码加法调整指令 DAA。
格式,DAA
功能:将 AL中的和调整为压缩 BCD码并送回 AL。 本指令执行之前必须先
执行 ADD或 ADC指令, 把两个压缩 BCD码相加, 且和存放在 AL寄存
器中 。 具体调整方法是:
若 ( AL) 的低 4位大于 9或 AF=1,则,AL← ( AL) + 06H,并使 AF=1;
若 ( AL) 的高 4位大于 9或 CF=1,则,AL← ( AL) + 60H,并使 CF=1;
其余情况 AL内容不变 。
说明,DAA指令影响 CF,ZF,SF,AF和 PF,对 OF无定义 。
② 压缩 BCD码减法调整指令 DAS。
格式,DAS
功能:将 AL中的差调整为压缩 BCD码并送回 AL。 本指令执行之前必须先
执行 SUB或 SBB指令, 把两个压缩 BCD码相减, 且差存放在 AL寄存
器中 。 具体调整方法是:
若 ( AL) 的低 4位大于 9或 AF=1,则,AL← ( AL) - 06H,并使 AF=1;
若 ( AL) 的高 4位大于 9或 CF=1,则,AL← ( AL) - 60H,并使 CF=1;
其余情况 AL内容不变 。
说明,DAS指令影响 CF,ZF,SF,AF和 PF,对 OF无定义 。
汇编语言 程序设计
三, 位操作指令
8086提供的位操作指令包括逻辑运算指令和移位指令, 这类指令可直
接对寄存器或存储器中的位进行操作 。
1,逻辑运算指令
逻辑运算指令包括,AND指令, OR指令, XOR指令, TEST指令和 NOT指
令, 其中前四种指令是双操作数指令, 符合双操作数指令的一般规律,
这四条指令执行后将使 CF和 OF位为 0,AF位不确定, 而 SF,ZF和 PF位则根
据运算结果设置; NOT指令是单操作数指令, 符合单操作数指令的一般规
律, 它的执行不影响标志位 。
( 1) 逻辑与指令
格式,AND OPD,OPS
功能:将目的操作数与源操作数按位相与, 结果送目的操作数 。
即,OPD← ( OPD) ∧ ( OPS) 。
说明,①, 与, 的运算原则是,1∧ 1=1,0∧ 1=0,1∧ 0=0,0∧ 0=0。
② AND指令常用于,
(a)使一个操作数中的若干位保持不变, 而若干位清为 0的场合 。
( b) 某一操作数, 自己和自己相, 与,, 操作数不变, 但可以使
进
位标志 CF清 0。
汇编语言 程序设计
( 2) 逻辑或指令
格式,OR OPD,OPS
功能:将目的操作数与源操作数按位相或, 结果送目的操作数 。
即,OPD← ( OPD) ∨ ( OPS) 。
说明:
①, 或, 操作的运算原则是,1∨ 1=1,0∨ 1=1,1∨ 0=1,0∨ 0=0
。
② OR指令常用于:
(a) 使一个操作数中的若干位保持不变, 而另外若干位置 1的
场合 。 这时, 要保持不变的这些位与, 0” 相或;而要置 1
的这些位与, 1” 相或 。
(b) 某一操作数, 自己和自己相, 或,, 操作数不变, 但可以
使进位标志 CF清 0。
( 3) 逻辑异或指令
格式,XOR OPD,OPS
功能:将目的操作数与源操作数按位相异或, 结果送目的操作数 。
即,OPD← ( OPD) ⊕ ( OPS) 。
汇编语言 程序设计
说明:
①, 异或, 操作的运算原则是,1⊕ 1=0,0⊕ 0=0,0⊕ 1=1,1⊕ 0=1。
② XOR指令常用于:
(a) 使一个操作数中的若干位保持不变, 而另外若干位取反的场
合 。 这时, 要保持不变的这些位与, 0” 相异或;而要取反的
那些位与, 1” 相异或 。
(b) 使某一操作数清 0。 由于一个操作数自身做, 异或, 时, 每一
位都相同,, 异或, 结果必为 0,且使进位标志也为 0。 因此这
是使操作数的初值置 0的常用的有效的方法 。
如指令 XOR AX,AX使 AX清 0。
(c) 测试某一操作数是否与另一确定的操作数相等 。 这种操作在
检查地址是否匹配时是常用的 。
( 4) 测试指令
格式,TEST OPD,OPS
功能:目的操作数与源操作数按位相与, 结果反映在标志位上,
但不送回目的操作数 。 即,( OPD) ∧ ( OPS) 。
汇编语言 程序设计
说明:
① 该指令完成与 AND指令相同的操作, 但 TEST指令不改变目的操
作数的值 。
② TEST指令常用于:在不希望改变原有的操作数的情况下, 用来
检测某一位或某几位的条件是否满足 。 编程时常与条件转移指
令一起使用, 可在 TEST指令后面加上条件转移指令, 来测试操
作数某位是否为 1,或者是否为 0。
( 5) 逻辑非指令
格式,NOT OPD
功能:将目的操作数各位取反, 结果送目的操作数 。
即,OPD← ( OPD) 。
说明:若将整个操作数取反, 则应使用 NOT指令, 若只需将操作数
的一部分位取反, 则应使用 XOR指令 。
总之, 逻辑运算指令对字或字节执行按位操作, 主要用于将字或
字节的指定位进行置, 1”, 清, 0”, 取反的操作, 测试字或字节指定的
位, 以及对字, 字节数据进行拆分与拼装操作 。
汇编语言 程序设计
2,移位指令
移位指令包括逻辑移位指令, 算术移位指令和循环移位指令 。 这些指
令都对目的操作数按操作符规定的方式向左或向右移动指定位数的操作 。
( 1) 逻辑左移指令
格式,SHL OPD,COUNT
功能:将目的操作数向左移动 COUNT指定的位数, 每左移一位, 最低位
补 0,最高位送 CF。
( 2) 逻辑右移指令
格式,SHR OPD,COUNT
功能:将目的操作数向右移动 COUNT指定的位数, 每右移一位, 最高位
补 0,最低位送 CF。
( 3) 算术左移指令
格式,SAL OPD,COUNT
功能,SAL指令与 SHL指令的功能完全相同 。
( 4) 算术右移指令
格式,SAR OPD,COUNT
功能:将目的操作数向右移动 COUNT指定的位数, 每右移一位, 最高位
均保持不变, 最低位送 CF。
汇编语言 程序设计
( 5) 循环左移指令 ROL
格式,ROL OPD,COUNT
功能:将目的操作数向左循环移位 COUNT指定的位数, 每左移一位,
左移前的最高送最低位以及 CF。
( 6) 循环右移指令 ROR
格式,ROR OPD,COUNT
功能:将目的操作数向右循环移位 COUNT指定的位数, 每右移一位,
右移前的最低送最高位以及 CF。
( 7) 带进位的循环左移指令 RCL
格式,RCL OPD,COUNT
功能:将目的操作数连同 CF位一起向左循环移位 COUNT指定的位数,
每左移一位, 左移前的 CF送最低位, 左移前的最高位送 CF。
( 8) 带进位的循环右移指令 RCR
格式,RCR OPD,COUNT
功能:将目的操作数连同 CF位一起向右循环移位 COUNT指定的位数,
每右移一位, 右移前的 CF送最高位, 右移前的最低送 CF。
汇编语言 程序设计
四, 处理器控制 指令
1,标志位操作指令
( 1) 清除进位标志指令 ( 2) 进位标志置位指令
CLC ; 置 CF= 0 STC ; 置 CF= 1
( 3) 进位标志取反指令
CMC ; CF取反
( 4) 清除方向标志指令 ( 5) 方向标志置位指令
CLD ; 置 DF= 0 STD ; 置 DF= 1
( 6) 清除中断标志指令 ( 7) 中断标志置位指令
CLI ; 置 IF= 0 STI ; 置 IF= 1
2,处理器控制指令
( 1) 空操作指令
格式,NOP 功能,CPU执行一次空操作 。
( 2) 暂停指令
格式,HLT 功能:使 CPU进入暂停状态, 不进行任何操作 。
( 3) 等待指令
格式,WAIT 功能:使 CPU处于等待状态 。 返回
汇编语言 程序设计
3.4,80X86及 Pentium扩展指令
80x86及 Pentium处理器的指令系统都包括了各自前期处理器的全部
指令, 并在此基础上对前期处理器的指令系统进行了增强和扩展 。
1,80286增强和扩展指令
80286指令系统除了包括所有的 8086指令及对上述部分指令进行了功能
扩展之外, 还新增了一些指令, 并在原有工作模式基础上增加了一种新
的工作模式, 即保护虚地址模式 。
(1) 80286工作模式
( a) 实地址模式 。 80286系统上电启动后, 就进入了实地址模式, 在此
模式下, 80286与 8086在目标代码一级是向上兼容的, 存储器最大的可访
问空间为 1MB,CPU产生 20位物理地址的方法, 段的结构以及存储区中专
用单元和保留单元均与 8086相同 。 在实地址模式下, 用 LMSW指令设置机
器状态字 MSW中的 PE标志, 可进入保护虚地址模式 。
( b) 保护虚地址模式 。 该工作模式是集实地址模式的能力, 存储器管理,
对虚拟存储器的支持和对地址空间的保护为一体而建立起来的一种特殊
工作方式 。 保护虚地址模式下的寄存器功能, 指令功能及寻址方式等与
实模式相同, 8086的程序及 80286在实地址模式下的程序都可以在保护虚
地址模式下运行 。
汇编语言 程序设计
(2) 80286扩展指令
( a) 堆栈操作指令
① PUSH 16位立即数
将 16位立即数压入堆栈, 该指令不影响状态标志位 。 该指令中立即
数如果给出的数不够 16位, 则自动扩展为 16位后压入堆栈 。
② PUSHA
将所有通用寄存器 AX,CX,DX,BX,SP,BP,SI,DI的内容按顺序
压入堆栈, 入栈的 SP值是执行该指令之前 SP的值, 在执行完本指令后
,SP值减 16。
③ POPA
将栈顶的内容顺序弹至 DI,SI,BP,SP,BX,DX,CX,AX( 次序
与 PUSHA指令相反 ) 。 SP中的值是堆栈中所有通用寄存器弹出后, 堆
栈指针实际指向的值 ( 不是栈中保存的 SP值 ), 也即该指令执行后 SP
的值, 可以通过加 16来恢复 。 PUSHA及 POPA均不影响状态标志位 。
汇编语言 程序设计
(b) 有符号整数乘法指令 。
① IMUL 16位寄存器, 立即数
将 16位通用寄存器中的有符号数作为被乘数, 与有符号立即数相乘
,乘积送回通用寄存器 。 若乘积超出字有符号数的表示范围
( -32768--+32767), 除丢失溢出部分外, 并将 OF及 CF置为 1;否则
,将 OF及 CF置为 0。
② IMUL 16位寄存器, 16位寄存器, 立即数
该指令与上一条指令功能类似, 区别仅在于将 16位存储器操作数作
为被乘数与立即数相乘, 结果送 16位寄存器 。
( c) 移位指令 。
8086中有 8条移位指令, 移位计数使用 CL或 1表示, 且规定当移位次
数大于 1时, 必须使用 CL。 在 80286中, 则修改了上述的限制, 当移位
次数为, 1~31次时, 允许使用立即数 。 例如,ROR BX,7。
汇编语言 程序设计
2,80386增强和扩展指令
80386微处理器是 Intel公司 80x86发展史上的里程碑, 它不但兼
容 8086,80186,80286微处理器, 而且也为后来的 80486,Pentium
,Pentium Pro的发展打下了坚实的基础 。
80386指令系统包括了所有 80286指令, 并对 80286的部分指令进
行了功能扩充, 还新增了一些指令, 特别指出的是, 80386提供了
32位寻址方式, 可对 32位数据直接操作 。 所有 16位指令均可扩充为
32位指令 。 80386有 8个 32位通用寄存器,EAX,ECX,EDX,EBX,
ESP,EBP,ESI,EDI。 它们分别是原来的 16位通用寄存器 AX,CX,
DX,BX,SP,BP,SI,DI的扩展 。 对于数据段寄存器, 80386在原
有基础上增加了两个,FS和 GS。
80386有实地址模式, 保护虚地址模式和虚拟 8086模式三种工作
方式, 在 DOS环境中只能运行实模式, 可做为超高速 8086芯片使用
。
80386的标志寄存器扩展到了 32位, 其中某些位没有定义 。 80386
在实地址模式下有 9个标志位可用, 在保护虚地址模式下有 13个标志
位可用, 扩展后的标志寄存器称为 EFLAGS。
汇编语言 程序设计
(1) 数据传送指令
( a) MOVSX 寄存器, 寄存器 /存储器
将源操作数传送到目的操作数中 。 目的操作可以是 16位或 32位寄
存器;源操作数可以是寄存器或存储器操作数, 其位数应小于或等
于目的操作数的位数 。 当源操作数的位数少于目的操作数时, 目的
操作数的高位用源操作数的符号位填补 。, 此指令适用于有符号数
的传送与扩展 。 该指令不影响状态标志位 。
( b) MOVZX 寄存器, 寄存器 /存储器
与 MOVSX功能基本相同, 惟一区别在于, 当源操作数的位数少于
目的操作数位数时, 目的操作数的高位用, 0” 填补 。 该指令适用于
无符号数的传送与扩展 。
汇编语言 程序设计
(2) 堆栈操作指令
( a) PUSH 32位立即数
将 32位立即数压入堆栈 。 该指令执行后 SP的值将减 4。 通常使用以下
方法来区别操作数是 8位, 16位还是 32位立即数,PUSH 23H,PUSHW
14H,PUSHD 45H。
( b) PUSHAD
将所有通用寄存器 EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI的内
容顺序压入堆栈, 其中压入堆栈的 ESP是该指令执行前 ESP的值 。 执行
该指令后, ESP值减 32。
( c) POPAD
将当前栈顶内容顺序弹至 EDI,ESI,EBP,ESP,EBX,EDX,ECX,
EAX( 次序与 PUSHAD指令相反 ), 但是最终 ESP的值为弹出操作对堆栈
指针调整后的值 ( 而不是堆栈中保存的 ESP的值 ) 。 即执行该指令后
ESP的值, 可以通过增加 32来恢复 。
( d) PUSHFD
将 32位标志寄存器 EFLAGS的内容压入堆栈 。
( e) POPFD
将当前栈顶的 4字节内容弹至 EFLAGS寄存器 。
上述堆栈操作指令中, 除 POPFD以外, 其余均不影响状态标志位 。
汇编语言 程序设计
(3) 地址传送指令
( a) LFS 寄存器, 存储器
将源操作数所指存储单元的 4字节或 6字节内容送指定的寄存器及段
寄存器 FS。
当目的操作数为 16位寄存器时, 将 4字节的存储器操作数中的低两字
节送指定寄存器, 高两字节送段寄存器 FS; 当目的操作数为 32位寄存
器时, 将 6字节的存储器操作数中的低 4字节送指定寄存器, 高两字节
送段寄存器 FS。 该指令不影响状态标志位 。
( b) LGS 寄存器, 存储器
该指令与 LFS指令功能基本相同, 惟一区别是该指令所涉及的段寄存
器为 GS。
( c) LSS 寄存器, 存储器
该指令与 LFS指令功能基本相同, 惟一区别是该指令所涉及的段寄存
器为 SS。
汇编语言 程序设计
(4) 有符号数乘法指令
( a) IMUL 寄存器, 寄存器 /存储器
将 16位或 32位通用寄存器中的有符号数作为被乘数, 相同位数通用
寄存器或存储单元中的有符号数作为乘数, 乘积送目的操作数 。 若乘
积溢出, 溢出位部分将丢失, 且将 OF及 CF置 1,否则将 OF及 CF置 0。
注意:目的操作数的位数必须与源操作数位相同 。
( b) IMUL 寄存器, 寄存器/存储器, 立即数
与前一指令功能基本相同, 惟一区别是寄存器 /存储器为被乘数, 立
即数为乘数, 乘积存放在第一个操作数中 。
(5) 符号扩展指令
( a) CWDE
将 AX中 16位有符号数的符号位扩展到 EAX的高 16位中, 即把 AX的 16位
有符号数扩展为 32位后, 送 EAX。
( b) CDQ
将 EAX中 32位有符号数扩展到 EDX,EAX寄存器对中, 使之成为 64位有
符号数, 即将 EAX中的符号位扩展到 EDX中 。
汇编语言 程序设计
(6) 位操作指令
( a) 位测试及设置指令
① BT 寄存器 /存储器地址, 寄存器 /立即数
第一操作数指定要测试的内容, 第二操作数指定要测试的位, 将被
测内容的指定测试位的值送 CF,其他状态标志不确定 。
② BTC 寄存器 /存储器地址, 寄存器 /立即数
该指令在 BT指令功能的基础上, 将被测位取反 。
③ BTR 寄存器 /存储器, 寄存器 /立即数
该指令在 BT指令功能的基础上, 将被测位清 0。
④ BTS 寄存器 /存储器, 寄存器 /立即数
该指令在 BT指令功能基础上, 将被测位置 1。
( b) 位扫描指令 。
① BSF 寄存器, 寄存器 /存储器
对第二操作数从最低位到最高位进行扫描, 将首先扫描到的, 1” 的
位号送第一操作数, 且使 ZF置 0。 若第二操作数的各位均为 0,则第一
操作数的值不确定, 且使 ZF置 1。 其他状态标志位不确定 。
② BSR 寄存器, 寄存器 /存储器
与 BSF指令功能基本相同, 惟一区别是该指令是从最高位到最低位
进行扫描 。
汇编语言 程序设计
(7) 移位指令
80386中增加了一组新的移动多位的指令 。 它们可以把指定的一组
位左移或右移到一 个操作数中去 。
( a) SHLD 寄存器 /存储器, 寄存器, CL/立即数
将第一操作数左移若干位,空出位用第二操作数高位部分填补, 但
第二操作数内容不变, CF标志位中保留第一操作数最后的移出位 。 若
仅移一位, 当 CF值与移位后的第一操作数的符号位不一致时, OF置 1
,否则, OF置 0。
( b) SHRD 寄存器 /存储器, 寄存器, CL/立即数
将第一操作数右移若干位, 空出位用第二操作数低位部分填补, 指
令执行后, 第二操作数内容不变, CF标志位保留第一操作数最后的移
出位 。
(8) 条件设置指令
这是 80386特有的指令用于测试指定的标志位所处的状态, 并根据
测试结果, 将指定的一个 8位寄存器或内存单元置 1或置 0。
指令格式,SET 条件 寄存器/存储器
说明:条件是指令助记符的一部分, 用于指定要测试的标志位 。
汇编语言 程序设计
3,80486新增指令
80486指令系统与 80386指令系统的差异不大, 仅仅是在 80386指令系
统的基础上新增了几条指令 。
( 1) 字节交换指令
格式,BSWAP 寄存器
功能:将 32位通用寄存器以字节为单位进行高低字节的交换, 即对
指定寄存器的 32位操作数的位 31- 24与位 7- 0,位 23- 16与位 15- 8交
换 。 该指令不影响状态标志位 。
( 2) 互换并相加指令
格式,XADD 寄存器 /存储器, 寄存器
功能:将第一操作数与第二操作数内容互换, 并将两者之和送第
一操作数 。 该指令对状态标志位的影响与 ADD指令相同 。
(3) 比较并交换指令
格式,CMPXCHG 寄存器 /存储器, 寄存器
功能:将第一操作数内容与对应长度累加器内容作比较, 若相等, 则
使 ZF置 1,且将第二操作数内容送第一操作数;否则使 ZF清 0,且第一
操作数送对应累加器 。 若 ( ESI) = ( EAX), 则 ZF=1,且将 ( EBX) 送
ESI; 否则 ZF=0,且将 ( ESI) 送 EAX。
汇编语言 程序设计
(4) Cache管理指令
(a) 使整个片内 Cache无效指令
格式,INVD
该指令用于将 CPU内部 Cache的内容无效 。 其具体的操作是刷新内
部 Cache,并分配一个专用总线周期刷新外部 Cache,执行该指令不
会将外部 Cache中的数据写回主存, 即 Cache中数据自然丢失 。
( b) 写回并使 Cache无效指令
格式,WBINVD
该指令功能与 INVD相似, 具体操作是刷新内部 Cache。 并分配一
个专用总线周期将外部 Cache的数据写回主存, 并在此后的一个专用
总线周期将外部 Cache刷新 。
( c) 使 TLB无效指令
格式,INVLPG
该指令使页式管理机构内的高速缓冲器 TLB中的某一项作废 。
若 TLB中含有一个存储器操作数映像的有效项, 则该 TLB项被标记为
无效 。
汇编语言 程序设计
4,Pentium新增指令
与 80486相比, Pentium新增了几条指令, 但某些新增的指令是否
有效与 Pentium的型号有关, 可利用处理器特征识别指令 CPUID判别
处理器是否支持某些新增指令 。
(1) 8字节比较交换指令
格式,CMPXCHG8B 存储器
功能:将 EDX,EAX中的 8字节值与指定的 8字节存储器操作数相比较
,若相等, 则使 ZF置 1,且将 ECX,EBX中的值送指定的 8字节存储单
元替换原有存储器操作数;否则使 ZF=0,且将指定的 8字节存储器操
作数送 EDX,EAX。
(2) 处理器特征识别指令
格式,CPUID
功能:根据 EAX中的参数, 将处理器的说明信息送 EAX,特征标志字
送 EDX。
汇编语言 程序设计
(3) 读时间标记计数器指令
格式,RDTSC
功能:将 Pentium中的 64位时间标记计数器的高 32位送 EDX,低 32
位送 EAX。 该计数器随每一个时钟递增, 在 Reset后该计数器被置 0
。 利用该计数器可检测程序运行性能 。
(4) 读模型专用寄存器指令
格式,RDMSR
功能:将 ECX所指定的模型专用寄存器的内容送 EDX,EAX,具体
来说, 高 32位送 EDX,低 32位送 EAX。 若所指定的模型寄存器不是 64
位, 则 EDX,EAX中的对应位无定义 。
(5) 写模型专用寄存器指令
格式,WRMSP
功能:将 EDX,EAX的内容送到由 ECX指定的模型专用寄存器 。 具
体来说, EDX和 EAX的内容分别作为高 32位和低 32位 。 若指定的模型
寄存器有未定义或保留的位, 则这些位的内容不变 。
返回