汇编语言02:8086数据传送指令

计算机的指令系统就是指该计算机能够执行的全部指令的集合。Intel 8086指令系统可以分为6类:数据传送类指令、算术运算类指令,位操作类指令,控制转移类指令、串操作类指令、处理机控制类处理指令。在介绍指令时,一般从具体操作,寻址方式和对标志影响三个方面来描述。

数据传送指令是最常使用的一类指令。8086有14种传送指令。其中又分为通用数据传输指令、堆栈操作指令、标志传送指令、地址传送指令。

1、通用数据传输指令

传送指令MOV

MOV是最普通的传送指令,其主要格式如下:

MOV  dest,src ;  dest<-src

操作:MOV指令将1字节或者字的操作数从源地址传送至目的地址。

寻址方式:绝大多数的传送方式都是被认可的,但是不能进行以下的寻址方式组合。

  • 立即数传送到段寄存器
  • 主存直接传送到主存(非串操作时)。
  • 段寄存器直接传送到段寄存器。

对于后一种操作,可以使用reg<-mem,mem<-reg的间接操作来实现。

标志影响:无。

另外,在进行立即数传送时,如果立即数开头是字母,为了和指令相区别,需要在最高位前方加0。例如:

MOV CX,0FFH

该指令中的立即数FFH最高位是F,为了和指令相区别,在前方加0表示这是立即数。

在立即数传送方式中,当目的操作数寻址是寄存器寻址,一般对于数据类型都有明确要求(字节或者字);但是目的操作数是存储器寻址时则没有明确要求,这时需要显式指出是byte ptr(字节操作)还是word ptr(字操作)。例如下方指令:

MOV byte ptr[SI], 0AH; DS:[SI]<-0AH

该指令执行字节操作,将立即数0AH传送到SI寄存器。

交换指令XCHG

交换指令用来将源操作数和目的操作数内容交换,其格式如下:

XCHG reg,reg/mem;

同理,XCHG指令可以在通用寄存器与通用寄存器或存储器之间交换,但是不能在两存储器之间交换数据。例如如下指令:

MOV AX,1234H; AX = 1234H
MOV BX,5678H; BX = 5678H
XCHG AX,BX; AX = 5678H , BX = 1234H
XCHG AH,AL; AX = 7856H

将XCHG的源操作数和目的操作数对换位置,产生的结果是一样的。

换码指令XLAT

操作:换码指令用于将BX指定的缓冲区中,AL指定的位移处的数据取出赋给AL,格式如下:

XLAT label
XLAT   ; AL<-DS:[BX+AL]

上行和下行的指令是完全等效的。例如要将100H的表格缓冲区的3号数据取出:

MOV BX 100H
MOV AX 03H
XLAT

换码指令如其名,一般常用于转换代码。一般在BX规定的内存处建立一个换码表格,将需要转换的代码存储在AL处。进行MOV,XLAT,MOV的循环方式将输入AL的代码进行转换并且输出到另外一个位置。

需要注意的是,由于AL是8位的,故表格最大长度只能是256。超过这个长度的表格需要用修改BX和AL的方式进行查找。

标志影响:无。

2.堆栈操作指令

栈属于LIFO或者FILO结构,由于堆栈存在自动指针SP,因此堆栈操作指令只有两个:进栈指令PUSH和出栈指令POP。

进栈指令PUSH

操作:把一个字操作数存入堆栈顶部。注意,只能是字操作数。进栈时,采用小端方式。其格式如下:

PUSH r16/m16/seg; sp<-sp-2, SS:[SP]<-r16/m16/seg

寻址方式:源操作数可以是立即数,存储器有效地址或者16位寄存器。

标志影响:SP向低地址移动两字节单元。

出栈指令POP

操作:把栈顶的一个字传送至指定的目的操作数。从栈顶弹出时,采用小端方式。其格式如下:

POP r16/m16/seg ;  r16/m16/seg<- SS:[SP], sp<-sp+2

寻址方式:目的操作数可以是通用寄存器,段寄存器或者存储器有效地址。

标志影响:SP向高地址移动两字节单元。

堆栈操作指令的应用

堆栈指令可以用来在子程序执行完后恢复被修改的寄存器内容,可以使用如下方法

;现场的保护与恢复
;调用子程序前
PUSH AX
PUSH BX
PUSH DS
...
;返回主程序前
POP DS
POP BX
POP AX

注意:POP的顺序和PUSH指令相反,这是因为堆栈采用的是LIFO的结构。

如果进入堆栈的数据超出了堆栈设置的范围,就会产生常见的stackoverflow错误,轻的情况下程序会出错,严重的情况下可能导致系统崩溃。

堆栈操作还可以和一些子程序指令相结合。例如使用子程序控制的CALL(子程序调用)、RET(子程序返回)、INT(中断调用)和IRET(中断返回)等指令,还有内外部异常都会导致堆栈的使用和SP值的修改。因此,在使用POP出栈指令时一定要清楚当前的栈顶数据。

堆栈可以以随机存取的方式读写其中的数据。例如如下指令:

MOV BP,SP
MOV AX,[BP+4]
MOV [BP],AX

上述指令将栈顶的数据传到了栈的下方。这说明了主程序和子程序之间传递参数的部分原理。注意,由于BP实际上指向主存,因此指令“XCHG  [BP],[BP+4]"是非法的。

使用汇编进行编程时,注意入栈和出栈的数据要成对,要保持堆栈平衡。

3.标志传送指令

在上一章讲到,8086存在着6种状态标志CF,PF,AF,ZF,SF,OF。在程序的过程中,有时候这些标志的传递非常重要,否则会导致程序出现意外的执行结果。标志传送指令用来传送标志寄存器FLAGS的内容,主要有LAHF/SAHF,PUSHF/POPF指令,以及一些标志位操作指令。

标志送AH指令LAHF

操作:将标志寄存器FLAGS的低字节送寄存器AH,其标准格式如下:

LAHF        ; AH<-FLAGS的低字节

其中SF/ZF/AF/PF/CF分别送第7/6/4/2/0位,其他位随意。

寻址方式:操作数固定。

标志影响:FLAGS低字节->AH

AH送标志指令SAHF

操作:将AH寄存器内容送FLAGS的低字节,其标准格式如下:

SAHF          ;FLAGS的低字节<-AH

其中AH的第7/6/4/2/0位分别送SF/ZF/AF/PF/CF。

寻址方式:操作数固定。

标志影响:AH->FLAGS低字节。

由上课件,LAHF和SAHF是一对功能相反的指令。

标志进栈指令PUSHF

操作:将标志寄存器的内容压入堆栈,同时使栈顶指针SP-2。和上方两条指令不同,PUSHF指令可以用来保存全部标志位。其标准格式如下:

PUSHF       ;SP<-SP-2,SS:[SP]<-FLAGS

寻址方式:操作数固定。

标志影响:FLAGS->SP。

标志出栈指令POPF

操作:与PUSHF相反。其标准格式如下:

POPF        ;FLAGS<-SS:[SP],SP<-SP+2

使用标志的栈操作指令可以对标志寄存器的一些内容作出修改。下方代码实现了对单步标志TF的修改。

PUSHF
POP AX
OR AX 0100H;  修改第9位TF
PUSH AX
POPF

不一定所有的标志都需要通过栈操作进行更改。下面的几个指令可以实现对某些标志的修改。

标志位操作

标志位操作指令可以对CF,DF和IF三个标志位进行设置。具体表示如下:

CLC ;复位进位标志(CLR CF)
STC ;置位进位标志(SET CF)
CMC ;求反进位标志(COMP CF)
CLD ;复位方向标志
STD ;置位方向标志
CLI ;复位中断标志
STI ;置位中断标志

除了CF,DF和IF之外,其他的标志改变都需要经过栈操作。

对标志进行更改,为什么不直接使用LAHF/SAHF指令呢?原因是LAHF/SAHF只传送了五位,不能起到全面的效果。为了保持规范,通常还是采用栈操作的办法。

4.地址传送指令

地址传送指令会将存储器的逻辑地址传送至指定的寄存器。

有效地址传送指令LEA

操作:将存储器操作数的有效地址传送至指定寄存器。其具体格式如下:

LEA r16,mem

得到的是一个有效地址,需要注意段前缀。

寻址方式:源操作数使用(相对)基址变址寻址方式。

标志影响:无。

指针传送指令

操作:LDS或者LES指令将主存中指定的字送至16位寄存器,并将MEM的下一个字送到DS或者ES寄存器。其主要格式如下:

LDS r16,mem     ;r16<-mem,DS<-mem+2
LES r16,mem     ;r16<-mem,ES<-mem+2

之所以叫做逻辑地址,是因为上述指令实际上传送了四字节,可以看作段基:偏移的逻辑地址,也就传送了32位的地址指针。

寻址方式:存储器寻址方式。

标志影响:无。

总结

汇编语言的数据传送类指令,或是程序内直接传输数据,或是通过堆栈进行程序间数据传输,或是传输标志,或者传送指针,都具有明确的目的性,需要在应用的同时仔细分辨理解。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值