汇编学习笔记(13)--字符串操作

字符串操作指令包括:

​ movs 字符串传送

​ cmps 字符串比较

​ scas 字符串扫描

​ stos 存入字符串

​ lods 从字符串取

指令前缀

​ rep 重复

​ repe 相等则重复

​ repz 结果为0则重复,与repe等价

​ repne 不相等则重复

​ repnz 结果不为0则重复,与repne完全等价

单独的字符串指令表示执行一次字符串操作,加了指令前缀的字符串指令表示重复执行字符串操作

字符串传送指令 movsb movsw movs

[rep] movsb;以字节为单位传送字符串
;movsb
;byte ptr es:[di]=byte ptr ds:[si]
;if df==0 si++ di++;正方向
;else si-- di--;反方向
;rep movsb
again:
	if cx==0
	goto done
	else 
	byte ptr es:[di]=byte ptr ds:[si]
	if df==0 si++ di++
	else si-- di--
	cx--
	goto again
;注意,是先赋值,然后++,

[rep] movsw;以字为单位传送字符串,类似
不过里面的si,di+2

[rep ] movs byte ptr es:[di],byte ptr seg:[si]
;类似上面的movsb,但这里区别就是源段地址寄存器不只是ds可以任意指定,当然也可以都是es

[rep ]movs word ptr es:[di],word ptr seg:[si]

字符串比较指令:cmpsb,cmpsw,cmps

[repe|repne]cmpsb;以字节为单位比较字符串
;cmpsb
;null=byte ptr ds:[si]-byte ptr es:[di]比较ds:[si]与es:[di]
;temp=fl
;if df==0 si++ di++
;else si-- id--
;endif,fl=temp
;repe cmpsb
again:
	if cx==0
	goto done
	else
	{
	null=byte ptr ds:[si]-byte ptr es:[di]
	temp=fl
	;if df==0 si++ di++
   ;else si-- id--
	cx=cx-1
	fl=temp
	if zf==1;若两者不相等,那么就不循环了,就可以直接得出两个字符串不一样
	goto agaim
	}
;继续下次比较的条件是cx!=0,zf=1

;repne cmpsb
;与repe唯一区别就是 if zf==0 goto again
;若两者相等,就不继续比较,只有不相等才继续循环
;继续下次比较的条件是zf=0,cx!=0

repe cmpsb 等价于repz cmpsb
repne cmpsb等价于repnz cmpsb

;注意,cmp与mov指令都会在结束后指向下一个字符,他们总是现为下次做好准备,然后才判断本次比较是否相等

[repe|repne ]cmpsw;以字为单位比较
[repe|repne ]cmps byte ptr seg:[si],byte ptr es:[di]
[repe|repne ]cmps word ptr seg:[si],word ptr es:[di]

字符串扫描指令 scasb,scasw

[repe|repne] scasb;在字符串中查找一个字符
scasb
;null=al-byte ptr es:[di];比较al与byte ptr es:[di]
;temp=fl
;if(df==0) di++ else di--
;fl=temp
repe scasb
;again:
	;if(cx==0)
	;goto done'
	else{
	null=al-byte ptr es:[di]
	temp=fl
	if (df==0)di++ else di--
	cx--
	fl=temp
	if(zf==1)
	goto again
done:
	}
repne scasb
;与上面的位移区别就是判断zf==0

repe scasb要求本次扫描相等才进行下次扫描,而repne scasb要求本次扫描不相等才进行下次扫描
;格式
scasb
repe scasb ;等价于 repz scasb
repne scasb ;等价于repnz scasb

例子:求一个字符串长度,(该字符串以00h结束),长度不包括结束字符串
mov ax,1000h
mov es,ax
mov di 10a0h;es:di指向目标首字符
movv cx,0ffffh;最多查找65535次
mov al,00h;带查找字符
cld;df==0,正向
repne scasb;因为之前循环的条件都是不相等,所以用repne
;指令结束时,由于repne内部实现的机理,di指向的是00h后面的一个字节
dec di;这个时候才指向的是00h
sub di,10a0h
mov cx,di;字符串的长度
;;注意,字符串扫描指令同字符串比较,总是先为下次扫描作准备,然后才判断本次扫描是否相等

[repe|repne] scasw;在字符串中查找一个字
scasw
null=ax-word ptr es:[di];比较ax和es:[di]
temp=fl
if df==0 di+2 else di-2
fl=temp
;类似于scasb,只不过al换成ax,byte ptr换成word ptr,di++换成di+2

存入字符串指令stosb,stosw

[rep]stosb;存入字节到字符串
;stosb操作
byte ptr es:[di]=al
if(df==0)di++ else di--
;rep stosb操作
again:
if(cx==0) done
else{
byte ptr es:[di]=al
if (df==0) di++ else di--
cx--
goto again
}
其实比较像我们在定义数据段200 dup(0)
ex:用存入字符串指令按照正方向填100个0
mov ax,1000h
mov es,ax
mov di,10a0h
mov cx,100h
mov al,0
cld
rep stosb

[rep] stosw
类似,只不过word ptr es:[di]=ax,di+2或di-2

从字符串读取字节或字指令 lodsb,lodsw,lods

lodsb;从字符串读取字节
;操作
al=byte ptr ds:[si]
if(df==0) si++ else si--
例子:设存放了old red cracker字符串,长度为15字节额,把除空格意外复制到2000:20f0中
mov ax,1000h
mov ds,ax
mov ax,2000h
mov es,ax
mov si 10A0h
mov di,20f0h
mov cx,15
cld
again:
	lodsb;al=ds:[si]并且si++
	cmp al,' '
	je next
	stosb;es:[di]=al,并且di++指向下一个储存的位置
next:
	dec cx
	jnz again

lodsw
;操作类似,不过是ax=word ptr ds:[si],si+2或si-2

lods byte ptr seg:[si]
;区别就是seg可以是cs,es,ds,ss任意一个
lods word ptr seg:[asi]
;同上
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值