BTS DST,SRC ;检查DST中由SRC指定的位,并将其复制到CF中,然后该位置1
BTR DST,SRC ;检查DST中由SRC指定的位,并将其复制到CF中,然后该位清0
BTC DST,SRC ;检查DST中由SRC指定的位,并将其复制到CF中,然后该位取反 例如:
BTS AX,7 ;(AX)的位7→CF,1→AX7 (2)位扫描指令
BSF REG,SRC ;从右到左扫描源操作数SRC中的各位 4.移位指令
这类指令可将寄存器与存储器单元8/16/32位二进制数进行逻辑移位、算术移位或循环移位。在移位过程中,这些指令都把CF看作扩展位,用它接收从操作数最左或最右移出的一个二进位。 SHL DST,SRC ;逻辑左移,SRC决定移位次数,最高位进入标志位CF,最低位补0
SHR DST,SRC ;逻辑右移,操作与SHL类似,不同的只是移位方向相反 SAL DST,SRC ;算术左移,操作与SHL相同,但符号位发生变化时,OF置1 SAR DST,SRC ;算术右移,操作与SHR类似,但每次移位通过复制保持号位不变
ROL DST,SRC ;循环左移,移出的位送到操作数的另一端,CF不参加循环移位
ROR DST,SRC ;循环右移,移出的位送到操作数的另一端,CF不参加循环移位
RCL DST,SRC ;带进位循环左移,CF作为操作数的扩展,一起参加循环移位
RCR DST,SRC ;带进位循环右移,CF作为操作数的扩展,一起参加循环移位
SHRD DST,REG,SRC ;双精度右移 SHLD DST,REG,SRC ;双精度左移 5.串操作指令
串操作指令用来处理存储器中存放的字节、字或双字数据串。 ①MOVS:串传送指令,DS:SI/ESI指向的数据串传送到ES:DI/EDI指向的内存区。 ②CMPS:串比较指令,比较DS:SI/ESI和ES:DI/EDI指向的数据串,若相同,则ZF=1。
③SCAS:串扫描指令,用ACC中的关键字扫描ES:DI/EDI指向的目标串,若相同,则ZF=1。
④LODS:取串指令,将DS:SI/ESI指向的数据串元素取到ACC中。
⑤STOS:存串指令,将ACC中的内容存入ES:DI/EDI指向的内存单元中。
⑥INS:串输入指令,从DX指示的端口取数据串到ES:DI/EDI指向的内存区。 ⑦OUTS:串输出的指令,将DS:SI?ESI指向的数据串传送到DX指示的端口中去。 6.控制转移指令 1)无条件转移指令
这种类型的指令无条件转移到目标地址执行程序。按不同的寻址方法可以分为以
下6种指令形式。
JMP SHORT DST ;段内直接短转移,-128~+127B范围相对转移,DST为标号 JMP NEAR PTR DST ;段内直接近转移,±32 KB范围相对转移,DST为标号 JMP DST ;段内直接转移,64 KB范围绝对转移,DST为寄存器 JMP WORD PTR DST ;段内间接转移,64KB范围绝对转移,DST为存储单元 JMP FAR PTR DST ;段间直接转移,段外绝对转移,DST为标号 JMP DWORD PTR DST ;段间间接转移,段外绝对转移,DST为存储单元 2)条件转移指令
这种类型的指令是以标志位的状态或者以标志位的逻辑运算结果作为转移依据,这类指令都是采用段内直接短转移,转移地址的偏移量限制在-128~+127B范围内。
3)条件设置指令 指令格式如下: SETcc DST
4)条件传送指令 指令格式如下: CMOVcc REG,DST 5)循环指令
循环指令用于控制程序的重复执行,它们以CX/ECX寄存器为计数器,在其中预置程序的循环次数,并根据对CX/ECX内容的测试结果来决定程序是循环至目标地址,还是顺序执行循环指令的下一条指令。 按控制循环的方式,循环指令有以下4种形式。 LOOP DST ;(CX/ECX)-1≠0,则循环
LOOPZ/LOOPE DST ;(CX/ECX)-1≠0且ZF=1,则循环 LOOPNZ/LOOPNE DST;(CX/ECX)-1≠0且ZF=0,则循环 JCXZ/JECXZ ;(CX/ECX)=0,则转移 6)调用和返回指令 (1)CALL调用指令
下面是CALL指令的几种基本类型:
CALL NEAR PTR DST ;段内直接调用(NEAR PTR可省略),DST为子程序入口地址
CALL DST ;段内间接调用,DST为寄存器 CALL WORD PTR DST ;段内间接调用,DST为存储单元
CALL FAR PTR DST ;段间直接调用,DST为子程序入口地址 CALL DWORD PTR DST ;段间间接调用,DST为存储单元 (2)RET返回指令
该指令通常放在子程序的末尾,使子程序执行完毕以后能够返回主程序继续执行原来的程序。执行该指令后应该把返回地址出栈送IP寄存器(段内或段间调用时)和CS寄存器(仅段间调用)。 7)中断指令
80x86微处理器提供了以下3条中断指令。
INT TYPE ;TYPE为中断类型号,取值范围为0~255
INTO ;溢出中断指令,若OF=1,产生类型号为4的中断服务 IRET/IRETD ;中断返回指令,偏移地址和段地址送CS:IP/EIP,恢复
FLAGS/EFLAGS
7.处理器控制指令
处理器控制指令用于控制处理器的某些功能,下面只介绍常用的4种类型。 1)标志操作指令
①STC:进位标志置1(set carry)。 ②CLC:进位标志置0(clear carry)。
③CMC:进位标志取反(complement carry)。 ④STD:方向标志置1(set direction)。 ⑤STI:中断允许标志置1(set interrupt)。 ⑥CLI:中断允许标志置0(clear interrupt)。 2)外部同步指令
①NOP:空操作指令,除了使指令指针加1以外,不执行任何操作。 ②HLT:使处理器处于暂停状态。
③WAIT:使处理器处于空转状态 ,定期检查TEST信号是否为低电平。
④ESC:换码指令,可作为其他指令的前缀联合使用,以保持总线的封锁信号。 3)高级语言支持指令
(1)内存存储范围检查指令 指令格式如下: ROUND r,mem
(2)设置与撤销堆栈空间的指令 ENTER i16,i8 ;为过程参数建立一个堆栈区,其中i16指出过程所需要的堆栈字节数
;i8指出过程的嵌套层数(0~31) LEAVE ;撤销前面ENTER指令建立的堆栈区 4)处理器特征识别指令CPUID 2.4 80x86宏汇编语言
2.4.1 汇编语言及其程序结构
汇编语言是机器语言的符号表示,用汇编语言编写的程序不仅容易阅读和理解,而且可以很方便地借助于汇编程序MASM和连接程序LINK对方扩展名为.asm的源程序进行汇编与连接,逐步生成扩展名为.obj的目的程序和护展名的.exe的可执行程序,从而为计算机的软件开发提供了新的支持。 汇编语言编写的程序有以下几个特点。
(1)汇编语言程序以SEGMENT和ENDS把整个程序分成若干段 (2)代码段中可以用PROC和ENDP伪指令定义若干过程
(3)整个程序必须用END语句结束,表示汇编源程序到此为止 2.4.2 80x86宏汇编语言的数据与表达式 1.常量
常量是汇编时已经确定的值,主要用于伪指令中给变量赋值,或作为指令语句中的立即数或存储操作数的组成部分。 2.变量
变量用于定义存储器中的数据,这些数据在程序运行过程中可以随时修改。变量名可以认为是存放数据的存储单元符号地址,它的3个属性是: (1)段属性,指变量所在的段基址。
(2)偏移地址属性,指变量所在地与段基址之间的偏移量。
(3)类型属性,指变量占用存储单元的字节数。 3.标号
标号是给指令性语句所在地址取的名字,它表明该指令在存储器中的位置,可以作为转移类指令的操作数,以确定程序转移的目标地址。 4.表达式和运算符 常量、变量和标号是汇编语言中表示数据的基本形式。在实际使用中往往需要将这3种基本形式的数据用运算符把它们组合起来形成表达式作为汇编语言的数据。
80x86宏汇编语言允许使用的表达式有两种类型:一类是数值表达式,它只产生一个数值结果;另一类是地址表达式,它所产生的结果是一个存储器地址,如果这个地址存放的是数据,则称它为变量,如果这个地址中存放的是指令,就称它为标号。
运算符主要包括以下6种类型。 1.算术运算符
算术运算符包括加(+)、减(-)、乘(*)、除(/)、模除(MOD)、左移(SHL)和右移(SHR)共7种。 2.逻辑运算符
逻辑运算符包括AND(与)、OR(或)、XOR(异或)、NOT(非)共4种,它们只适用于对常量进行逻辑运算。 3.关系运算符
关系运算符包括EQ(相等)、NE(不等)、LT(小于)、GT(大于)、LE(小于等于)、GE(大于等于)共6种。 4.数值返回运算符
这种运算符的运算对象必须是存储器操作数,即变量或标号。运算符总是加在运算对象之前,返回的结果是一个数值。 (1)SEG运算符
该运算符加在变量名称或标号之前,返回的数值是该变量或标号所在段的段基址。
(2)OFFSET运算符
该运算符加在变量或标号之前,返回的数值是该变量或标号在段内的偏移地址。例如:
MOV SI,OFFSET ARRAY (3)TYPE运算符
TYPE运算符加在变量名之前,返回该变量以字节数表示的类型,DB、DW、DD、DF、DQ、DT定义的变量类型分明用1、2、4、6、8、10表示,而当TYPE加在标号之前,则返回该标号类型的数值,NEAR和FAR标号类型分别用-1和-2表示。 (4)LENGTH运算符 该运算符加在变量之前,返回的数值是变量中所定义的元素个数。如果变量用重复数据操作符DUP说明,则返回外层DUP前面的数值;如果没有DUP说明,则返回的值总是1。
(5)SIZE运算符
该运算符加在变量之前,返回的数值是变量所占的总字节数,且等于LENGTH和TYPE两个运算符返回值的乘积。 5.修改属性运算符
(1)该运算符用来指明某个变量、符号或地址表达式的类型或距离属性,或者使它们临时兼有与原定义不同的类型属性,但保持它们原来的段属性和偏移地址属性。其使用格式如下: <类型>PTR<地址表达式>
根据地址表达式的不同,所赋给的新类型可以是BYTE、WORD、DWORD、NEAR、FAR,它们只在所在的指令内有效。 (2)THIS运算符
该运算符用来把它后面指定的类型或距离属性赋给当前的变量、符号或地址表达式,但不分配新的存储单元,下一个能分配存储单元的段和偏移地址就是它的段和偏移地址。其使用格式如下: THIS<类型>
注意,该运算符必须与伪操作命令EQU(或=)连用,类型属性可以是BYTE、WORD、DWORD、NEAR、FAR。 (3)HIGH和LOW运算符
HIGH和LOW运算符分别用于从运算对象中分离出高字节和低字节。 (4)SHORT运算符
用于说明转移指令的目标地址与本指令之间的字节距离在-128~+127范围内。 6.其他运算符
(1)圆括号运算符()
用于改变运算符的优先级别。 (2)方括号运算符[]
该运算符中可以是数组变量的下标或地址表达式,以区别操作数的操作数地址。 4.3 80x86宏汇编语言的伪指令语句 80x86宏汇编语言有两种类型的语句,其中指令性语句是80x86微处理器的各种符号指令,它们在汇编过程中被翻译成相应的目标代码,并经过连接后生成计算机可执行的机器指令代码;而伪指令语句使用的是各种伪操作命令,它们在汇编时被解释执行,其功能是为汇编程序提供一些信息,以便能正确地把指令性语句翻译相成应的机器指令代码。
下面分别介绍这些为操作命令的功能及使用方法。 1.符号定义伪指令
符号定义伪指令用于给程序中多次出现的同一个常量或表达式赋一个符号名,也可以为其他符号名取一个新名子,并赋给新的类型属性。 (1)EQU
这是一种等值为操作命令,其语句格式如下: <符号名>EQU<表达式> 其中表达式可以是数值、地址或新的类型属性,也可以是其他符号名,它们与EQU左边所赋给的符号名完全等价,因而在程序中可以方便地用符号名来取代它们。 (2)“=”
该伪操作命令与EQU具有相同的功能,但它定义的符号允许重新定义。其语句格式如下:
<符号名>=<表达式> (3)LABEL
该伪操作命令为当前存储单元定义一个指定类型的变量或符号。语句格式如下: <变量名>LABEL<类型>