汇编之串处理指令


前言

串处理指令一般与REP指令配合。
因为串操作指令其实只是对
“串”主要就体现在REP上
REP是前缀,但它不是伪指令,REP有具体功能,它可以判断CX是否为0,还可以执行CX=CX-1
CX的递减不影响标识位

串处理指令

与REP相配合的串传送指令

串传送类指令不影响标志位。
也就是说
MOVSB、MOVSW、MOVS;
LODSB、LODSW、LODS;
STOSB、STOSW、STOS
都不影响标志位。
但是它们受到方向标志位DF的影响。
很好的关于指令影响标志位的百度文档。

REP

REP重复串操作直到CX的内容为0为止
在这里插入图片描述
请注意,REP是前缀,但它不是伪指令,因为它有具体功能。像上面列出的判断CX是否为0,让CX-1等都是它的功能。
还要注意CX的递减不影响标志位。

MOVS

格式

在这里插入图片描述
MOVSB和MOVSW不需要有操作数,因为他们的操作数都是定好了的。
就是ES:DI⬅DS:SI(注意箭头方向)
不同的就是转移的是字节还是字

注意BYTE PTR和WORD PTR
它们用于指明字节
MOV ES:DI DS:SI
有一个操作数写明WORD PTR或BYTE PTR就行了。

MOV这种指令,起码有一个操作数一定要是位数清晰的,如果不清晰明确,就要指明
像PUSH,POP这种指令,就不需要指明,因为它们就只做字操作。

执行的操作

在这里插入图片描述
方向标志位DF决定串传送的方向。
SI和DI加一或者减一,这是由DF决定的。
如果CLD了,DF=0了,那就是SI+1和DI+1

串操作的准备工作

在这里插入图片描述
一般来说,源串存放在数据段中,目的串存放在附加段中。
使用REP重复前缀前,要把数据串长度放入CX
回忆一下移位操作,如果移位次数大于1,也要将移位次数放入CL

做准备工作不要忘记设置方向标志
CLD——使DF=0——增地址——先传小地址
STD——使DF=1——减地址——先传大地址

带重复前缀的串传送指令

在这里插入图片描述
先判断是否为0,再减1,再执行传送操作
REP MOVSB
REP MOVSW
这两条语句都不影响标志位。

例一
在这里插入图片描述
在这里插入图片描述
例二
在这里插入图片描述
在这里插入图片描述
17,也就是不包括$
$在汇编中是字符串结束的标志
$在字符串中显示不了,如果偏得要他显示那就得找别的方法。
在这里插入图片描述
REP MOVSB
先判断CX是否为0,CX=17,显然不为0,于是CX-1=16,再执行传送字节的操作,然后SI+1,DI+1,再判断CX是否为0,再减1,再执行传送字节操作,直到CX减到0,判断的时候发现CX是0,就停止操作
简洁的总结一下:

首先判断CX是否为0
不等于0的话

  1. CX-1
  2. 传送字节
  3. SI±1(或2),DI±1(或2)

判断CX是否为0
如此循环
一开始SI和DI指向要被复制和填充的第一个单元,最后SI和DI指向被复制和填充的最后一个单元的下一个单元。

STOS

在这里插入图片描述
注意存入字节的话,用的是AL
其实我感觉这种情况下,用的一般都是AL哈

STOS是存进去一堆一样的,可以用于初始化。
在这里插入图片描述
注意执行完之后,DI是指向最后一个单元的下一个单元。
20H是空格的ASCII码

LODS从串取指令

在这里插入图片描述
LODS拿出来的只能存在AX里
所以与REP连用是没有意义的
最后AX中只有最后拿出来的那一个
就像狗熊掰苞米,最后夹在咯吱窝里的只有哪一个了。
在这里插入图片描述
注意高字节在高地址,低字节在低地址

串比较指令

与REPE/REPZ和REPNE/REPNZ联合工作的串比较指令CMPS和SCAS
REPE/REPZ和REPNE/REPNZ中CX的递减不影响标志位(即使CX减到零,也不影响)。
CMPS/SCAS则根据减法的结果设置标志位。
说实话这里,还有前面的STOS之类的,可能基本概念你掌握了,但是应用还是不熟练的,这个我们之后再补充,比如说
LODS SRC
这个用法你还是不知道怎么用啊
(虽然这个用法可能也不常见)
总之我们之后再通过实践来补充吧。但是这块的实践可是也不简单!加油!

注意:
字符串比较,关键的唯一的条件是ZF
如果只有最后一个字节不同,CX=0后退出重复。这个时候你还是要看ZF!如果你看到CX=0就觉得比较完了他俩都一样,这是不行的,你必须看ZF,如果ZF=0,就说明最后一个字节不同;ZF=1,就说明最后一个字节相同。
其实不止是最后一个字节,每个字节的比较的结果都要看ZF才能看出来
关键在于CX=0是退出条件,CX不能体现字符串比较出的结果,CX=0只能说明每一个都比完了,至于结果,结果唯一的条件就是ZF

REPE/REPZ 当相等/为零时重复串操作

在这里插入图片描述
REPE和REPZ是完全相等的同义词!两者可以随意相互替换。
E-Equal 相等
Z-ZF
相等的话,结果为0,ZF就等于1这里真的好容易犯糊涂),因此从字面上也能看出虽然指令有一个字母的不同,但它们的意思是一样的。
REPE/REPZ——相等则重复,也就是说
ZF=1且CX≠0时重复
ZF=1,表示结果为0,两数相等;CX≠0,表示任务还没结束,还没扫描到字符串的结尾。
常用于比较指令
如果一直扫描到最后,我们就可以说这两个字符串完全相等。
执行的操作是先判断CX是否为0,ZF是否为0,CX=0,ZF=0两个条件满足一个就退出。否则继续向下,CX=CX-1,执行其后的串指令。
重复上述过程。
注意CX的递减不影响标志位。
DF决定先查小地址还是先查大地址
DF=0:先查小地址,增地址
DF=1:先查大地址,减地址
CLD使DF置0
STD使DF置1

REPNE/REPNZ 当不相等/不为零时重复串操作

在这里插入图片描述
同样地,REPNE和REPNZ也是完全相等的同义词!两者可以随意相互替换。
REPNE/REPNZ——不相等则重复
ZF=0且CX≠0时重复
ZF=0,表示两数相减结果不为0,两数不相等;CX≠0,表示任务还没结束。
退出条件:
常用于查找指令
比如要在一个很长的字符串里找到空格,就用REPNE或REPNZ,不相等会重复,相等时就停下。
执行的操作是先判断CX是否等于0,ZF是否等于0,CX=0,ZF=1满足其中一个就退出,否则向下执行,CX=CX-1,执行其后的指令。
重复上述操作。
注意CX的递减不影响标志位。

CMPS 串比较指令

在这里插入图片描述
用源串中的一个字节(或者字)减去目的串中的一个字节(或者字)
因为做了减法,结果很显然会对标志寄存器产生影响,如果结果为0,ZF标志位会等于1

SCAS 串扫描指令

在这里插入图片描述
用AL中的字节(或者字)和附加段中的字符串中的一个字节(或者字)做减法。
要记住8086的内存是以8位的字节为单位来组织的。

例题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
DS和ES重叠,注意要从下面开始传送,注意串传送是从数据段传到附加段。
所以它这里说的向前移动一个不是图片上的向前,指的是地址上向前,而且移动的是一个字,也就是两个单元。
如果从P开始传送,因为DS和ES是重叠的,P会覆盖掉R,SI和DI向下再向下后指向的单元的内容还是P,这就不对了。
如果从下面开始,S先放到比S大两个字节的地方(这个地方原来是空的),R再放到比S原来的地方大一个字节的地方,这样是对的。

在这里插入图片描述
源串首地址送DI
请注意EXIT后的内容
先DEC DI,再将DI送BX
因为REPNE中,先看CX是否为0,然后CX-1,然后做减法,然后DI+1
这一串都做完之后,判断是否达到退出重复的条件,如果达到了条件,就向下执行,然后才到
JZ EXIT
要明白,SCASB只是一条指令而已!做重复的是REPNE,REPNE是ZF等于0时重复,也就是结果不为零,相减的两个数不相等的时候重复。找到#的时候ZF=0了,REPNE就不重复了,就执行下面的JZ EXIT。
当然不重复还有一种可能是都扫描完了也没找到#,这个时候也结束重复,执行下面的JZ,但是因为此时ZF=0,所以不会跳转。
找到#的话,JZ EXIT会跳转。
但是此时DI指向的是#的后面一个单元,因为SCAS做完减法后紧接着就会让地址DI+1。
因此要让DI-1,这才得到#字符(一个8位的字符)所在的地址。

  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值