3.汇编指令:【数据传输类指令】

数据传输类指令

在这里插入图片描述

1. 通用数据传输指令

1.1 MOV指令

形式是 : MOV 目标操作数 ,源操作数

源操作数的内容目标操作数

下面重点看看 MOV 指令对操作数的要求:

  1. 目标操作数和源操作数的字长必须相同
  2. 两个操作数不能同时为段寄存器
  3. 两个操作数不能同时为存储器操作数(也就是说,如果我们想把内存单元的某一个数赋值到内存的另外一个单元,是不能一步到位的,必须借助中间媒介)
  4. 目标操作数不能为立即数
  5. 立即数不能直接传输给段寄存器
  6. CS,IP 不作为目标操作数

辨析下面指令:

【1】MOV DS, 1000H (×):立即数不能够直接赋值给段寄存器

【2】MOV CS, AX (×):代码段寄存器不能作为目标操作数

【3】MOV VALUE1, CX (×):这里的 VALUE1 是一个定义了的变量,那么它就是一个立即数,立即数不能够作为目标操作数

【4】MOV [BX], [SI] (×):这里用方括号表示存储器寻址,那么 [SI] 就代表存储器里面的一个数,MOV 指令中两个操作数不能够同时为存储器操作数

【5】MOV DS, ES (×):两个操作数不能同时为段寄存器

【6】MOV AH, BX (×):两个操作数字长不一致,AH 是8位的,BX 是16位的

【7】迷惑题:MOV DX , 09H (√):看起来这两个操作数字长不等,但是别忘了,09H 是0开头的,既然是0开头,前面有几个0都可以,那么09H 可以写成 0009H,这样就 OK 了




1.2 堆栈操作指令 PUSH , POP

在这里插入图片描述

对于 PUSH 操作,我们首先先将栈顶指针 SP : SP − 2 → SP ,然后把数据压入(16位的!)

在这里插入图片描述

对于 POP 操作,取完数后,再将栈顶指针做: SP + 2 → SP (+代表往下,地址增大)

在这里插入图片描述

堆栈操作指令例子

在这里插入图片描述




1.3 交换指令 XCHG

格式: XCHG 操作数1, 操作数2

这个指令的作用就是将两个操作数的内容互换

但是对操作数有以下要求:

  1. 任何一个操作数都不能为立即数。因为这两个操作数既是源操作数,又是目标操作数。既然是目标操作数就不能是立即数。
  2. 两个操作数中必须得保证有一个是寄存器操作数,例如 BX, AX之类的
  3. 两个操作数不能够同时为存储器操作数。(也就是存储器寻址方式)
  4. 同样不允许有段寄存器作为操作数

例如: XCHG   BX , [BP + SI]
假设

  1. BX寄存器内存放的内容是 BX = 6F30H
  2. [ BP + SI ] 是基址+变址寻址方式,由于没有段超越,所以BP默认的段寄存器是 SS,假设:SS = 2F00H, BP = 0200H,SI = 0046H 那么 [ [BP+SI] 表示的偏移地址是:0246H,对应的物理地址就是:2F000H+0246H = 2F246H。
  3. 那么也就是把 内存地址为 2F246H 的数和寄存器 BX 内的数交换




1.4 查表指令 XLAT

这个适用于查找一维数组中的元素。使用 XLAT 的时候不用写操作数,直接 XLAT 就OK。

但是,有几点说明:

  1. XLAT 规定:需要使用 BX 存放表头地址,AL 用于存放一维数组中元素距表头的距离。因此,需要查找的元素地址就是 BX+AL
  2. 那么 XLAT 的工作是将地址 BX+AL 所指向的数组元素赋值给 AL




2. 地址传输类指令

2.1 LEA (近地址)

LEA 指令是取近地址的,也就是说,LEA 工作的区域就是在同一个段里面,因此不用考虑段基址

LEA REG, MEM。LEA指令的功能是将变量的 16 位的偏移地址写入到目标寄存器
注意:LEA 指令的源操作数一定要是存储器操作数!!

LEA 的目标操作数一定不能是段寄存器,而一定是通用寄存器!!,通常是间址寄存器

在这里插入图片描述

在这里插入图片描述

2.2 LDS & LES (远地址)

LDS指令功能:从src指定的存储单元开始,由4个连续存储单元中取出前2字节送到偏移地址,取出后2字节送到DS中 。

LES跟上面的一样,只是后2字节送到ES中 。

例: LDS AX,(SI +20 )
假设执行前为
(20050H)=1234H,(20052H)=5678H,

AX=0000H,DS=2000H,SI=0030H,则物理地址=2000H×16+20+0030H=20050H。
执行的结果为:AX=1234H(偏移地址!),DS=5678H (地址中的数据)(注意取数据的顺序!)




在这里插入图片描述

3. 输入输出指令

这一类指令很重要,我们首先需要明确几个定义:1. 什么是接口?2. 什么是端口?

所谓接口,比如说,我们电脑上有一个用来插 U 盘的东西,我们称之为 “USB接口”,这类和外部设备连接的 “口”,我们就叫做接口。一个计算机里面可以有好多接口。

端口是什么呢?比如说,你电脑通过接口连接了某一个设备,而这个设备里面又会有许许多多的寄存器,我们电脑的 CPU 可以直接访问这些寄存器。因此,在外设里面,能够被 CPU 直接访问的寄存器就是端口。
在这里插入图片描述

既然有那么多端口,如果要想实现对端口数据的读或写,那么势必需要对这些端口进行地址编码,这样才能准确低找到所需要控制的端口。因此,也就引申出了下面端口的寻址方式:

根据端口地址码的长度,指令具有两种不同的端口地址表现形式:

  1. 假设我们的端口数目不多,小于256个,那么我们可以使用8位二进制来进行地址编码。那么这个8位的地址我们可以在指令里面直接给出来。(也就是可以寻址的端口数为: 2^8=256 )
  2. 如果端口很多,端口地址是 16位时,我们在指令里面的端口地址必须要由 DX 指定!这叫间接寻址。所能够寻址的端口数是 216=64K)

另外,端口的编码也分为了两种方式:

  1. 独立编码的方式:端口地址的编码和存储空间的编码是两个不同的独立地址空间。
  2. 统一编址方式:对内存单元和端口进行统一的编址

下面我们来看看这两个指令:

【1】IN acc , PORT
acc 表示累加器,PORT 顾名思义就是端口的意思。
IN 操作的功能是把 PORT 所指向的端口的内容 读入 acc里面 (注意:acc 只能是 AX 或 AL)

在这里插入图片描述

【2】 OUT PORT , acc
就是把 acc里面的内容 写进 PORT 所指向的端口 里面

在这里插入图片描述




4.字位扩展指令

  • 仅用于有符号数扩展字长;对无符号数,直接在高位补0
  • 符号扩展仅增长数据位数,并不改变数据大小。方便计算



5. 标志位传输指令

这里我们将要了解 4 个指令: LAHF, SAHF, PUSHF, POPF

首先是:
LAHF 和 SAHF,它们的默认操作数是 FALGS 和 AH。

LAHF (Load AH from flags). 也就是说,它的功能是将 FLAGS 寄存器的低八位 赋值给 AH

SAHF (Store AH into flags). 意思是将 AH 里面的数 存入 FLAGS 的低八位

PUSHFPOPF很简单,就是将FLAGS 的内容压入堆栈或者说弹出堆栈




例题

在这里插入图片描述

  • 10
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

你说的白是什么白_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值