作为汇编语言的课程笔记,方便之后的复习与查阅
本篇为课程第九次课内容
目录 串操作指令串寻址方式串传送MOVS(move string)串存储STOS(store string)串读取LODS(load string)串比较CMPS(compare string)串扫描SCAS(scan string)重复前缀指令(repeat)REPREPZ / REPNZ 处理机控制类指令空操作指令 NOP 串操作指令串操作指令采用比较特殊的数据串寻址方式,操作主存连续区域的数据
重点掌握:
MOVS STOS LODS CMPS SCAS REP( REPZ/REPE REPNZ/REPNE)串操作指令的操作数是主存中连续存放的数据串(String)——即在连续的主存区域中,字节或字的序列 该数据串是以字(W)为单位的字串,或是以字节(B)为单位的字节串
串寻址方式 源操作数用寄存器SI寻址,默认在数据段DS中,但允许段超越:DS:[SI]目的操作数用寄存器DI寻址,默认在附加段ES中,不允许段超越:ES:[DI]每执行一次串操作指令,SI和DI将自动修改: ±1(对于字节串)或±2(对于字串) 执行指令CLD指令后,DF = 0,地址指针增1或2 执行指令STD指令后,DF = 1,地址指针减1或2我们存储模式选择tiny,因此段不需要了解,可以认为所有的都在同一个段
串传送MOVS(move string)把字节或字操作数从主存的源地址传送至目的地址
MOVSB;字节串传送:ES:[DI]←DS:[SI];SI←SI±1,DI←DI±1MOVSW;字串传送:ES:[DI]←DS:[SI];SI←SI±2,DI←DI±2例:将长度为100字节的字符串soure,复制到destination 字节串传送:
mov si,offset sourcemov di,offset destinationmov cx,100;cx←传送次数cld;置DF=0,地址增加again:movsb ;传送一个字节dec cx;传送次数减1jnz again字串传送:
mov si,offset sourcemov di,offset destinationmov cx,50;cx←传送次数cld;置DF=0,地址增加again:movsw;传送一个字dec cx;传送次数减1jnz again 串存储STOS(store string)把AL或AX数据传送至目的地址
STOSB;字节串存储:ES:[DI]←AL;DI←DI±1STOSW;字串存储:ES:[DI]←AX;DI←DI±2例:将内存地址200H,长度为8000H范围内数据清零
mov ax,0mov di,200Hmov cx,8000h;cx←传送次数cld;DF=0,地址增加again:stosb ;传送一个字dec cx;传送次数减1jnz again;传送次数cx是否为0 串读取LODS(load string)把指定主存单元的数据传送给AL或AX
LODSB;字节串读取:AL←DS:[SI];SI←SI±1LODSW;字串读取:AX←DS:[SI];SI←SI±2例:对Block缓冲内的count字节数据进行处理:。正数存入dplus缓冲,负数存入dminus缓冲
mov si,offset blockmov di,offset dplusmov bx,offset dminus;数据都在一个段中,所以设置es=dsmov cx,count;cx←字节数cldgo_on:lodsb;从block取出一个数据test al,80h;检测符号位,判断是正是负jnz minus;符号位为1,是负数,转向minusstosb;符号位为0,是正数,存入dplusjmp again;程序转移到again处继续执行jnz go_on;完成正负数据分离minus:xchg bx,distosb;把负数存入dminusxchg bx,diagain:dec cx;字节数减1jnz go_on;完成正负数据分离 串比较CMPS(compare string)将主存中的源操作数减去目的操作数,以便设置标志,进而比较两操作数之间的关系
CMPSB;字节串比较:DS:[SI]-ES:[DI];SI←SI±1,DI←DI±1CMPSW;字串比较:DS:[SI]-ES:[DI];SI←SI±2,DI←DI±2例:比较字符串string1,string2,长度都为count, 相同result赋0,否则result赋0FFH.
mov si,offset string1mov di,offset string2mov cx,countcldagain:cmpsb ;比较两个字符jnz unmat;有不同字符,转移dec cxjnz again;进行下一个字符比较mov al,0;字符串相等,设置00hjmp output;转向outputunmat:mov al,0ffh;设置ffhoutput:mov result,al;输出结果标记 串扫描SCAS(scan string)将AL/AX减去目的操作数,以便设置标志,进而比较AL/AX与操作数之间的关系
SCASB;字节串扫描:AL-ES:[DI];DI←DI±1SCASW;字串扫描:AX-ES:[DI];DI←DI±2例:查找字符串string中是否包含空格, 有则转到found进行处理
mov di,offset stringmov al,20hmov cx,countcldagain:scasb ;搜索jz found;为0(ZF=1),发现空格dec cx;不是空格jnz again;搜索下一个字符...;不含空格,则继续执行found:... 重复前缀指令(repeat)串操作指令执行一次,仅对数据串中的一个字节或字量进行操作。但是串操作指令前,都可以加一个重复前缀,实现串操作的重复执行。重复次数隐含在CX寄存器中
重复前缀分2类,3条指令:
配合不影响标志的MOVS、STOS(和LODS)指令的REP前缀配合影响标志的CMPS和SCAS指令的REPZ和REPNZ前缀 REP REP;每执行一次串指令,CX减1;直到CX=0,重复执行结束例:将长度为100字节的字符串soure,复制到destination
mov si,offset sourcemov di,offset destinationmov cx,100;cx←传送次数cld;置DF=0,地址增加rep movsb;等价于下面三行;again:movsb ;传送一个字节;dec cx;传送次数减1;jnz again例:将内存地址200H,长度为8000H范围内数据清零
mov ax,0mov di,200Hmov cx,8000h;cx←传送次数cld;DF=0,地址增加rep stosb;等价于下面三行;again:stosb ;dec cx;jnz again REPZ / REPNZ REPZ;每执行一次串指令,CX减1;并判断ZF是否为0,;只要CX=0或ZF=0,重复执行结束REPZ/REPE前缀可以理解为:当数据串没有结束(CX≠0),并且串相等(ZF=1),则继续比较
REPNZ;每执行一次串指令,CX减1;并判断ZF是否为1,;只要CX=0或ZF=1,重复执行结束REPNZ/REPNE前缀可以理解为:当数据串没有结束(CX≠0),并且串不相等(ZF=0),则继续比较
例:比较字符串string1,string2,长度都为count, 相同result赋0,否则result赋0FFH.
mov si,offset string1mov di,offset string2mov cx,countcldrepz cmpsbjnz unmat;有不同字符,转移mov al,0;字符串相等,设置00hjmp output;转向outputunmat:mov al,0ffh;设置ffhoutput:mov result,al;输出结果标记例:查找字符串string中是否包含空格, 有则转到found进行处理
mov di,offset stringmov al,20hmov cx,countcldrepnz scasbjz found;为0(ZF=1),发现空格...;不含空格,则继续执行found:... 处理机控制类指令对CPU状态进行控制的指令
NOP CS: SS: DS: ES: 空操作指令 NOP不执行任何操作,但占用一个字节存储单元,空耗一个指令执行周期
NOP常用于程序调试
在需要预留指令空间时用NOP填充代码空间多余时也可以用NOP填充还可以用NOP实现软件延时