第4章习题及参考解答1.试编一程序,把地址偏移量为100H单元开始的256个单元分别写入00H,01H,02H,03H,…,FFH数据。解源程序如下DATASEGMENTORG100HBUF1DB256DUP(?)COUNTEQU$-BUF1DATAENDSSTKSEGMENTSTACKDB100DUP(?)STKENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVSI,OFFSETBUF1;戓LEASI,BUF1MOVCX,COUNTXORAL,AL;或MOVAL,00HNEXT:MOV[SI],ALINCALINCSILOOPNEXTMOVAH,4CHINT21HCODEENDSENDSTART2.统计上题写入的数据块中0元素、正元素、负元素的个数,并分别把统计结果送入上述数据块之后的三个单元中。解DATASEGMENTORG100HBUF1DB00H,01H.02H,…,0FEH,0FFH;共256个数据COUNTEOU$-BUF1DB3DUP(?)DATAENDSSTKSEGMENTSTACKDB100DUP(?)STKENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVS1,OFFSETBUF1MOCCX,COUNTXORBX,BX;BL与BH分别存放正、负元素的个数XORDH,DH;DH寄存器存放0元素个数NEXT2:MOVAL,[SI]CMPAL,0JZZER0;若ZF=1,则为0,转至ZERO,DH+1JSNEGAT;若SF=0则为负数,BH+1INCBL;既不是0又不是负,则为正数,BL+1JMPNEXT3ZERO:INCDH;0的个数加1JMPNEXT3NEGAT:INCBH;负数个数加1NEXT3:INCSI;修改地址指针SILOOPNEXT2;未完,继续循环MOV[SI],DH;存入0元素个数统计结果INCSIMOV[SI],BX;存入正、负数个数统计结果MOVAH,4CHINT21HCODEENDSENDSTART4.把地址偏移量为STRG1单元开始的128个单元的内容传送到地址偏移量为STRG2开始的单元中。解DATASEGMENTSTRGlDBXXH,XXH,XXH,….XXH;128个数据COUNTEOU$-STRGlSTRG2DB128DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVSI,OFFSETSTRG1MOVDI,OFFSETSTRG2MOVCX,COUNTCLDREPMOVSBMOVAH,4CHINT21HCODEENDSENDSTART5.寄存器SI做地址指针,自SI所指的内存单元开始连续存放三个无符号数(以字为单位),编一程序求它们的和,并将结果存放在这三个数之后的单元中。解DATASEGMENTBUFDWXXH,YYH,ZZHSUMDW?,?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVSI,OFFSETBUFMOVDI,OFFSETSUMMOVAX,[SI]ADDAX,[SI+2]MOV[DI],AXMOVAX,0ADDCAX,0MOV[DI+2],AXMOVAX,[DI]ADDCAX,[SI+4]MOV[DI],AXMOVAX,0ADDCAX,[DI+2]MOV[DI+2],AXMOVAH,4CHINT21HCODEENDSENDSTART6.读下面程序段,问:在什么情况下本段程序的执行结果是AH=0?START:INAL,5FHMOVAH,0JZBRCHMOVAH,0JMPSTOPBRCH:MOVAH,0FFHSTOP:INT20H解当标志寄存器的ZF=0时,执行结果AH=0。(JZ之前的两条指令对零标志没有影响)7.下面语句在存储器中分别为变量分配多少字节?0NEDW10TW0DW4DUP(?),5THREEDB2DUP(?,8DUP(0))COUNTEQU10FOURDDCOUNTDUP(?)FIVEDB‘HOWAREYOU?’解ONEDW10;为ONE分配2个字节TWODW4DUP(?),5;为TWO分配10个字节THREEDB2DUP(?,8DUP(0));为THREE分配18个字节COUNTEQU10;不给COUNT分配存储单元FOURDDCOUNTDUP(?);为FOUR分配40个字节FIVEDB‘HOWAREYOU?’;为FIVE分配12个字节8.数据定义语句如下所示:FIRSTDB90H,5FH,6EH,69HSECONDDB5DUP(?)THIRDDB5DUP(?)FORTHDBDUP(?)自FIRST单元开始存放的是一个四字节的十六进制数(低位字节在前),要求:(1)编一段程序将这个数左移两位后存放到自SECOND开始的单元(注意保留移出部分);(2)编一段程序将这个数右移两位后存放到自THIRD开始的单元(注意保留移出部分);(3)编一段程序将这个数求补后存放到自FORTH开始的单元。解DATASEGMENTFIRSTDB90H,5FH,6EH,69HSECONDDB5DUP(?)THIRDDB5DUP(?)FORTHDBDUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXCALLSUBP1CALLSUBP2CALLSUBP3MOVAH,4CHINT21HSUBP1PROCMOVSI,OFFSETFIRSTMOVDI,OFFSETSECONDXORBL,BLMOVCL,2MOVAX,[SI]MOVDX,[SI+2]LOP1:SHLAX,1RCLDX,1RCLBL,1DECCLJNZLOP1MOV[DI],AXMOV[DI+2],DXMOV[DI+4],BLRETSUBP1ENDPSUBP2PROCMOVSI,OFFSETFIRSTMOVDI,OFFSETTHIRDXORBL,BLMOVCL,2MOVAX,[SI]MOVDX,[SI+2]LOP2:SHRDX,1RCRAX,1RCRBL,1DECCLJNZLOP2MOV[DI],BLMOV[DI+1],AXMOV[DI+3],DXRETSUBP2ENDPSUBP3PROCMOVSI,OFFSETFIRSTMOVDI,OFFSETFORTHMOVAX,[SI]MOVDX,[SI+2]NOTAXNOTDXADDAX,1ADCDX,0MOV[DI],AXMOV[DI+2],DXRETSUBP3ENDPCODEENDSENDSTART9.指令语句ANDAX,OPD1ANDOPD2中,OPD1和OPD2是两个已赋值的变量,问两个AND操作分别在什么时间进行?有什么区别?解前面的AND是指令,在程序运行时执行,后面的AND是运算符,在汇编的时候由汇编程序计算,表达式计算结果出现在执行程序中。二者的区别在于,前者是指令,程序运行时执行,后者是运算符,汇编时计算。10.如下指令或程序是否有错,若有错,请指出错在哪里?(1)KIEOU1024┇MOVK1,AX(2)MOVDS,100MOV[1000],[2000](3)IMPDB?┇MOVIMP,AX(4)A1DB?A2DB10┇CMPA1,A2(5)将1000送入X1单元,用如下程序:X1DB?┇MOVBX,X1MOV[BX],1000解(1)MOVK1,AX错。因为K1为立即数,它不能作为目的操作数。(2)这两条指令都是错的。第一条立即数不能直接送给段寄存器;第二条两个操作数不能同时为内存操作数。(3)MOVIMP,AX错。两操作数类型不匹配,IMP是一字节内存单元,而AX寄存器中为16位数据。(4)CMPA1,A2错。两个操作数A1与A2不能同时为内存操作数。(5)MOV[BX],1000错。两操作数类型不匹配,[BX]只定义了一字节单元,而1000是16位数据。11.8086汇编语言程序中段的类型有几种?各段如何定义?段定义语句中,定位类型、组合类型、类别各起什么作用?各有什么含义?解8086汇编语言中,段的类型有三种,即代码段、堆栈段、数据段(附加数据段可归属于数据段)。各段可用段定义语句(SEGMENT与ENDS)和段名赋给段寄存器语句(ASSUME)来定义。段定义语句中,定位类型表示此段的起始边界要求,可允许4种段的起始边界,即PAGE、PARA、WORD或BYTE。它们分别表示段的起始值为以页、节、字、字节为边界,若此项省略,则默认值为PARA。组合类型用来告诉连接程序本段与其他段的关系,分别为NONE、PUBLIC、COMMON、AT表达式、STACK或MEMORY。每一种的含义请参看主教材。类别是连接程序(LINK)需要的。它可以是任何合法的名称,必须用单引号括起来,连接程序只使同类别的段发生关联。典型类别如‘CODE’、'STACK'。12.使用DOS功能调用0AH从键盘输入40个字符的字符串并将其送入一输入缓冲区。在按下Enter键后,显示这些字符。解NAMEKBDINPUTCODESEGMENTASSUMECS:CODE,DS:CODEORG100HSTART:JMPBEGINBUFDB41NUMBDB?CHARSDB41DUP(?)MSG1DB'Typeanything,followedbyenter.',0DH,0AH,'$'MSG2DB0DH,0AH,'ContentsoftheKBDinputbuf:',0DH,0AH,'$'BEGIN:MOVAX,CSMOVDS,AXMOVDX,OFFSETMSG1MOVAH,9INT21HMOVDX,OFFSETBUFMOVAH,0AHINT21HMOVDX,OFFSETMSG2MOVAH,9INT21HXORBX,BXMOVBL,NUMBMOVCHARS[BX],'$'MOVDX,OFFSETCHARSMOVAH,9INT21HMOVAH,4CHINT21HCODEENDSENDSTART说明本题把数据区放在代码段中,没有单独定义数据段。并且用ORG100H语句把程序起始地址的偏移量放在100H开始的单元,用JMPBEGIN指令跳过数据区,这样可以把该程序经汇编、连接后的执行程序(.EXE)用EXE2BIN软件生成.COM文件。或:DATASEGMENTBUFDB41NUMBDB?CHARSDB41DUP(?)MSG1DB'Typeanything,followedbyenter.',0DH,0AH,'$'MSG2DB0DH,0AH,'ContentsoftheKBDinputbuf:',0DH,0AH,'$'DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVDX,OFFSETMSG1MOVAH,9INT21HMOVDX,OFFSETBUFMOVAH,0AHINT21HMOVDX,OFFSETMSG2MOVAH,9INT21HXORBX,BXMOVBL,NUMBMOVCHARS[BX],'$'MOVDX,OFFSETCHARSMOVAH,9INT21HMOVAH,4CHINT21HCODEENDSENDSTART13.某软件共可接收10个键盘命令(分别为A,B,C,…,J),完成这10个命令的程序分别为过程P0,P1,…,P9。编一程序从键盘接收命令,并转到相应的过程去执行。要求用两种方法:(1)用比较、转移指令实现;(2)用跳转表实现。解(1)用比较、转移指令实现CODESEGMENTASSUMECS:CODEORG100HSTART:JMPBEGlNMSGDB'Errorcharacter!',0DH,OAH,'$'BEGlN:MOVAX,CSMOVDS,AXMOVAH,1INT