汇编传送指令

----------------------------------------------------------------------------------------------------------------------------

r8——任意一个8位通用寄存器AH/AL/BH/BL/CH/CL/DH/DL
r16——任意一个16通用寄存器AX/BX/CX/DX/SI/DI/BP/SP
reg——代表r8或r16
seg——段寄存器CS/DS/ES/SS
m8——一个8位存储器操作数单元(包括所有主存寻址方式)
m16——一个16位存储器操作数单元(包括所有主存寻址方式)
mem——代表m8或m16
i8——一个8位立即数
i16——一个16位立即数
imm——代表i8或i16
dest——目的操作数
src——源操作数

----------------------------------------------------------------------------------------------------------------------------
一、通用数据传送指令
1、传送指令MOV
格式:MOV dest,src    ;dest←src
MOV指令把一个字节或字的操作数从源地址src传送至目的地址dest。源操作数可以是立即数、寄存器或是主存单元,目的操作数可以是寄存器或主存单元,但不能是立即数。用约定的符号表达如下:


MOV reg/mem,        imm             ;立即数送寄存器或是存储器
MOV reg/mem/seg,  reg              ;寄存器送寄存器(包括段寄存器)或贮存
MOV reg/seg,          mem            ;主存送寄存器(包括段寄存器)
MOV reg/mem,        seg              ;段寄存器送主存或寄存器
特别说明:(1)立即数传送至通用寄存器(不包括段寄存器)或存储单元
MOV reg/mem,imm
例:
mov al,4                            ;al←4,字节传送
mov cx,0ffh                       ;cx←00ffh,字传送
mov byte  ptr [si],0ah         ;ds:[si]←0ah,       byte ptr说明是字节操作
mov word ptr [si+2],0bh     ;ds:[si+2]←0bh,  word ptr 说明是字操作
绝大多数说操作数的指令中(除非特别说明)目的操作数与源操作数必须类型一致,或同为字节,或同为字,否则为非法指令。8086不允许立即数传送至段寄存器。
特别说明(2)8086指令系统除串操作类指令外,不允许两个操作数都是存储单元,所以也就没有主存至主存的数据传送 。可以通过寄存器间接实现

。例:
mov ax,buffer1       ;ax←buffer1(将buffer1内容送ax)
mov buffer2,ax       ;buffer2←ax
                             ;buffer1、buffer2实际表示直接寻址方式


虽然存在通用寄存器和存储单元向CS段寄存器传送数据的指令,但却不允许执行 。因为这样直接改变CS值,将引起程序执行混乱。如MOV CS,[SI]是不允许使用的指令
特别说明(3)段寄存器传送到通用寄存器(不包括段寄存器)或存储单元。例:
mov [si],ds
mov ax,es
但是,不允许段寄存器之间的直接数据传送 ,如:MOV DS,ES是非法指令。

----------------------------------------------------------------------------------------------------------------------------

实践操作:数据块传送程序

例1:将以S1为其实地址的30个字符依次传送到同数据段的以S2为起始地址的一片字节存储单元里。
方法一:数据块是用DB定义的一个字符串S。用变址寄存器间接寻址方式访问S1和S2,即用[SI]表示S1中个字节的位移量,用[DI]表示S2中个字节的位移量。
完整程序:
NAME EX1-1
DATA     SEGMENT
S1         DB 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123'
S2         DB 30 DUP(?)
DATA     ENDS
CODE    SEGMENT
            ASSUME DS:DATA,CS:CODE
START: MOV AX,DATA                               ;数据段寄存器的填充
            MOV DS,AX                                   ;
            MOV SI,OFFSET S1                        ;S1的位移量→SI
            MOV DI OFFSET S2                       ;S2的位移量→DI
            MOV CX,30                                  ;循环次数30→CX
NEXT:   MOV AX,[SI]                                ;([SI])→AL
            MOV [DI],AX                                ;(AL)→[DI]
            INC SI                                        ;(SI)+1→SI
            INC DI                                        ;(DI)+1→DI
            LOOP NEXT                                  ;(CX)-1→CX,(CX)=0时循环结束
            MOV AH,4CH                               ;程序结束
            INT 21H                                      ;返回系统
CODE   ENDS
           END START


方法二:用db定义30个字节的字符数据标的方法来定义的数据块s1。用变址+16位位移量的寄存器相对寻址方式(即s1[SI]和S2[SI])访问S1 和S2,即用[SI]表示距离S1(或S2)的起始地址的字节数(相对位移量),用16位的直接位移量S1(或S2)加上[SI]中的相对位移量,表示 S1或S2中的各字节的位移量(有效地址)。SI寄存器的取值应为0~29,每次循环SI加1。
完整程序:
NAME EX1-2
DATA     SEGMENT
S1         DB 'ABCDEFGHIJKLMNOPQISTUVWXYZ0123'
S2         DB 30 DUP (?)
DATA     ENDS
CODE     SEGMENT
             ASSUME DS:DATA,CS:CODE
START:  MOV AX,DATA
             MOV DS,AX
             MOV SI,0H
             MOV CX,30
NEXT:    MOV AL,S1[SI]
            MOV S2[SI],AL
            INC SI
            LOOP NEXT
            MOV AH,4CH
            INT 21H
CODE    ENDS
            END START


方法三:数据块用DW伪指令定义15个字的数据表,每次分配两个字符。由于8086/8088微处理器是小端方式存储,为了等效一、二方法里用DB定义的字符串,数据必须写成:'BA','DC',…,'32'形式。采用相对基址变址寻址方式(即[BX+SI]和[BX+SI+30])来访问S1和S2中各字(S1、S2在内存分配上是相邻的)。将S1的起始地址[OFFSET S1]送至BX,用[SI]表示距离S1(或S2)的起始地址的字节数(相对位移量),且数据块传送时以字为单位,SI寄存器的取值为 0,2,...,28,循环15次。
完整程序:
NAME EX1-3
DATA     SEGMENT
S1          DW 'BA','DC','FE','HG','JI','LK','NM','PO','RQ','TS','VU','XW','ZY','10','32'
S2          DW 15 DUP(?)
DATA      ENDS
CODE     SEGMENT
             ASSUME DS:DATA,CS:CODE
START:  MOV AX,DATA
             MOV DS,AX
             MOV BX,OFFSET S1
             MOV SI,0
             MOV CX,15
NEXT:    MOV AX,[BX+SI]
             MOV [BX+SI+30],AX
            INC SI
            INC SI
            LOOP NEXT
            MOV AH,4CH
            INT 21H
CODE    ENDS
            END START

 

二、通用数据传送指令:交换指令XCHG和换码指令XLAT

1、交换指令用来将源操作数和目的操作数内容交换,格式如下:
XCHG reg,reg/mem         ;reg←→reg/mem,也可以表达为:XCHG reg/mem,reg
XCHG指令中操作数可以是字、也可以是字节,可以在通用寄存器与通用寄存器或存储器之间对换数据,当不能在存储器与存储器之间对换数据。
(1)XCHG指令不影响状态标志。
(2)段寄存器不能作为XCHG指令的操作数。
指令举例:
XCHG SI,AX
XCHG AL,BL
XCHG AX,[2000H]
XCHG WORD_VAR,CX
数据交换程序实例:
例:LI7-1.ASM
将S1串与S2串交换
NAME LI7-1.ASM
DATA    SEGMENT
S1        DB 'ABCDEFG'
S2        DB '0123456'
N          DW $-OFFSET S2                    ;N为字符串长度
DATA    ENDS
CODE   SEGMENT
           ASSUME CS:CODE,DS:DATA
START: MOV AX,DATA
            MOV DS,AX
            MOV SI,0
            MOV CX,N
L1:       MOV AL,S1[SI]                         ;S1[SI]与S2[SI]交换
           XCHG AL,S2[SI]
           MOV S1[SI],AL
           INC SI                                     ;(SI)+1—〉SI
           LOOP L1
           MOV CX,N                                ;显示S1串
           MOV SI,0
           MOV AH,02H
L2:       MOV DL,S1[SI]
           INT 21H
           INC SI
           LOOP L2
           MOV DL,' '
           INT 21H
           MOV CX,N                          ;显示S2串
           MOV SI,0
L3:      MOV DL,S2[SI]
           INT 21H
           INC SI
           LOOP L3
           MOV AH,4CH
           INT 21H
CODE  ENDS
          END START

2、换码指令用于将BX指定的缓冲区中、AL指定的位移处的数据取出赋给AL,格式为:
XLAT LABEL
XLAT               ;al←ds:[bx+al]
换码指令的两种格式完全等效。第一种格式中,label表示首地址;第二中也可以用XLATB助记符。实际的首地址在BX寄存器中。
将首地址为100H的表格缓冲区中的3号数据取出
MOV BX,100H
MOV AL,03H
XLAT
因为AL的内容实际上是距离表格首地址的位移量,只有8位,所以表格的最大长度为256,超过256的表格需要采用修改BX和AL的方法才能转换。XLAT指令中没有显式指明操作数,而是默认是用BX和AL寄存器,这种方法称为隐含寻址方式。
换码指令的应用,如扫描码转换为ASCII码,数字0~9转换为7段显示码等换码程序实例:将二进制表示的十六进制数字转换成ASCII码在显示出来。根据题意,需要在数据段中定义一个换码表,就是0,1,2,...,16所对应的

ASCII码表:
TAB_DA   DB 30H,32H,32H,33H,34H,35H,36H,37H,38H,39H
               DB 41H,42H,43H,44H,45H,46H
或者是:
TAB_DA   DB '0123456789ABCDEF'
完整程序如下:
NAME LI7-2.ASM
TABLE     SEGMENT
TAB_DA  DB 30H,32H,32H,33H,34H,35H,36H,37H,38H,39H
              DB 41H,42H,43H,44H,45H,46H
TAB_HEX DB 0,1,2,3,4,5,6,7,8,9
              DB 0AH,0BH,0CH,0DH,0EH,0FH
TABLE     ENDS
CODE     SEGMENT
             ASSUME CS:CODE,DS:TABLE
START:  MOV AX,TABLE
             MOV DS,AX
             MOV CX,10H
             MOV BX,OFFSET TAB_DA
             MOV SI,OFFSET TAB_HEX
NEXT:    MOV AL,[SI]
            XLAT TAB_DA
            MOV DL,AL
            MOV AH,02H
            INT 21H
            MOV DL 00H
            MOV AH,02H
            INT 21H
            INC SI
            LOOP NEXT
            MOV AH,4CH
            INT 21H
CODE   ENDS
            END START

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值