1.数据传送:问题描述:设在DS=3000H,偏移地址为0100H的内存中顺序存放着100个字节的数据。要求传送到以2000H为起始偏移地址的区域。代码:利用寄存器间接寻址来寻找操作数可以编程如下:movax,3000hmovds,ax;建立数据段movsi,0100h;建立源数据指针movdi,2000h;建立目的地指针movcx,100;设置计数器nt:moval,[si];取数mov[di],al;送数incsi;调整指针incdideccx;计数器减1jnent;CX-1≠0转nt标号另一种方法:提示:若将倒数第2、3行用REPMOVSB代替,则可进一步简化。MOVAX,3000HMOVDS,AXMOVES,AXMOVSI,0100HMOVDI,0200HMOVCX,100CLDNT:MOVSBLOOPNTINT20H2.多字节的加法:问题描述:有两个4字节的无符号数相加,这两个数分别放在2000H和3000H开始的存储单元中,低位在前,高位在后。运算后,得到的和放在2000H开始的内存单元中。代码:MOVSI,2000H;取第一个数的首地址MOVAX,[SI];将第一个数的低16位取到AXMOVDI,3000H;取第二个数的首地址ADDAX,[DI];两个数的低16位相加。MOV[SI],AX;低16位相加的结果送到2000H和2001H单元MOVAX,[SI+2];取第一个数的高16位送到AX中ADCAX,[DI+2];两个数的高16位连同CF相加MOV[SI+2],AX;高16位相加的结果送到2002H,2003H单元。3.多字节组合BCD码十进制加法问题描述:设第一个数据在1000H开始的8个内存单元中,第二个数据在2000H开始的8个内存单元中,要求相加之后将结果放在2000H开始的内存区域。代码:movsi,1000h;SI指向第一个数据movdi,2000h;DI指向第二个数据movcx,8;共有8字节长c1c;清除进位标志l1:mova1,[si];取第一个数据的1个字节adca1,[di];加上第二个数据的相应字节daa;对相加结果进行十进制调整mov[di],a1;存到指定的内存区域incsi;指向下一个字节incdi;指向下一个字节deccx;计数器减1jnzl1;如未算完,则继续int20h;返回DOS4.多字节的移位问题描述:使BX所指的四个单元中的四字节数左移1位,代码:SALWORDPTR[BX+0],lRCLWORDPTR[BX+2],15.ASCII码转换为BCD码问题描述:设键盘输入的100个十进制数的ASCII码已在首地址DS为3000H,偏移量为0100H的内存区域中,要求把它们转换为组合型BCD码,高地址的放在高半字节。存入偏移地址为0200H的区域中。分析:算法是这样的:先将较低字节的32H转换为02H,再将较高字节的34H转变为40H,然后将其与02H按位相或成为42H。循环50次完成50个字节的组合BCD码的转换。代码:MOVAX,3000HMOVDS,AXMOVSI,0100HMOVDI,0200HMOVCX,0032HNEXT:MOVAL,[SI]INCSIANDAL,0FHMOVBL,ALMOVAL,[SI]INCSIPUSHCXMOVCL,4SHLAL,CLPOPCXADDAL,BLMOV[DI],ALINCDILOOPNEXTINT20H6.比较两个字符串问题描述:假设两个字符串分别放在DS段(设ES=DS)的str1和str2区域,其长度分别为L1和L2,比较这两个字符串是否相等。若相等,则置M1单元内容为FFH,否则为00H。代码:提示:前缀REPZ和REPE表示,当作比较的两字节(或字)相等时继续往下比较直至出现不等,或者CX减为0为止。重复前缀使用前必须对CX置重复次数。每比较一次,CX-1→CX(字比较CX-1→CX)。CX=0表示两个字符串所有字节都比较过了,这时结束比较。前缀REPNE和REPNZ则表示字节(字)不等时继续往下比较。LEASI,STR1LEADI,STR2MOVCX,L1CMPCX,L2JNEUNEQCLDREPZCMPSBJNEUNEQMOVAL,0FFHJMPEXIT1UNEQ:MOVAL,00HEXIT1:MOVM1,ALINT20H7.有条件的数据传送问题描述:将从BLOCK1单元开始的100个字节传送到BLOCK2单元开始的区域中,两区域的相对位置不确定。数据传送过程中遇0DH(回车符)则结束传送。假设DS=ES,即BLOCK1和BLOCK2同在一个数据段,并且位置不定(BLOCK1值可以大于、小于或等于BLOCK2)。分析:由于该题要求有条件传送,使用MOVSB指令不如LODSB和STOSB方便。又因源数据区和目标数据区有可能重叠,所以应区分两种情况分别用地址增量和地址减量的方式来传送。若源地址大于目的地地址,则应用地址增量方式从首地址开始传送,反之,则应用地址减量方式从末地址开始传送。代码:LEASI,BLOCK1LEADI,BLOCK2MOVCX,100CMPSI,DIJEDONEJADFOSTDADDSI,99ADDDI,99JMPTRANDFO:CLDTRAN:LODSBCMPAL,0DHJEDONESTOSBLOOPTRANDONE:INT20H8.确定字符串的长度问题描述:在STRING为始地址的字符串中搜索字符串结束符“$”,并将字符串的长度(不包括“$”)放入STRLN单元中;如果连续100个字节单元之中无“$”符则在STRLN单元中填入0FFH。提示:目标串搜索指令SCASB和SCASW将AL(或AX)与ES:DI所寻址的字节(或字)内容进行比较而不改变其值;只影响标志位SF、ZF、PF、OF、CF、AF,并且修改DI指针使指向目标串中下一个元素。代码:LEADI,STRINGMOVAL,‘$’MOVCX,100CLDREPNESCANSBJZDONE1MOVAL,0FFHJMPDONE2DONE1:MOVBX,100SUBBX,CXDECBLMOVAL,BLDONE2:MOVSTRLN,ALINT20H另一方法:LEADI,STRINGMOVAL,‘$’MOVCX,100DECDIL1:INCDICMPAL,[DI]LOOPNEL1JZDONE1MOVAL,0FFHJMPDONE2DONE1:MOVBX,100SUBBX,CXDECBLMOVAL,BLDONE2:MOVSTRLN,ALINT20H9.求符号数的最大值问题描述:设数据区1000H开始的区域中存放着50个字节的符号数。要求找出其中最大的一个数并存到0FFFH单元。代码:MOVBX,1000HMOVAL,[BX]MOVCX,31HL1:INCBXCMPAL,[BX]JGEL2MOVAL,[BX]L2:DECCXJNEL1MOVBX,0FFFHMOV[BX],ALINT20H注:如果是无符号数则把JGEL2换为JAEL2。10.两个32位无符号数乘法问题描述:32位乘法需要做4次16位乘法,每次都要将部分积相加来实现,相加时则要注意位数对齐。我们用连续的四个字单元来存放乘积,各部分积应加到适当单元。分析:datasegmentnum1dw8000h,8000hnum2dw8008h,8000hmutdw4dup(0)dataendsstacksegmentstack’stack’db100dup(’s’)stackendscodesegmentpara‘code’assumecs:code,ds:data,ss:stackprocfarpushdsxorax,axpushaxmovax,datamovds,axleabx,num1movax,[bx];b→axmovsi,[bx+4];d→simovdi,[bx+6];c→dimulsi;b*dmov[bx+8],ax;部分积1存于积单元中。mov[bx+10],dxmovax,[bx+2];a→axmulsi;a*dadd[bx+10],axadc[bx+12],dx;带进位加入积2单元中movax,[bx];b→axmuldi;b*cadd[bx+10],ax;b*c加入积单元adc[bx+12],dx;带进位加至部分积3adcwordptr[bx+14],0;进位加至部分积4movax,[bx+2];a→axmuldi;a*cadd[bx+12],axadc[bx+14],dxretstaendpcodeendendsta11.datasegmentxdw12ydw?dataendsstacksegmentstack‘stack’db100dup(‘s’)stackendscodesegmentpara‘code’assumecs:code,ds:data,ss:stacksignprocfarpushdsxorax,axpushaxmovax,datamovds,axmovax,xandax,ax;建立标志jzzerojnsplusmovbx,0ffffhjmpdonezero:movbx,0jmpdoneplus:movbx,1done:movy,bxretsignendpcodeendsendsign12.大散转问题描述:根据BUFFER单元的值,转到相应的子程序。子程序的入口地址存放在转移表BRTAB中。若BUFFER内容等于n,则转到第n个子程序(n从1~256,0代表256)。代码:datasegmentbufferdb3brtabdw0000h,3000hdw0100h,3050hdw0000h,3090hdw0100h,4050hdw0000h,6000hdataendsstacksegmentstack‘stack’db100dup(‘s’)stackendscodesegmentpara‘code’assumecs:code,ds:data,ss:stackbrchprocfarpushdsxorax,axpushaxmovax,datamovds,axleabx,brtabmoval,bufferdecalmoavah,0shlax,1;AL*2shlax,1;AL*4addbx,axjmpdwordptr[bx]retbrchendpcodeendsendbrch13.数组求和问题描述:假设有一数组求和子程序SUM,试用这个子程序分别求出ARY1和ARY2两个数组的和,结果分别存入SUM1和SUM2字单元中。代码:datasegmentaryldb03h,07h,50h,06h,23h,45h,0f6h,0dfhlen1equ$-ary1sum1dw?ary2db33h,44h,55h,12h,78h,89h,0feh,0cdhlen2equ$-ary2sum2dw?dataendsstacksegmentstack‘stack’db100dup(’s’)stackendscodesegmentpara‘code’assumecs:codc,ds:data,ss:stackstaprocfarpushdsxorax,axpushaxmovax,datamovds,axmovax,len1pushaxleaax,ary1pushaxcallsummovax,len2pushaxleaax,ary2pushaxcallsumretstaendpsumprocpushbpmovbp,sppushaxpushbxpushcxpushfmovcx,[bp+6];getarraylenthmovbx,[bp+4];getoffsetaddressxorax,ax;sum=0add1:addal,[bx]adcah,0incbxloopadd1mov[bx],axpopfpopcxpopbxpopaxpopbpret4sumendpcodeendsendsta14.阶乘问题描述:确定变量NUMB的阶乘,把结果存入变量FNUMB。变量NUMB的值大于0且小于8。