当前课程知识点:微机原理与接口技术 > 第5周 算术运算、逻辑运算与移位操作指令 > 第20讲 移位操作指令 > 移位操作指令
好 大家好
这一讲我们来学习
移位操作指令
移位操作无非就是
移动
一位一位的
向这边移动
或者向这边移动
移位操作指令
它在我们整个指令集里边
有一些它自己
独有的一些特殊性
也就是说
它最大的一个特殊性
是在形式上
它是一个
双操作数格式的指令
但是在本质上
它们是
单操作数格式的指令
所以在学习
这一类指令之前
我们先把
这一类指令的
一些共同的点
我们做一个简单的介绍
移位操作指令
就是控制二进制位
向左
或者向右移动指令
一共有两个小类
一类叫
非循环移位
一类叫
循环移位
就是说我们
可以简单的说
一类是线性移位
一类是循环移位
移位指令
刚才我们说了
在格式上
它是双操作数格式的
但是在本质上
它们是单操作数格式
为什么是这样呢?
因为
指令的
移动的对象
或者指令操作的对象
实际上是目标操作数
那么原操作数是什么?
原操作数
就是移位的次数
因此
作为单操作数
就是说本质上
作为单操作数格式的指令
所以
当目标操作数
是存储器操作数的时候
一定要声明它的字长
否则
我们不知道
对一个字节的数移位
还是对两个字节数移位
等等
当然目标操作数
我们知道它肯定不能是立即数
所以在这里
这一点就不强调了
还有一个
在移位指令里
大家要关注的就是
移动一次的时候
也就是说不论向左也好
向右也好
循环也好不循环也好
当移动一位的时候
这个1
是可以直接存
出现在原操作数中的
也就是说这个1
是可以直接写出来的
但是如果
移动两位
或者两位以上
这个是
移位次数
是不能直接
在指令中写的
而是必须要写给CL
也就是说CL的值
来指定它的移位次数
因此
指令的原操作数
只能是1
或者是CL
下边我们来
具体的学习
移位操作指令
我们先来看一下
非循环移位指令
非循环移位
又包括了逻辑左移
就是向左和向右
两个维度 对吧
其中又是
包括逻辑左移
算术左移
和逻辑右移
算术右移
也就是说
它从方向上来讲
有向左
有向右
两种
那么它还有一个逻辑和算术
它们逻辑和算术的
区别在哪里呢?
我们下边
慢慢来说
算术左移指令
当移动一次的时候
这个1可以在这里写
移动两次或者两次以上
这个移动次数
必须由CL给出
算术左移指令的
指令助记符是SAL
那么逻辑左移的指令
是SHL
这是它的指令助记符
所以我们
话说到这
我们中断一下
我们
大家看
刚才我们说
这个移位操作
有线性的
和非线性的
也就是线性的和循环的
不能说非线性
就是线性的和循环的
那么
又有向左和向右
又有算术和逻辑
所以
这样子
七七八八加起来
这个移位指令的
指令码的种类
就变得比较多
现在我们看到
这个非循环移位指令
我们有向左向右
这肯定是两种
然后又有算术和逻辑
这又是两种
所以有关左移指令
大家看就
有算术左移和逻辑左移
这就两条
那么相应的
右移指令
也有算术右移
和逻辑右移
所以
非循环移位指令
加起来就是四条指令了
这种指令的格式
后边所有的指令
不论是循环还是不循环
它就是
指令助记符
是不一样的
其它的格式都是一样的
也就是说它的移位
移动1位的时候
1可以在这里写
移动两位
或者两位以上
必须移动次数是CL
而移动的对象
是目标操作数
也就是说它在本质上
是个单操作数格式的指令
那么为什么要叫
算术和逻辑
它的区别在哪里呢?
主要是这样
算术移位指令
针对的是有符号数
而逻辑移位指令
针对的是无符号数
这个就是算术和逻辑
它们的不同
但是对于
左移指令来讲
不论是算术左移
还是逻辑左移
它们在移动原理上
都是一样的
我们用一个示意图
来描述一下
左移就是将
最高位
移到CF
最低位补0
所以对这一类指令
不管
执行的结果怎么样
它们一定会对CF
产生影响
其它标志位的影响
我们不在这里强调
但是请大家一定注意
每一次的移动
因为最高位移到C里了
所以C的状态
一定会发生变化
那么低位就是补0
大家看一下
如果对于一个八位操作数
移动8次的情况下
那么这个结果
一定就全部变成0了
所以这
非循环移位指令
它是一个破坏性的移位
就是它移掉以后
这边的就是不可还原了
那么右移
我们同样的有逻辑右移
和算术右移
刚才我们说
左移指令
算术左移
和逻辑左移
虽然它针对的
操作数的性质不一样
但是它的移动原理
是一样的
但是逻辑
但是右移指令不一样
逻辑右移
针对的是无符号数
而算术右移
针对有符号数
这个不仅仅
是数的性质不一样
它们的原理
也是不一样
我们先来看一下
逻辑右移指令
格式我就不再强调了
指令助记符
请大家注意
SHR
这个R实际上就是RIGHT
就是向右移的意思
刚才那个SHL
L就是左的意思 对吧
所以
这个针对的是
无符号数的右移
我们刚才讲
左移
每左移一位
相当于对这个数
乘2的运算
那么
每右移一位
就相当于对它
除以2的运算
所以右移指令的原理
是这样
就是说每移动一次
最低位移入CF
最高位补0
同样的
逻辑右移
当它右移八次的时候
对于八位数来讲
右移八次的时候
这个数
数就都全部都变成0了
这是逻辑右移的原理
下面我们来看一个例子
这三条指令
第一行指令的
执行结果AL=68H
第二行指令的执行结果
CL=2
那么最后一行
是一个逻辑右移指令
就是将这个68H
右移
逻辑右移两位
这条
这三条指令
最后的功能就是这样
我们刚才说了
每逻辑右移一位
相当于对于一个无符号数
除以2的运算
现在要右移两位
就是相当于
对这个无符号数68H
除以4的运算
我们看一下它的移动过程
这是68H
01101000
那么
移动一位的时候
就是说
第一次移动
我们会把
最低位
移到CF
所以CF
不管原来是什么状态
现在变成0了
然后再
高位补0
所以当移动完
一次以后
它的AL的结果
是这样的一个结果
那么
因为现在CL=2
表示现在要移动两位
所以
第二次移动的时候
照样最低位移到CF
最高位补0
所以
两次移动完了
以后的结果
就是这样一个值
00011010
也就说1AH
这就是68H
除以4
它的结果
余数
是0
CF里
没有1
所以它的余数是0
好了
现在这个是
逻辑右移
那么算术右移
在移动原理上
和逻辑右移
完全不一样
这一点
跟左移不同
左移不论是
算术左移
还是逻辑左移
它们的移动原理
都是一样的
那么算术右移
相当于有符号数
它每移动一位
相当于有符号数
除以2的运算
我们来看一下
它的原理
算术右移是这样
每移动一位
最低位会移到CF
但是最高位
不是补0
而是将符号位
再copy一份
放在前面
也就是说符号位
会跟着往右移动
但是它同时
又会再复制一下
放到最高位
我们用一个例子
来看一下
假设现在
AL的值是11101000
也就是E8H
那么我们如果
对它
算术右移一位的话
会使
首先会使
CF=0
就是最低位移入CF
但是最高位
就是符号位
它还会
复制到前面
所以当它右移一位
算术右移一位以后
AL的值
会是这样的一个结果
那么
从这个结果里
我们也可以看出来
逻辑右移
当对于一个八位数
这段前提来讲
当逻辑右移
八次的时候
AL的值
就是它原来
目标操作数里的结果
会是0
但是对于算术右移
它移动八次以后
目标操作数里
会使全部变成符号位
如果
符号位是0的话
那就全变成0
如果符号位是1的话
就全变成了1
这个就是
算术右移指令
它的执行原理
那么非循环移位指令
在程序中有什么作用呢?
首先我们就说
它可以实现
相乘
或者乘以2
或者乘以2的整数次方
或者除以2的
整数次方
这样的一个运算
所以左移指令
可以实现乘法
而右移指令
可以实现除法
这个是
非循环移位指令
在程序中
它的主要的一个应用方向
我们
在教材里
有过一些事例
我们在这里
不再一一拿出来讲了
大家有兴趣
可以自己看一下教材
不是有兴趣
就是说我们建议你
认真的看一下
教材上的每一个事例
就是说
它对于这样
非循环移位指令
实际上它可以
实现一些 就是
代替一些乘法的运算
因为乘法运算指令
所需要的时间
是比较长的
所以我们教材上
有一个例 就是说
X乘10的运算
虽然
10不能转换成
2的整数次方
但是它可以分解为
2+8
所以它可以变成
乘2加上乘8的运算
而8
就是相当于
乘以2的3次方的运算
这样就都可以
变成左移指令来实现了
我们下边来讲
介绍一下循环移位
刚才我们说
非循环移位指令
不论是向右也好
向左也好
它移动若干次以后
操作数的值
就都变成0
或者都变成了符号位
也就是说
对于这个数本身
它实际上
它是破坏掉了
但是循环
就是转圈
转圈已经
所以
当你转了若干次以后
它可能就有
就有可能还原到它原来
所以循环移位指令
又分成两个小类
一类是
不带进位标志位
也就是不带CF的循环
还有一个是
带进位的循环
这是两种
那么
同样的
它也有
左移和右移之分
因此
循环移位指令
一样有四条
请大家注意
它们的指令助记符
这也是我们学
移位操作指令
容易出错的一点
因为指令助记符太多了
一共八条
加上它的移位次数
以及它的指令
虽然是双操作数格式
但是本质又是
单操作数格式
这样三点合在一起
所以这条
这一类指令在学习中
容易出现一些失误
但是这一类指令
在原理上非常简单
所以我们也没有必要
去花过多的时间
来介绍
请大家注意
这一类指令在
循环移位指令
在格式以及对操作数的要求上
与非循环移位指令
是一样的
所以下边我们
就还是用示意图的形式
来解释一下
这两类
以及四条指令
它们的执行原理
不带进位位的循环
循环指令是这样
对于左移来讲
就是最高位
移入到CF
最低位这个时候不是补0
最高位移到CF以后
最高位同时会移到最低位
那么
对于右移来讲
就是最低位移到CF
并且同时
移到最高位
所以
对于这种
不带进位位的
循环移位指令
如果这个被
这个目标操作数
是个8位的话
那么当你移动8次之后
它又回到了
原来的状态
不论是向左
还是向右
都是这样的结果
带进位位的循环
也就是带着CF一起循环呢?
我们 它是这样
向左移动的时候
它首先
把CF原来的值
拿出来
移到最低位
然后把最高位
移进CF
向右
就是把CF原来的值
拿出来
移到最低位
然后把
移到最高位
然后把最低位移进CF
这个就是
我们可以说它叫
简单的说
它叫大循环
就是带着CF一起
当然这个循环移位的结果
会和原来的
操作数的结果
会不一样
这个大家自己
拿数据做一下练习
这个原理很简单
我们不想
就在这里
再过多的去解析了
循环移位指令
一共在程序中
有3个应用方向
一个
可以用来对
某些位的状态
进行测试
我们前面用AND指令
和TEST指令
我们都做了练习
可以测试
某些位的状态
比如我们测试
bit1的状态是1还是0?
测试bit1 3 5的状态
是不是同时是1 等等
其实
用循环移位指令也可以
当然 如果是
你不想 不在意
它之前的状态
就是不在意其它位的状态
我们只想知道
比如只想知道
bit1是不是1还是0
那么我们其实用
循环移位
和非循环移位
用AND指令都可以
比如刚才我们的bit1
我们用AND指令
去测了它是不是1
但是我们也可以
比如向右
逻辑右移两位
把那个bit1
移进了CF
然后我们去看CF的状态
到底是0还是1
如何看CF的状态
我们后边讲
转移类指令的时候
我们会看到它
会讲到它
那么如果我们
想知道bit1 3 5是不是同时是1
那么我们就
不能随意的去破坏
这个时候我们
可以用循环移位指令来实现
这些都是没有问题的
那么另外
循环移位指令
可以实现
高位部分
和低位部分的交换
比如AL
我们里面的值
假设是68H的话
我们不论向右循环四位
还是向左循环四位
实际上都达到了68H
变成86H这样子的一个效果
在有些时候
我们需要有
这样子的操作
另外
循环移位指令
和非循环移位指令
可以一起
组成一个32位
或者更长字节数的
这种移位
也就是说可以实现
更长字节数的
乘法运算
或者除法运算
这个我们教材上
有这么一个相关的例
有兴趣大家可以看一下
下边为了
说明我们移位操作的
这种应用
我们用一个事例
来给大家
解释一下
在内存数据段
M1为首地址的
四个单元中
存放了四个压缩BCD码
要求
将这四个压缩BCD码
分别转换位ASCII码
并且将转换结果
存放在同一逻辑段
M2为首的单元中
用图来表示就是这样
M1为首的这个
连续四个单元中
分别存放了12 34 56 78
这样四个压缩BCD数
然后要把它们
转换成ASCII码
存放在这个
M2为首的区域里
我们现在回忆一下
压缩BCD码
是用四位二进制码
来表示一位十进制数的
那么
ASCII码的意思是什么?
数值的ASCII码
实际上就是
数值的字符
我们
从这两个角度
我们一起来分析一下
这个题目应该怎么来解
首先
压缩BCD码
是用四位二进制码
表示一位十进制数
这就意味着
一个字节的数
一个字节的二进制数
是表示了两位压缩BCD数
也就是说
我们知道
压缩BCD
实际上是十进制的含义
那么
一字节表示两位压缩BCD
那么就意味着高四位
是十进制的十位
低四位是十进制的个位
转换ASCII码的时候
因此我们就需要
分别来转换
也就是说高四位的时候
要把高四位拿出来
转换它们对应的ASCII码
低四位要转换
再转换成低四位的ASCII码
比如刚才我们说
第一个数12
这样一个BCD数
那么
12实际上
如果是BCD的话
它的这个12
实际上就是12的意思
那么这个1就是十位数
因为1有1的字母
2有2的字母
所以转换的时候
分别 必须分别进行
0到9的ASCII码
我们知道它的高4位
都是0011
也就是说9的ASCII码
是39H
1的ASCII码
是31H
因此在转换低4位的时候
需要先把
高4位清零
然后把高4位变成
0011
这样的话
对应的低4位的ASCII码
就出来了
那么转换高4位的时候
我们就必须把
高4位要移到
移位到
低4位这个位置上
然后
高位它等于是向右
移动四位
高4位自然就补0了
那么这个时候
把高4位再变成0011
这就是我们整个
这个题目
它的设计的一个思路
下面来看具体的代码
同样的这个
工作流程
我们前面已经
用好几个例子
我们看到过了
首先我们要取
把这个存放压缩BCD码的
这个M1
这个变量的偏移地址
取到SI
比如把目标
就是我们最后转换的结果
存放处M2
它的偏移地址
要送给DI
我们一共有
四个压缩BCD数
所以总的来讲
我们要有四次操作
我们把4
暂时送给CH
这就是我们
取来了第一个数
第一个数
因为它是八位的
我们刚才说
高4位和低4位
要分别转换
所以我们在这里
把它们
先暂存到BL中
然后将高4位清零
然后
或30H
就是把高4位
变成了3
低4位没有改变
然后
这就是转换的结果了
AL里的值
就是低4位
它的对应的ASCII码
把它存放在DI里
DI所指的单元
也就是现在的
M2所指的单元
那么下边
我们就要转
高4位了
转高4位的时候
高4位转换完了以后
要存放在哪里呢?
存放在
DI加1的单元
所以我们下边要把
DI加1
然后用
BL的值
把BL的值
再送回AL中
这样的话
就说我们高4位
那个整个八位数
又还原了
还原了以后
我们刚才
按照我们刚才的分析
我们必须把高4位
向右移动四位
把它移到
低4位的位置上
所以
下边我们就是
用逻辑移位来
移动四次
请大家再次注意
当移动两次
或者两次以上的时候
这个移位次数
必须送给CL里
好 这一条SHR指令
就是向右
逻辑右移四位
逻辑右移四位
我们知道实际上
高4位就是补0
所以 这个时候
高4位自然就成了0
接着去
或30H的时候
高4位自然就变成了3
所以或完了以后
低4位并没有改变
而高4位变成了3
这样的话
AL的值
就是高4位
所对应的ASCII码了
然后我们把它接着送到
DI所指的单元
当然 现在
DI已经是M2加1单元了
这就是
第一个压缩BCD数的转换
就结束了
那么下边
我们将转换
第二个压缩BCD数
所以
SI和DI
都分别再加1
然后CH减1
如果CH不为0
那么我们接着
转向Next
转换
就准备去取第二个数
第二个压缩BCD数
直到什么呢?
直到CH为0
也就是说
四个压缩BCD
都转换结束的时候
程序就结束了
就去执行最后这一条
HLT暂停执行的指令
好 有关移位操作指令
我们到这里就结束了
希望大家
通过这个事例
能够理解
移位操作指令
在程序中的应用
-第1讲 关于本课程
--关于本课程
-第2讲 微型计算机系统
--微机系统_01
--微机系统_02
-第3讲 微型计算机一般工作过程
-第4讲 数制与编码
--计算机中的编码
-第5讲 计算机中数的表示与运算
--数的表示
--符号数的表示
--数的表示与运算
-第6讲 基本逻辑运算与逻辑电路
-第7讲 本周小结
--本周小结
-第1周 微型计算机基础概论--第一周单元测验
-第8讲 8088微处理器
-第9讲 8088 CPU主要引线及机构
-第2周 8088微处理器--第二周单元测验
-第10讲 实模式存储器寻址
-第11讲 8088系统总线
--8088系统总线
-第12讲 微处理器小结
--微处理器小结
-单元测验--作业
-第13讲 指令概述
--指令概述
-第14讲 寻址方式
--寻址方式
-第15讲 通用数据传送指令
-第16讲 地址传送指令
--地址传送指令
-第17讲 输入输出指令
--输入输出指令
-第4周 数据传送指令--第四周单元测验
-第18讲 算术运算指令
--加法运算指令
--减法指令
--乘除运算指令
-第19讲 逻辑运算指令
-第20讲 移位操作指令
--移位操作指令
-第5周 算术运算、逻辑运算与移位操作指令--第五周单元测验
-第21讲 关于串操作指令的说明
--串操作指令说明
-第22讲 串传送与串比较
--串传送与串比较
-第23讲 串扫描指令
--串扫描指令
-第24讲 串装入与串存储指令
-第六周单元测验--作业
-第25讲 程序控制指令说明
-第26讲 转移类指令
--无条件转移指令
--条件转移指令
-第27讲 循环控制指令
--循环控制指令
-第28讲 过程调用指令
--过程调用指令
-第29讲 中断指令
--中断指令
-第30讲 处理器控制指令
--处理器控制指令
-第31讲 指令系统小结
--指令系统小结
-第7周 程序与处理器控制--第七周单元测验
-第7周 程序与处理器控制--第七周作业
-第32讲 汇编语言源程序
-- 汇编语言源程序_01
-- 汇编语言源程序_02
-第33讲 伪指令
--数据定义伪指令
--其它伪指令
-第34讲 系统功能调用
-第35讲 汇编语言程序设计示例详解
--程序设计示例1
-第36讲 汇编语言程序设计小结
-第8周 汇编语言程序设计--第八周单元测验
-第8周 汇编语言程序设计--第八周作业
-第37讲 半导体存储器概述
--半导体存储器概述
-第38讲 内存单元编址
--存储单元编址
-第39讲 随机存取存储器RAM
-- RAM_01
--RAM_02
-第40讲 只读存储器ROM
--ROM_01
--ROM_02
-第九周单元测验--作业
-第41讲 半导体存储器扩展
--存储器扩展_2
-第42讲 半导体存储器小结
--半导体存储器小结
-第十周单元测验--作业
-第十周作业--作业
-第43讲 基本I/O接口
-第44讲 简单接口芯片
--简单接口芯片
-第45讲 基本输入输出方法
--基本I/O方法
-第46讲 简单I/O控制系统设计
-第47讲 中断技术
--中断技术1
--中断技术2
-第48讲 输入输出与中断技术小结
--本周小结
-第十一周单元测验--作业
-第49讲 可编程定时计数器
-第50讲 可编程并行接口
-第51讲 可编程接口小结
--本周小结_01
--本周小结_02
-第十二周单元测验
-第52讲 模拟量的输入输出
--模拟量的输入输出
-第53讲 D/A转换器
-第54讲 A/D转换器
-- A/D转换器_01
-第十三周单元测验--作业
-第55讲 I/O接口系统综合设计示例详解I
-第56讲 综合设计示例详解II
-第57讲 结束语
--结束语