3.2.1 数据传送类指令
把数据从一个位置传送到另一个位置
14条指令分 5组
1、通用数据传送,MOV XCHG XLAT
2、堆栈操作,PUSH POP
3、标志寄存器传送,LAHF SAHF PUSHF POPF
4、地址传送,LEA LDS LES
5、输入输出,IN OUT
学习要求
数据传送是计算机中最基本、最重要的一种操作。传送指令也是最常使用的一类指令。
传送指令把数据从一个位置传送到另一个位置。
除标志寄存器传送指令外,均 不影响标志 位重点掌握,MOV PUSH POP
特别熟悉,XCHG XLAT LEA
一般了解,LAHF SAHF PUSHF POPF LDS LES
以后展开,IN OUT
传送指令 MOV( move)
把一个字节或字的操作数从源地址传送至目的地址
MOV reg/mem,imm ;立即数送寄存器或主存,例 2.1
MOV reg/mem/seg,reg ;寄存器送(段)寄存器或主存,例 2.2
MOV reg/seg,mem ;主存送寄存器,例 2.3
MOV reg/mem,seg ;段寄存器送寄存器或主存,例 2.4
传送指令不是万能的,有不少非法传送的情况。
例子段寄存器:
CS/DS/ES/SS
通用寄存器:
AX/BX/CX
/DX
AH/AL/BH/
BL/CH/CL/
DH/DL
立即数
MEM
例 3.1:立即数传送
MOV AL,55H
MOV AX,55AAH
MOV CX,0F943H
MOV BYTE PTR [BX],12H ; 12h?DS:[BX]
MOV WORD PTR [BX+SI],100h ;
100h?DS:[BX+SI]
注意:立即数是 字节 ( byte)还是 字 ( word),
也就是明确指令是字节操作还是字操作。
进一步解释例 3.2:寄存器传送
MOV AX,BX
MOV AH,BL
例 3.3:存储器传送
MOV AX,[BX]
MOV [SI],AL
MOV SS,[2000H]
MOV ES:[DI],CS
注意:不存在存储器向存储器的传送指令进一步解释例 3.4:段寄存器传送
MOV AX,CS
MOV DS,AX
注意:对段寄存器的操作有一些限制进一步解释非法传送种种
两个操作数的类型不一致例如源操作数是字节,而目的操作数是字;或相反
两个操作数不能都是存储器传送指令很灵活,但主存之间的直接传送却不允许
段寄存器的操作有一些限制段寄存器属专用寄存器,对他们的操作能力有限实例实例实例交换指令 XCHG( exchange)
把两个地方的数据进行互换
XCHG reg,reg/mem ; reg←→reg/mem
交换指令可以在寄存器与寄存器之间对换数据交换指令可以在寄存器与存储器之间对换数据交换指令不能在存储器与存储器之间对换数据例 2.7
例 2.6
Why
例 3.6:寄存器与寄存器数据交换
MOV AX,1234H
MOV BX,5678H
XCHG AX,BX
。操作该段程序执行完,AX=5678H,BX=1234H
例 3.7:寄存器与存储器数据交换
MOV BP,0200H
MOV SI,0046H
XCHG AX,[BP+SI] ;这里是 BP,则对应的段寄存器为 SS
设 SS=5000H,则存储单元的物理地址
PA=SS*16+EA=50000H+0200H+0046H=50246H,
指令执行前,AX=5621H,( 50246H) =12H,( 50247H) =34H
指令执行后,AX=3412H,( 50246H) =21H,( 50247H) =56H
换码指令 XLAT( translate)
将 BX指定的缓冲区中、
AL指定的位移处的一个字节数据取出赋给 AL
XLAT ; al←ds:[bx+al],例 2.8
换码指令执行前:
在主存中建立一个字节表格,内容是要转换成的目的代码,
表格的首地址存放于 BX,AL存放相对表格首地址的位移量
然后,执行换码指令:
将 AL寄存器的内容转换为目标代码隐含寻址方式例 3.8:代码转换
换码指令没有显式的操作数,但使用了 BX和 AL;
因为换码指令使用了隐含寻址方式。
隐含寻址方式 —— 采用默认操作数的寻址方式。
例2,8
例 3.8,将 0~9,A~F的 16 进制数转换为 ASCII码并显示
.MODEL SMALL
.STACK
.DATA
TABLE DB '0123456789ABCDEF'; 0~9,A~F的 ASCII码
.CODE
.STARTUP
MOV BX,OFFSET TABLE
MOV AL,10
XLAT ; AL=41H,为 A的 ASCII码
MOV DL,AL
MOV AH,02H
INT 21H
.EXIT 0
END
堆栈操作指令
堆栈的概念
堆栈的操作,进栈和出栈
堆栈的特点
PUSH r16/m16/seg;进栈指令:; SP←SP - 2; SS:[SP]←r16/m16/seg
POP r16/m16/seg;出栈指令:; r16/m16/seg←SS:[SP]; SP←SP + 2
什么是堆栈
堆栈是一个,先进后出,
的主存区域,位于堆栈段中,使用 SS段寄存器记录其段地址。
堆栈只有一个出口,即当前栈顶。栈顶是地址较小的一端(低端),
它用堆栈指针寄存器 SP
指定。图 a中的堆栈是个空栈。
堆栈的操作堆栈只有两种基本操作:进栈和出栈,
对应两条指令 PUSH和 POP。
进栈指令 PUSH:
进栈指令先使堆栈指针
SP减 2,然后把一个字操作数存入堆栈顶部出栈指令 POP:
出栈指令把栈顶的一个字传送至指定的目的操作数,然后堆栈指针 SP加 2
请参看实 例 2.9和例 2.10
请对照 图 b和图 c
堆栈的实例和图例
MOV AX,1278H
PUSH AX
POP AX操作堆栈的特点
堆栈操作的单位是字,进栈和出栈只对字量
字量数据从栈顶压入和弹出时,都是低地址字节送低字节,高地址字节送高字节
堆栈操作遵循先进后出原则
可用存储器寻址方式随机存取堆栈中的数据
堆栈常用来临时存放数据传递参数保存和恢复寄存器例 2.11
有效地址传送指令 LEA( load EA)
将存储器操作数的有效地址传送至指定寄存器中
LEA r16,mem ; r16←mem 的有效地址例 2.12:有效地址的获取
LEA BX,[2000H] ;把 [2000H]操作数的偏移地址送给 BX
指令执行后,BX=2000H。要注意和
MOV BX,[2000H]的区别,它是把 DS:
[2000H]的内容送给 BX。
操作指针传送指令
LDS r16,mem; r16←mem,; DS←mem+2
LDS指令将主存中 mem
指定的字送至 r16,并将 mem的下一字送 DS寄存器
LES r16,mem; r16←mem,; ES←mem+2
LES指令将主存中 mem
指定的字送至 r16,
并将 mem的下一字送
ES寄存器例 2.13 例 2.14
例 3.13:
LDS BX,ADDRx[SI]
若 DS=2000H,SI=1000H,ADDRx=0020H,则存储器操作数的物理地址是:
PA=DS*16+EA=20000H+1000H+0020H=21020H 。
指令执行前,BX=6543H,( 21020H) =1040H,
( 21022H) =4000H 。
指令执行后,BX=1040H,DS=4000H,( 21020H)
=1040H,( 21022H) =4000H 。
操作例 3.14
LES BX,[SI]
若 DS=2000H,SI=1000H,则存储器操作数的物理地址是:
PA=DS*16 =20000H+1000H=21000H 。
设指令执行前:( 21000H) =1400H,( 21002H)
=4000H 。
指令执行后,BX=1400H,ES=4000H,( 21000H)
=1400H,( 21002H) =4000H 。
标志低字节出入 AH指令
LAHF; AH←FLAGS 的低字节
LAHF指令将标志寄存器的低字节送寄存器
AH
SF/ZF/AF/PF/CF状态标志位分别送入 AH的第 7/6/4/2/0位,而 AH
的第 5/3/1位任意
SAHF; FLAGS的低字节 ← AH
SAHF将 AH寄存器内容送 FLAGS的低字节
用 AH的第 7/6/4/2/0
位相应设置
SF/ZF/AF/PF/CF标志标志寄存器出入堆栈指令
PUSHF; SP←SP - 2; SS:[SP]←FLAGS
PUSHF指令将标志寄存器的内容压入堆栈,
同时栈顶指针 SP减 2
POPF; FLAGS←SS:[SP]; SP←SP + 2
POPF指令将栈顶字单元内容送标志寄存器,
同时栈顶指针 SP加 2
例 2.15
输入输出指令
IN AL/AX,i8/DX; AL/AX←I/O 端口
输入 IN指令将外设数据传送给 CPU内的
AL/AX
OUT i8/DX,AL/AX; I/O端口 ← AL/AX
输出 OUT指令将 CPU内的 AL/AX数据传送给外设
8086通过输入输出指令与外设进行数据传送输入输出指令
8086通过输入输出指令与外设进行数据交换;
呈现给程序员的外设是 端口 ( Port)即 I/O地址
8086用于寻址外设端口的地址线为 16条,端口最多为 216= 65536( 64K)个,端口号为
0000H~ FFFFH
每个端口用于传送一个字节的外设数据输入输出寻址方式
8086的 端口有 64K个,无需分段,设计有两种寻址方式
直接寻址,只用于寻址 00H~ FFH前 256个端口,
操作数 i8表示端口号
间接寻址,可用于寻址全部 64K个端口,DX寄存器的值就是端口号
对大于 FFH的端口只能采用间接寻址方式
OUT 61H,AL ; 把 AL的内容输出到端口 61H中
OUT 20H,AX ;把 AX的内容输出到端口 20H,21H
MOV DX,3C0H
OUT DX,AL ;把 AL的内容输出到端口 3C0H中
OUT DX,AX ;把 AX的内容输出到端口 3C0H,3C1H
例 3.17OUT