分享

汇编语言---字符串操作指令

 dbn9981 2017-03-25

汇编语言---字符串操作指令

2010-07-20 20:41:32|  分类: ASM|字号 订阅

 
 
字符串操作指令的实质是对一片连续的存储单元进行处理,这片连续的存储单元由隐含指针DS:SI或ES:DI来指定;字符串操作指令可对内存单元按照字节、字、双字进行处理,并能根据操作对象的字节数使变址寄存器SI/DI增加或减少1、2、4字节;
规定如下:
A.当DF=0时,变址寄存器SI/DI增加1、2、4字节;即:变址寄存器SI/DI递增的步长可以是1、2、4字节;
B.当DF=1时,变址寄存器SI/DI减少1、2、4字节;即:变址寄存器SI/DI递减的步长可以是1、2、4字节;
一、取字符串数据指令(Load String Instruction)
从指针DI:SI所指定的内存单元开始,取一个字节/字/双字,然后存入到AL/AX/EAX中,并根据标志位DF的值对寄存器SI做相应的增减;把存放字符串数据的连续存储区当做是数据源,使用寄存器SI;
该指令的执行不会影响任何标志位;
指令格式: LODS         地址表达式
          LODSB/LODSW  地址表达式
          LODS         地址表达式 ;80386+
在指令LODS中,它会根据"地址表达式"的属性来决定读取一个字节、字或双字;即:当该地址表达式的属性为字节、字或双字时,将从指针DI:SI处读取一个字节到AL中,或读取一个字到AX中,或读取一个双字到EAX中,与此同时,SI还将分别增减1、2、4字节;
取字符串数据指令的功能示意图如下图所示:

八、重复字符串操作指令(Repeat String Instruction)
前面的字符串操作指令:取字符串数据、置字符串数据、字符串传送、输入字符串、输出字符串、字符串比较、字符串扫描,等指令,都是执行一次所具有的功能;但是,每个字符串通常都是由多个字符组成的,所以,需要重复执行这些字符串操作指令;为了满足这种需要,指令系统提供了一组重复前缀指令;
虽然在这些字符串指令的前面都可以添加一个重复前缀指令,但是由于指令执行结果的差异,对某个具体的字符串指令又不用重复前缀指令而改用其它循环来实现重复的需要;
重复字符串操作指令对标志位的影响是由被重复的字符串操作指令来决定;
1.重复前缀指令REP(Repeat String Instruction)
重复前缀指令是重复其后指定的字符串操作指令,重复的次数由计数寄存器CX来决定;

指令格式:
REP LODS/LODSB/LODSW/LODSD
REP STOS/STOSB/STOSW/STOSD
REP MOVS/MOVSB/MOVSW/MOVSD
REP INS/INSB/INSW/INSD
REP OUTS/OUTSB/OUTSW/OUTSD
重复前缀指令的执行步骤如下:

STEP1:判断: CX=0
STEP2:如果CX=0,则结束重复操作,执行程序中的下一条指令;
STEP3:否则,CX=CX-1(不影响相关标志位),并执行重复前缀指令后面指定的字符串操作指令,在该指令执行完后,再转到步骤STEP1;
从上面的重复前缀指令格式来看,虽然我们可以使用重复前缀指令来重复取字符串数据指令(第一组指令),但是可能会因为指令的执行结果而在程序中几乎不会使用;
例如:编写一段程序,计算字符串"12345abcdefg"中各个字符的ASCII之和;
解:
......
MESS DB '12345abcdefg'  ;在数据段进行变量说明
......
MOV AX,SEG MESS
MOV DS,AX
LEA SI,MESS             ;用DS:SI来指向字符串的首地址;
MOV CX,13D              ;重复次数
XOR BX,BX               ;置求和的初值为0
REP LODSB               ;循环去处字符;
......
从程序片段中看,虽然"REP LODSB"能从字符串中逐一取出每个字符,但这个操作是在同一条指令中完成的,程序的其它指令根本无法处理每次取出的字符数据,指令的执行结果是:AL中只保存了最后一次取出的字符'h'的ASCII码;
所以,为了实现本例的要求,不能使用重复前缀指令,而要把指令"REP LODSB"改写成如下四条指令:
      XOR AH,AH     ;为后面的累加做准备
AGAIN:LODSB
      ADD BX,AX     ;AL是被取出的字符,AH已被清0
      LOOP AGAIN
2.条件重复前缀指令(Repeat String Conditionally)
条件重复前缀指令与重复前缀指令的功能相似,所不同的是:条件重复前缀指令中的重复次数不仅由CX来决定,而且还会由标志位ZF的值来决定;根据ZF所起的作用又可分为两种:相等重复前缀指令和不等重复前缀指令;
A.相等重复前缀指令:
指令格式:
REPE/REPZ SCAS/SCASB/SCASW/SCASD
REPE/REPZ CMPS/CMPSB/CMPSW/CMPSD
该重复前缀指令的执行步骤如下:

STEP1:判断条件: CX!=0 且 ZF=1
STEP2:如果条件不成立,则结束重复操作,执行程序中的下一条指令;
STEP3:否则,CX=CX-1(不影响任何标志位),并执行重复前缀指令后面指定的字符串操作指令,在该指令执行后,再转到步骤STEP1;
B.不等重复前缀指令:
指令格式:
REPNE/REPNZ SCAS/SCASB/SCASW/SCASD
REPNE/REPNZ CMPS/CMPSB/CMPSW/CMPSD
该重复前缀指令的执行步骤如下:

STEP1:判断条件:CX!=0 且 ZF=0
STEP2:如果条件不成立,则结束重复操作,执行程序中的下一条指令;
STEP3:否则,CX=CX-1(不影响任何标志位),并执行重复前缀指令后面指定的字符串操作指令,在该指令执行完后,再转到步骤STEP1;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章