【新书推荐】8.1 数据传送指令

第八章 8086指令系统

我们把汇编指令称为机器语言的指令助记符,每一条汇编指令都对应一条机器指令。X86 CPU厂商AMD和INTEL提供硬编码表。编译器或者调试器就是通过查表的方式,将汇编指令翻译成机器指令,或者将机器指令反编译成汇编指令。

指令分组

(1)数据传送指令;

(2)算术运算指令;

(3)逻辑运算指令;

(4)串操作指令——第十七章字符串处理详细讲述;

(5)程序控制指令,又称为转移指令;

(6)处理器控制指令;

(7)宏命令——自定义指令,第二十二章宏命令详细讲述。

指令表示格式

[标号:]  指令助记符 [操作数1  [,操作数2]]  [;注释]

指令是否带操作数,取决于指令本身,可以没有操作数,也可以是一个、两个或三个操作数。最多就是三个操作数了。

标号的使用取决于程序的需要。注意,这里的标号是代码段的地址标号,为了和数据段地址标号区别,代码段地址标号后面多了一个“:”。

注释

16位汇编指令中的注释使用“;”,后面添加注释内容,注释可以增强代码的可读性。我们需要养成良好的习惯,记得在源代码中添加注释。

其他说明

对于每一条指令,程序员需要注意以下几点:

(1)指令的功能;

(2)指令操作数的寻址方式;

(3)指令对FLAG寄存器标志位的影响;

(4)指令的长度和执行时间;

8.1 数据传送指令

         本节内容:数据传送指令,不影响标志位。

         ■传送指令:MOV指令,包含目的操作数和源操作数,功能为获取源操作数的值并送入目的操作数。操作数数据宽度必须一致,不能同时为内存操作数和段寄存器。CS不能做目的操作数,IP不能做目的操作数或源操作数。立即数不能做目的操作数。

         ■交换指令:XCHG指令,交换目的操作数和源操作数的值,为MOV指令的复合指令,使用规则与MOV指令相同。

         ■地址传送指令

●LEA指令的功能是获取内存操作数的地址并送入目的操作数。汇编语言中通过指令区分获取地址还是获取该地址处的值。

●LDS指令:将32位地址指针中的高16位送入DS,低16位送入目的操作数(指针寄存器)。

●LES指令:将32位地址指针中的高16位送入ES,低16位送入目的操作数(指针寄存器)。

堆栈操作指令

●PUSH指令:将16位操作数压入堆栈。

●POP指令:将16位操作数弹出堆栈。

标志操作指令

●LAHF指令:把标志寄存器的低8位(SF、ZF、AF、PF、CF)传送至AH寄存器的指定位。

●SAHF指令:和LAHF相反,把寄存器AH的指定位送至标志寄存器低8位。不影响高8位的OF,DF,IF,TF标志。

●PUSHF指令:把FLAG标志寄存器的内容压入堆栈。

●POPF指令:把当前堆栈顶的一个字传送到标志寄存器。

标志位操作指令

●CLC指令:CF位清零。

●STC指令:CF位置1。

●CMC指令:CF位取反。

●CLD指令:DF位清零。

●STD指令:DF位置1。

●CLI指令:IF位清零。

●STI指令:IF位置1。

8.1.1 传送指令

         ■MOV指令

指令格式:MOV DST(目的操作数) ,SRC(源操作数)

MOV指令把一个字节或一个字从源操作数SRC传送至目的操作数DST中。源操作数可以是通用寄存器、内存存储单元或立即数。目的操作数可以是通用寄存器或内存存储单元。

如图8-1所示,MOV 指令的操作数可以是如下组合:

MOV AX,1                            ;16位立即数送入16位通用寄存器

MOV BYTE PTR [SI],1        ; 8位立即数存入8位(BYTE PTR)内存操作数

MOV AX,BX                          ;16位通用寄存器

MOV AL,BL                          ; 8位数据寄存器

MOV AX,[SI]                       ;16位内存操作数

MOV WORD PTR [DI],AX ;16位寄存器存入16位(WORD PTR)内存操作数

MOV DS,AX                         ;16位通用寄存器存入16位段寄存器

MOV AX,SS                          ; 16位段寄存器存入16位通用寄存器

MOV WORD PTR [SI],CS   ;16位段寄存器存入16位内存操作数

MOV DS,[SI]                       ;16位内存操作数存入16位DS段寄存器

MOV DS,1         ;错误,立即数不可以直接存入段寄存器,可以借助通用寄存器间接存入

MOV AX,1         ;正确

MOV DS,AX      ;正确

                                图8-1 MOV指令数据传送方式

CPU内部寄存器之间的数据传送

mov ah,al

mov dl,bh

mov bp,sp

mov ax,cs

mov ds,bx

mov ds,1234h  ;错误    

mov cs,1234h  ;错误

mov ax,1234h  ;正确    

mov bx,ip     ;错误

mov ds,ax

mov es,ax

      注意

1.源操作数和目的操作数不能同时为段寄存器;

2.CS不能为目的操作数;

3.IP寄存器不能为源操作数,也不能做目的操作数,这种例外永远存在;

4.源操作数和目的操作数的数据宽度必须一致;

5.MOV指令不影响标志位;

6.不能同时为存储器操作数或段寄存器,需借助其它通用寄存器;

mov bx,[si]  

mov [di],bx

mov ax,cs

mov ds,ax

7.立即数不能直接传送到段寄存器,需借助其他通用寄存器;

mov ax,5000h 

mov ds,ax

8.立即数永远不能做目的操作数。

立即数送至通用寄存器或存储单元(各种存储器寻址方式)

mov bl,4                      ;十进制数

mov di,-5                    ;十进制数

mov varb,-1      ;varb表示变量名,代表一个存储单元

mov varw,1234h  ;varw是一个字变量

mov word ptr [si],5678h ;需要指定内存操作数的数据宽度

寄存器与存储器之间的数据传送

mov ax,varw         ;varw为字变量,存储器操作为直接寻址

mov bh,[si]           ;存储器操作数为寄存器间接寻址

mov di,es:[di+3]    ;存储器操作数为相对变址寻址,使用段超越前缀

mov dx,[bx+si+3]      ;存储器操作数为相对基址加变址寻址

mov [bp],ax           ;默认使用SS段寄存器

mov varb,bl          ;varb是一个字节变量

mov ds:[bp],dl       ;使用DS段超越前缀

mov varw,es          ;varw是字变量

mov cx,varw            ;将变量varw的值送入cx

    思考

         在MOV指令中:

         1.为什么CS不能做目的操作数?

         2.为什么IP不能做源操作数?

8.1.2 交换指令

XCHG指令

利用交换指令可方便地实现通用寄存器与通用寄存器或存储单元之间的数据交换。

指令格式:XCHG  OPRD1,OPRD2。

将操作数1的内容与操作数2的内容互换。操作数同时是字节或字。

例:

xchg al,ah

xchg si,di

    注意

1.OPRD1和OPRD2可以是通用寄存器和存储单元。

2.OPRD1和OPRD2操作数不可以是段寄存器。

3.OPRD1和OPRD2不能同时是存储单元。可采用各种寻址方式来指定存储单元。

xchg [si+1],al

xchg [si+di+3],bx

4.OPRD1或OPRD2不能是立即数。

5.XCHG指令不影响标志位。

8.1.3 地址传送指令

LEA指令:传送有效地址指令

指令格式:LEA  REG,OPRD

将操作数OPRD的有效地址传送到操作数REG。操作数OPRD必须是一个存储器操作数,操作数REG必须是一个16位通用寄存器。

lea ax,buff                  ; buff为变量名,将buff地址标号送入ax寄存器

lea dx,[bx+1]              ;将地址标号bx+1送入dx寄存器

lea si,[bx+di+4]          ;将地址标号bx+di+4送入si寄存器

    注意

1.LEA指令和MOV指令有本质的区别:

假设buffer变量的偏移是1234h,该字变量的值为5678h。

LEA指令取地址:lea ax,buffer      ;执行后,ax=1234h。

MOV指令取值:mov ax,buffer     ;执行后,ax=5678h。

在16位汇编语言中:

如果取内存操作数的值,则使用MOV指令;

如果取内存操作数的地址,则使用LEA指令;

2.LEA指令不影响标志位。

3.LEA指令还有一种用法,LEA AX,[1+2+3];AX=6,编译器会计算方括号内常量表达式的值,相当于做了一个简单的加法运算。

LDS指令:段值和段内偏移构成32位的地址指针。该指令传送32位地址指针。

指令格式:LDS REG,OPRD。

LDS指令将操作数OPRD中所含的一个32位地址指针的16位段值部分送到数据段DS,16位偏移部分送入REG寄存器。操作数OPRD必须是一个32位的存储器操作数,REG可以是一个16位的通用寄存器,实际往往是变址寄存器或基址寄存器。

lds di,[bx]                ; [bx]是一个32位内存操作数,高16位为段值,低16位为偏移。

lds si,farpointer   ;farpointer是一个32位双字变量。

指令LES

LES指令也是传送32位地址指针。

指令格式:LES REG,OPRD。

LES指令将操作数OPRD中所含的一个32位地址指针的段值部分送到附加段ES,偏移部分送入REG寄存器。其他与LDS指令相同。

         如图8-2所示,原数据段的逻辑地址为076A:1234H,对应的物理地址为088D4H。执行LDS SI,DWORD PTR [1234H]后,数据段DS的值为1234H,SI寄存器的值为5678H,逻辑地址变为1234: 5678 H,对应的物理地址为179B8H。

                                                图8-2 LDS指令执行示意图

8.1.4 堆栈操作指令

堆栈是一段RAM内存空间,栈底一端地址较大,栈顶一端地址较小,入栈时,由高地址到低地址,出栈时,方向相反。段值为SS寄存器,SP始终指向栈顶。堆栈内存空间16位对齐。

堆栈内数据存取原则为后进先出的原则,参见图6-11 堆栈存储数据规则演示。

堆栈用途

(1)现场和返回地址保护;

(2)寄存器内容的保护;

(3)传递参数;

(4)存储局部变量

进栈指令PUSH把16位数据压入堆栈

指令格式:PUSH SRC

PUSH指令把源操作数SRC压入堆栈。先把栈顶指针SP减2,然后把源操作数SRC送入SP指向的栈顶。

源操作数可以是通用寄存器或段寄存器,也可以是字存储单元,源操作数不可以是立即数。如果将8位寄存器或内存操作数入栈,必须先将其扩展为16位操作数,然后再入栈。

PUSH SI

PUSH DS

PUSH VARW ;字变量

PUSH [SI]

如图8-3所示:

假设AX=1234H

   PUSH AX

出栈指令POP

POP  DST

POP AX

                                                图8-3 进栈出栈操作示意图

    注意

1.8086 CPU不可以PUSH立即数,如 push 1;错误。80386 PUSH指令支持立即数操作数。

2.堆栈指令不影响标志位。

8.1.5 标志操作指令

标志传送指令

LAHF指令:LAHF

如图8-4所示,该指令把标志寄存器的低8位(SF、ZF、AF、PF、CF)传送至AH寄存器的指定位。

SAHF指令:SAHF

该条指令和LAHF相反,把寄存器AH的指定位送至标志寄存器低8位。不影响高8位的OF,DF,IF,TF标志。

                                8-4 LAHF指令示意图

PUSHF指令:PUSHF

该条指令把标志寄存器的内容压入堆栈,即先把堆栈指针寄存器SP的值减2,然后把标志寄存器的内容送入由SP所指的栈顶。

POPF指令:POPF

该条指令把当前堆栈顶的一个字传送到标志寄存器,同时相应地修改堆栈指针,即把SP加2。

PUSHF指令和POPF指令一起使用,起到保护和恢复标志寄存器的作用。

    思考

如何利用PUSHF和POPF指令改变TF追踪标志的状态?

标志位操作指令

清进位标志CF指令CLC

格式:CLC;功能:CF置0。

STC指令

格式:STC;功能:CF置1。

CMC指令

格式:CMC;功能:进位标志CF取反。

清方向指令CLD

格式:CLD;功能:DF置0。

STD指令

格式:STD;功能:DF置1。

CLI指令

格式:CLI;功能:IF置0。

STI指令

格式:STI;功能:IF置1。

  练习

1、8086的指令集可分为哪些子集?

2、通常情况下源操作数和目的操作数不能同时为存储器操作数。请给出存储器操作数甲送到存储器操作数乙的三种方法。

3、如何实现代码段与数据段相同?请编写一个将数据段和代码段合并成一个段的源程序,并验证其正确性。

4、请使用一条指令将(BX +123)的和送入AX寄存器。

5、请比较如下指令片段并添加注释:

LDS SI,[BX]   MOV SI,[BX]                   MOV DS,[BX+2]

MOV DS,[BX+2]         MOV BX,[BX]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2805665.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

matplotlib绘图初步

文章目录 绘制曲线图完整流程图像属性 绘制曲线图 matplotlib是python中最常用的可视化库,提供了不同坐标系下的二十余种常用图像,并且提供了动态图像绘制的方法,可以满足科学计算中的绝大多数可视化需求。而在matplotlib中,绝大…

RM电控讲义【HAL库篇】(二)

8080并口模式是一种常见的计算机接口模式,主要用于LCD(液晶显示屏)模块。 在8080并口模式中,通信端口包括多种信号线,用于实现数据的读写和控制功能。主要的信号线包括: CS(片选信号&#xff…

【开源】JAVA+Vue.js实现大病保险管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统配置维护2.2 系统参保管理2.3 大病保险管理2.4 大病登记管理2.5 保险审核管理 三、系统详细设计3.1 系统整体配置功能设计3.2 大病人员模块设计3.3 大病保险模块设计3.4 大病登记模块设计3.5 保险审核模块设计 四、…

【Linux】 yum命令使用

yum命令 yum( Yellow dog Updater, Modified) 是一个在 Fedora、CentOS 及其它一些基于 RPM 的 Linux 发行版中使用的包管理器。它允许用户自动安装、更新、配置和删除软件包。yum 由 Python 写成,基于 RPM(Red Hat Package Mana…

端口占用:Web server failed to start. Port XXX was already in use.原因分析-解决方案

一、windows 1.Web server failed to start. Port XXX was already in use出错原因分析 端口被占用了,我们只需要换一个端口就可以了,如果就想要用特定的端口,我们需要使用下面的命令,先找到对应端口号的进程号,然后结…

面试经典150题 -- 二叉树搜索树 (总结)

总的链接 : https://leetcode.cn/studyplan/top-interview-150/ 二叉搜索树相关概念 : 二叉搜索树是一个有序树。 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结…

音视频开发之旅(68)-SD文生图

目录 效果展示 sd使用流程:选大模型、写关键词和设置参数 SDWebui文生图调用流程 StableDiffusion原理浅析 参考资料 一、效果显示 1girl,smile,highres,wallpaper,in summer,landscape 1girl,smile,highres,wallpaper,in summer,city,street 二、sd使用流程&a…

算法-两两交换链表中的节点

1、题目来源 24. 两两交换链表中的节点 - 力扣(LeetCode) 2、题目描述 给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交…

128 Linux 系统编程6 ,C++程序在linux 上的调试,GDB调试

今天来整理 GDB 调试。 在windows 上我们使用vs2017开发,可以手动的加断点,debug。 那么在linux上怎么加断点,debug呢?这就是今天要整理的GDB调试工具了。 那么有些同学可能会想到:我们在windows上开发,…

爬取数位观察城市数据代码展示

import requests import json from Crypto.Cipher import AES # 开始解密 from Crypto.Util.Padding import unpad #去填充的逻辑 import base64 url https://app.swguancha.com/client/v1/cPublic/consumer/baseInfo data {current: 1,"dimensionTime": "20…

【MySQL 探索之旅】初始MySQL数据库

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有…

分布式应用:kylin 部署 zabbix 监控平台

目录 一、实验 1.环境 2. kylin 修改mysql数据库 3. kylin 部署 zabbix 监控平台 4. kylin 修改 zabbix 配置 5. kylin 修改zabbix web 二、问题 1. zabbix_server 查看版本报错 2.zabbix_server 文件如何去掉注释"#"和空行 3. zabbix图表显示异常 4.zabbi…

osg qt5.15 osg3.6.3 osgEarth3.1 编译爬山

Demo演示:Qt5.15.2OSG3.6.3OsgEarth3.1的QtCreator下的msvc2019x64版本 osgQt编译 步骤一:下载解压 步骤二:CMake配置 步骤三:CMake配置添加osg环境 步骤四:CMake配置添加Qt环境 步骤五:CMake修改CMakeLis…

【Python笔记-设计模式】享元模式

一、说明 享元模式是一种结构型设计模式,它摒弃了在每个对象中保存所有数据的方式,通过共享多个对象所共有的相同状态,让你能在有限的内存容量中载入更多对象。 (一) 解决问题 旨在减少大量相似对象创建时的内存开销 (二) 使用场景 大量…

可视化 RAG 数据 - 用于检索增强生成的 EDA

每日推荐一篇专注于解决实际问题的外文,精准翻译并深入解读其要点,助力读者培养实际问题解决和代码动手的能力。 欢迎关注公众号(NLP Research),及时查看最新内容 原文标题:Visualize your RAG Data — EDA for Retrieval-Augmented Generation 原文地址:https://medi…

蜂窝物联网咖WiFi认证解决方案

项目背景 随着目前网咖模式越来越流行,给网吧部署一套无缝漫游的WIFI网络势在必行。同时,网吧无线准入的验证码在客户机上面进行更新,以防周边的人员进行蹭网,损失网吧的外网带宽。 01 需求分析 1. 网吧服务区域全部覆盖无盲区…

Android 解决后台服务麦克风无法录音问题

Android 解决后台无法录音问题 问题分析问题来源解决方案1. 修改清单文件:`AndroidManifest.xml`2. 修改启动服务方式3. 服务启动时创建前台通知并且指定前台服务类型参考文档最后我还有一句话要说我用心为你考虑黄浦江的事情,你心里想的却只有苏州河的勾当 问题分析 安卓9.…

5G端到端案例三:锚点基站侧5G连接与VOLTE专载建立流程冲突导致CSFB回落问题

1. 问题描述: NSA组网场景下,语音业务仍使用4G VoLTE方案,在拉网测试中,发现存在较多流程交叉导致的VOLTE接入失败的问题。 流程冲突时的空口信令表现为,终端添加SCG流程与语音专载流程冲突时,专有承载建…

125 Linux C++ 系统编程4 Linux 静态库制作,动态库制作,静态库和动态库对比。静态库运行时找不到库的bug fix

一 静态库 和动态库 对比 静态库的原理:假设我们有一个 静态库,大小为500M,这个静态库实现了一些打牌的逻辑算法,提供了一堆API,让开发者 可以轻松的实现 54张扑克牌的随机发牌,指定发牌等功能。 我们写了…

红日靶场3

靶场链接:漏洞详情 在虚拟机的网络编辑器中添加两个仅主机网卡 信息搜集 端口扫描 外网机处于网端192.168.1.0/24中,扫描外网IP端口,开放了80 22 3306端口 80端口http服务,可以尝试登录网页 3306端口mysql服务,可…