汇编语言程序设计第5章循环程序设计汇编语言程序设计DO-WHILE结构DO-UNTIL结构控制条件初始化循环体YN控制条件初始化循环体YN循环程序结构设置循环的初始状态循环的工作部分及修改部分1.计数控制:循环次数已知2.特征值控制:次数已知,提前结束3.地址边界控制:循环次数未知汇编语言程序设计一、循环指令LOOP//计算0+1+2+3+4+5+6+7+8+9的值intsum=0;for(inti=0;i10;i++)sum=sum+i;//计算0+1+2+3+4+5+6+7+8+9的值movax,0movbx,0movcx,10s:addax,bxincbxloops标号S代表一个地址ax相当于sumbx相当于i判断汇编语言程序设计Loop指令指令的格式是:loop标号CPU执行loop指令的时候,要进行两步操作:–①(cx)=(cx)-1;–②判断cx中的值,不为零则转至标号处执行程序,如果为零则向下执行,退出循环。可见,cx中的值影响着loop指令的执行结果。用loop指令来实现循环功能时,cx中要存放循环次数。汇编语言程序设计一条循环指令可以用修改循环计数和判断转移条件的两条指令替代LOOPAGAINDECCXJNZAGAIN汇编语言程序设计例:求首地址为ARRAY的M个字之和(不考虑溢出),结果存入TOTAL(ARRAY和TOTAL都被定义为字变量)MOVCX,MMOVAX,0MOVSI,AXAGAIN:ADDAX,ARRAY[SI]ADDSI,2LOOPAGAINMOVTOTAL,AX寄存器相对寻址方式汇编语言程序设计例:编制程序将存放在首地址为ARRAY的字符串“happynewyear”向高地址方向移动一个字节的位置datasegmentarraydb‘happynewyear’dataendscodesegmentassumecs:code,ds:datastart:movax,datamovds,axmovax,4c00hint21hcodeendsendstartmovcx,14;设置循环次数movbx,13;初始化s:moval,array[bx]movarray[bx+1],aldecbxloops汇编语言程序设计二、可提前结束的循环指令功能格式测试条件当为0或相等时循环LOOPZ/LOOPE标号ZF=1且(CX)≠0不为0或不相等循环LOOPNZ/LOOPNE标号ZF=0且(CX)≠0执行步骤:(1)(CX)←(CX)-1(2)检查是否满足测试条件,如满足则实现循环;不满足则退出循环。注意:*CX中存放循环次数*与比较指令CMP联合使用可提前退出循环。汇编语言程序设计例:编制程序查找存放在首地址为string的字符串中的字母“n”,找到则将其改为大写的“N”,没找到则结束程序datasegmentstringdb‘happynewyear’dataendscodesegmentassumecs:code,ds:datastart:movax,datamovds,axmovax,4c00hint21hcodeendsendstartmovcx,14;设置循环次数movbx,-1;初始化moval,”n”s:incbxcmpal,array[bx]loopnzs(若zf=0,没有找到,结束程序)movarray[bx],”N”汇编语言程序设计思考题:对于如下程序movax,2movcx,3s:addax,2s1:loopsmovdi,offsets1movsi,offsets3movax,cs:[di]movcs:[si],axmovax,1movcx,3s2:addax,2s3:nopnop所有指令执行完后ax的值为_____。A、15B、7C、11D、3B汇编语言程序设计BX1234例1:把BX中的二进制数以十六进制的形式显示在屏幕上BX循环左移4位高位清零,保留低4位转换为ASCII码是A~F?加7显示字符汇编语言程序设计……movch,4;设置循环次数rotate:movcl,4;设置移位位数rolbx,cl;循环左移4位moval,bl;取低8位andal,0fh;保留低4位addal,30h;’0’~’9’ASCII30H~39Hcmpal,3ahjlprintit;判断是否为字母,不是则跳转addal,7h;’A’~’F’ASCII41H~46Hprintit:movdl,almovah,2int21h;调用功能号2,显示一个字符decchjnzrotate……汇编语言程序设计思考题要把BX中的二进制数以十进制的形式显示在屏幕上,怎么做?汇编语言程序设计……movbx,0newchar:movah,1;键盘输入int21hsubal,30h;ASCII码变数值jlexit;0退出cmpal,10jladd_tosubal,27h;‘a’~‘f’cmpal,0ahjlexit;‘a’退出cmpal,10hjgeexit;’f’退出add_to:movcl,4shlbx,cl;乘以16movah,0addbx,ax;加上输入的数值jmpnewcharexit:……例2:从键盘接收十六进制数并存入BX1af316166((0×16)+1)×16+0a)×16+0f汇编语言程序设计……movbx,0newchar:movah,1int21hsubal,30hjlexit;0退出cmpal,9jgexit;9退出cbw;扩展到AXxchgax,bxmovcx,10mulcxaddbx,axjmpnewcharexit:……例3:从键盘接收十进制数并存入BX((0×10)+1)×10+2)×10+5125313235汇编语言程序设计问题编程,将datasg段中每个单词的头一个字母改为大写字母。assumecs:codesg,ds:datasgdatasgsegmentdb‘1.file‘;定义了16个字节db'2.edit'db'3.search'db'4.view'db'5.options'db'6.help'datasgendscodesgsegmentstart:……codesgendsendstart汇编语言程序设计问题分析在datasg中定义了6个字符串,每个长度为16字节。(注意,为了直观,每个字符串的后面都加上了空格符,以使它们的长度刚好为16字节)。datasg中的数据的存储结构如图:因为它们是连续存放的,我们可以将这6个字符串看成一个6行16列的二维数组。汇编语言程序设计我们用bx作变量,定位每行的起始地址,用3定位要修改的列,用寄存器相对寻址的方式来对目标单元进行寻址,程序如下:movax,datasgmovds,axmovbx,0;指向第一行movcx,6s:moval,[bx+3]subal,20h;小写字母改为大写mov[bx+3],aladdbx,16;指向下一行loops汇编语言程序设计问题编程:将datasg段中每个单词都改为大写字母。assumecs:codesg,ds:datasgdatasgsegmentdb‘ibm’;定义了16个字节db‘dec’db‘dos’db‘vax’datasgendscodesgsegmentstart:……codesgendsendstart汇编语言程序设计问题分析在datasg中定义了4个字符串,每个长度为16字节。datasg中数据的存储结构如图:我们需要修改每一个单词,即二维数组的每一行的前3列。汇编语言程序设计算法描述:R=第一行的地址设置外循环次数s0:C=第一列的地址设置内循环次数s:改变(R行,C列)的字母为大写C=下一列的地址;loopsR=下一行的地址loops0movax,datasgmovds,axmovbx,0;行地址movcx,4;外循环次数s0:movsi,0;列地址movcx,3;内循环次数s:moval,[bx+si]subal,20hmov[bx+si],alincsi;改变列地址loopsaddbx,16;改变行地址loops0程序有没有问题?汇编语言程序设计在多重循环的程序结构中,CX计数器的保存和恢复MOVCX,MAGAIN:……PUSHCXMOVCX,NNEXT:……LOOPNEXT……POPCXLOOPAGAINMOVDI,MAGAIN:……MOVCX,NNEXT:……LOOPNEXT……DECDIJNZAGAIN