microcomputer_principle_06_位移操作与串操作
移位操作指令
- 控制二进制位向左或向右移动的指令
- 非循环移位指令(线性)
- 循环移位指令
- 指令格式在形式上为双操作数,本质上为 单操作数;
- 指令的目的操作数为被动移动对象,源操作数为移动次数
- 当目标为存储器操作数时,需要说明其字长
- 移动1位时由指令直接给出;移动两位以及以上时,移位次数必须由CL指定。
指令源操作数只能是1或CL
非循环移位指令
- 逻辑左移
- 算术左移
- 逻辑右移
- 算术右移
非循环移位指令是一种破坏性的移位,发生操作后,就不再可以还原了。
算术左移和逻辑左移
算术左移指令:(针对有符号数)
1 | SAL OPRD, 1 |
逻辑左移指令:(针对无符号数)
1 | SHL OPRD, 1 |
对于左移来讲,无论是算术还是逻辑层面操作都是一样的
将最高位移动到CF,最低位补零
逻辑右移
无符号数右移操作
- format:
1
2SHR OPRD, 1
SHR OPRD, CL
原理: 最低位–> CF, 最高位补0,其余右移。
算术右移
针对有符号数右移操作
- format:
1
2SAR OPRD, 1
SAR OPRD, CL
算术右移的高位会用最高位的数值补全
非循环移位指令应用
- 左移可以实现乘法运算
- 右移可以实现除法运算
循环移位指令
- 不带进位位的循环移位
- 左移 ROL
- 右移 ROR
- 带进位位的循环移位
- 左移 RCL
- 右移 RCR
指令格式、对操作数的要求与非循环移位指令相同
循环移位应用
- 用于对某些位状态的测试;
- 高位部分和低位部分的交换;
- 与非循环移位指令一起组成32bit或更长字长数的移位
- 题目分析:
- 压缩BCD码是用4位二进制码表示1位十进制数—->1字节表示2位压缩BCD
- 转换ASCII码时需要分别转换高4位(十位数)和低4位(个位数)
- 0~9的ASCII码的高4位均为0011(03H)
- 转换低4位时应先使高4位清零,转换高四位时须先将高4位移动到低4位的位置
1 | LEA SI, M1 |
串操作
- 针对数据块或字符串的操作
- 可实现存储器到存储器的数据传送;(双操作数指令,有时候,必须要求,两个操作数都是存储器操作)
- 待操作的数据串称为源串,目标地址称为目标串。
串操作指令说明
- 串操作指令的操作对象是多个字节数(一串字符或数据),因此,指令的执行需要确定:
- 串所在区域
- 串首地址(原串、目标串起始地址)
- 串长度(大小)
- 串的操作方向
串操作指令的要求
- 串所在区域及首地址:
- 源串一般存放在数据段,偏移地址由SI指定。允许段重设。
- 目标串必须在附加段,偏移地址由DI指定。
- 串长度:
- 串长度值由CX指定
- 串的操作方向:
- 由DF标志位决定。指令根据DF状态自动修改地址指针
- DF=0 –> 增地址方向
- DF=1 –> 减地址方向
- 由DF标志位决定。指令根据DF状态自动修改地址指针
会有专门的指令设置DF值
通过增加重复前缀,可以实现对CX值对自动修改
重复前缀
- 无条件重复
- REP(repeat)
- 当CX
0时,REP后的指令将继续重复执行 - 常用于传送类指令前 -> 未传完则继续传送
- 当CX
- REP(repeat)
- 条件重复
- 相等(为零)重复:REPE(REPZ)
- CX
0 ZF=1, 则前缀后的指令将继续重复执行
- CX
- 不相等(不为零)重复:REPNE(REPNZ)
- CX
0 ZF=0, 则前缀后的指令将继续重复执行
- CX
- 相等(为零)重复:REPE(REPZ)
条件前缀常用于运算累指令前,当:
- 操作未结束 AND 结果=0 or
- 操作未结束 AND 结果
0
使其后的指令继续重复执行。
串操作指令
- 串传送MOVS
- 串比较CMPS
- 串扫描SCAS
- 串装入LODS
- 串送存STOS
串操作指令流程
在串操作中,右部4个模块,用(一条指令+重复前缀)来完成
完成一个字节(字)操作+修改地址指针,由串操作指令实现
重复前缀,实现了循环结构
若按增地址方向操作,串操作结束时:
- 串传送指令: 指针将指向串尾+1
- 串比较类指令:指针将指向结束位+1
若按减地址方向操作,串操作结束时:
- 串传送指令: 指针将指向串尾-1
- 串比较累指令: 指针将指向结束位-1
串传送MOVS
- func:
- 将源数据串传送到目标地址
- format:
- MOVS OPRD1, OPRD2(仅用于对源串段重设)
- MOVSB(按字节传送)
- MOVSW(按字传送)
- 串传送指令通常与无条件重复前缀连用
应用例子:
分别用MOV指令和MOVS指令编写将200字节数数据从内存数据段MEM1为首地址的区域送到同一逻辑段MEM2为首地址的区域中的程序。
MOV指令实现算法:
1 | LEA SI, MEM1 |
MOVS指令实现算法:
1 | LEA SI, MEM1 |
串比较CMPS
在上一节的例子中,完成操作后,检验代码是否正确运行————可以利用串比较指令进行检验
- func:
- 用于实现两个数据串的比较
- manipulation:
- 目标串-源串,结果不写回目标地址
- 常与条件重复前缀连用
- format:
- CMPS OPRD1 OPRD2 (仅段重设采用)
- CMPSB
- CMPSW
前缀的操作对标志位不影响(虽然会进行CX-1操作)
串比较指令会影响全部6个标志位
- 测试上例中200Bytes数据传送是否正确。
1 | LEA SI, MEM1 |
串扫描SCAS(scan string)
常用于在指定存储区域中寻找某个关键字
- format:
- SCAS OPRD <– 目标操作数(被查找的长串)
(目标操作数,一般在附加段ES,指针为DI) - SCASB
- SCASW
- SCAS OPRD <– 目标操作数(被查找的长串)
- 执行与CMPS指令相似的操作,区别是:
- 这里的源操作数是AX或AL(需要查找的pattern)
(按字节扫描AL,按字扫描AX)
- 这里的源操作数是AX或AL(需要查找的pattern)
串扫描指令应用例:
- 在ES段中从2000H单元开始存放了10个字符,寻找其中有无字符“A”。若有则记下搜索次数,将搜索次数写入到DATA1单元,并将存放“A”的地址写入DATA2单元。
1 | MOV DI, 2000H |
串装入LODS
format:
- LODS OPRD –> 源操作数,指针必须使用SI寄存器
- LODSB
- LODSW
manipulation:
- 对字节: AL <– [DS:SI]
- 对字 : AX <– [DS:SI]
用于将内存某个区域的数据串一次装入累加器,以便显示或输出到接口。
LODS指令一般不加重复前缀。
与MOV指令无异
串存储STOS(store string)
- format:
- STOS OPRD –> 目标操作数
- STOSB
- STOSW
- manipulation:
- 对字节: AL –> [ES:DI]
- 对字: AX –> [ES:DI]
- 常用于将内存某个区域置同样的值
- 此时:
- 将待送存的数据放入AL(字节数)或AX(字数据);
- 确定操作方向(增/减地址)和区域大小(串长度值)
- 使用串存储指令+无条件重复前缀,实现数据传送
串操作Notes
- 需要定义附加段(ES
- 目标操作数必须在附加段
- (第四章会学习如何定义附加段)
- 需要设置数据的操作方向
- 确定DF的状态
- 源串和目标串指针分别为SI和DI
- 串长度值必须由CX给出
- 注意重复前缀的使用方法
- 传送类指令前加无条件重复前缀
- 串比较类指令前加条件重复前缀,但前缀不影响ZF状态
无论是串传送还是串比较完成,无论是否满足,都是先修改指针+修改长度值,再判断是否满足条件。
哪怕串比较不相等,不再继续,但是指针已经在跳出位置下一内存单元了
- Post title: microcomputer_principle_06_位移操作与串操作
- Create time: 2023-02-19 19:11:25
- Post link: embedded-system/microcomputer-principle-06-位移操作与串操作/
- Copyright notice: All articles in this blog are licensed under BY-NC-SA unless stating additionally.