浅谈汇编,认识汇编(三)
今天我们来谈谈,常用的汇编指令。
还是以8086为主,其指令按功能可以分为下面几大类:
(1) 数据传送指令
(2) 算术运算指令
(3) 逻辑运算指令
(4) 移位指令
(5) 标志处理指令和CPU控制指令
(6) 转移和循环控制指令
(7) 调用和返回指令
(8) 字符串操作指令
(9) 输入输出指令
我觉得学习指令,主要是熟悉它的格式,功能和合法的操作数寻址方式三个方面。只要掌握这三个方面,指令也就会熟练运用。
下面来详细先来介绍下数据传送类指令:
数据传送类指令
数据传送指令主要是把数据,地址等送入寄存器或存储单元
1、 通用传送指令(MOV)
格式:MOV DST, SRC
功能:将操作数从SRC传输到DST
(注意:立即数只能做SRC;类型要一致;类型要明确,不明确时,要用PTR说明;CS不能做DST;当DS,ES,SS做DST时,SRC不能为立即数;两存储单元之间不能直接传送数据;两段寄存器之间不能直接传送数据)
MOV AX, BX
目的操作数寻址和源操作数寻址都为寄存器寻址,该指令的作用是将BX中的一个字送入到AX里
MOV AX, 02
目的操作数寻址为寄存器寻址,源操作数寻址为立即数寻址,该指令的作用是将02送入AX中
MOV [BX][DX], DX
目的操作数寻址为基址变址寻址,源操作数寻址为寄存器寻址,该指令的作用是将DL的内容送入到[BX][DX]所对应的存储单元里,将DH送入到[BX][DX]+1的存储单元中。
MOV 6[DI], 02
这条指令是错误的,因为目的操作数和源操作数类型都不明确,这里可以这样理解,02可以写成02H(一字节),那么就是将一个字节送入到6[DI]所对应的存储单元中。当然02也可以写成0002H(一个字),那么就是将低字节02H送入6[DI],高字节00H送入6[DI]+1,然而02这个数认为更大,所以立即数和存储单元都是不明确类型的.当然我们可以用PTR操作符来指明操作类型,如:MOV BYTE PTR 6[DI], 02 ,这样就指出该指令为字节操作。
MOV 2[SI], AL
这条指令是正确的,虽然存储单元不明确但AL是明确的,它就是一字节,所以两个操作数只要有一个类型明确了,就是合法的,两个操作数的类型自然就一致了。
MOV AX, BL
这条指令是错误的,因为类型不一致,目的为一字(两字节),而源操作数为一字节,故非法指令。
2、 取有效地址指令(LEA)
格式:LEA REG, SRC
功能:将源操作数SRC的有效地址(偏移地址)送入寄存器REG中
注意:该指令中REG不能为段寄存器,源操作数的寻址方式不允许是立即数和寄存器方式。也就是说这里的SRC涉及的寄存器只能是BX,BP,SI,DI。可以理解因为该指令是取地址,所以你的SRC寄存器一定是跟地址有关。(当然SRC也可以是直接寻址方式)这条指令,它传送的不是操作数本身,而是操作数的有效地址。比较一下下面的两条指令:
MOV AX, 06H[DI]
LEA AX, 06H[DI]
若DI的内容为0020H,第一条指令显然是通过偏移地址0026H计算出的物理地址所对应的存储单元的内容送入AX,而第二条指令是将0026H直接送入AX。
3、 取地址指针指令(LDS, LES)
格式:LDS REG, SRC
LES REG, SRC
功能:该指令的功能是将源操作数SRC的有效地址所对应的存储单元的32位内容分别送入DS(或ES)和指令中所指出的寄存器REG中,同样REG不允许段寄存器,源操作数不允许立即数和寄存器寻址。
POINT DD 01201000H
LDS DI, POINT
指令执行后,DI的内容为1000H,DS的内容为0120H
4、 标志传送指令(LAHF,SAHF)
格式:LAHF
SAHF
功能:LAHF是将标志寄存器中的低8位内容送入寄存器AH,SAHF是将AH中的8位内容送入标志寄存器的低8位。
我觉得这里有必要注意下标志寄存器的内容,从下图可以看出它的低8位是SF,ZF,
AF,PF和CF这5个标志位。
5、 数据交换指令(XCHG)
格式:XCHG OPR1, OPR2
功能:完成寄存器与寄存器或寄存器与存储单元之间的内容交换。该指令要求两个操作数之一必须是寄存器,允许两个数都是寄存器,但不允许是段寄存器。
XCHG AX, 1234H
该指令是非法的,因为立即数不能参加交换
XCHG DAT1, DAT2
该指令非法,因为两个存储单元之间不能直接交换
XCHG CH, CL
该指令合法,作用是将CX的高8位和低8位互相交换
6、 字节转换指令(XLAT)
格式:XLAT
功能:该指令的寻址方式为隐含寻址。其有效地址为BX和AL的内容之和,指令的功能是将有效地址所对应的存储单元的一个字节送入AL中
这里给出一个小程序方便理解:
7、 堆栈操作指令
关于堆栈的概念,这里我就不再多说了,大家不熟悉的可以再去了解下,涉及到了SS和SP。
(1)进栈指令(PUSH)
格式:PUSH SRC
功能:将SRC或标志寄存器FLAG的内容送入堆栈,并修改堆栈指针的内容,指令中的操作数不能是立即数(指令不能将一个常数压入堆栈,若需要将一常数压入,必须通过寄存器来实现)。SP的内容先减2,然后将SRC的低字节送入减后的SP所指的存储单元,SRC的高字节送入减后SP+1所指单元。
(2)出栈指令(POP)
格式:POP DST
功能:将SP所指的栈顶的内容取出,并送入DST所指寄存器,内存某单元或标志寄存器FLAG,并修正SP内容(DST必须为字类型)该指令先弹出栈顶内容,后修正SP内容,以SP+2修正。
这里看一个例子:
过程遵循堆栈的结构,后进先出的特点。
程序执行后,SP将仍指向0100H单元。
8、 符号扩展传输和零扩展传输
(1)MOVSX带符号扩展传送指令
格式:MOVSX DST, SRC
功能:该指令的源操作数可以是8位或16位的寄存器或存储单元的内容,而目的操作数则必须是16位或32位寄存器,传送是将SRC的内容送入DST的低位,用SRC的符号位填充DST的高位。8扩16或16扩32。
(2)MOVZX带零扩展传送指令
格式:MOVZX DST, SRC
功能:和带符号扩展的不同就是在于用0填充DST的高位,其他相同