第4章--习题及参考解答.doc
精品文档,仅供学习与交流,如有侵权请联系网站删除第4章 习题及参考解答 1试编一程序,把地址偏移量为100H单元开始的256个单元分别写入00H,01H,02H,03H,FFH数据。 解源程序如下 DATASEGMENT ORG 100H BUF1 DB 256 DUP(?)COUNTEQU$BUF1 DATA ENDSSTKSEGMENT STACKDB 100 DUP(?)STKENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MOV SI,OFFSET BUF1;戓 LEA SI,BUF1 MOV CX,COUNT XOR AL,AL;或 MOV AL,00H NEXT:MOV SI,AL INC AL INC SI LOOP NEXT MOV AH,4CH INT 21 HCODE ENDS END START 2统计上题写入的数据块中0元素、正元素、负元素的个数,并分别把统计结果送入上述数据块之后的三个单元中。 解DATASEGMENT ORG 100HBUF1 DB 00H,01H02H,0FEH,0FFH;共256个数据COUNT EOU$BUF1DB 3 DUP(?)DATA ENDSSTKSEGMENT STACKDB 100 DUP(?)STKENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV S1,OFFSET BUF1 MOC CX,COUNT XOR BX,BX ;BL与BH分别存放正、负元素的个数 XOR DH,DH ;DH寄存器存放0元素个数NEXT2:MOV AL,SI CMP AL,0 JZ ZER0 ;若ZF=1,则为0,转至ZERO,DH+1 JS NEGAT ;若SF=0则为负数,BH+1INC BL ;既不是0又不是负,则为正数,BL+1JMP NEXT3ZERO:INC DH ;0的个数加1 JMP NEXT3NEGAT:INC BH ;负数个数加1NEXT3:INC SI ;修改地址指针SI LOOP NEXT2 ;未完,继续循环 MOV SI,DH ;存入0元素个数统计结果 INC SI MOV SI,BX ;存入正、负数个数统计结果 MOV AH,4CH INT 21HCODEENDS END START 4把地址偏移量为STRG1单元开始的128个单元的内容传送到地址偏移量为STRG2开始的单元中。 解 DATA SEGMENT STRGl DB XXH,XXH,XXH,XXH ;1 28个数据 COUNTEOU$STRGl STRG2 DB 128 DUP(?) DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MOV SI,OFFSET STRG1 MOV DI,OFFSET STRG2 MOV CX,COUNT CLD REP MOVSB MOV AH,4CH INT 21 H CODE ENDS END START 5寄存器SI做地址指针,自SI所指的内存单元开始连续存放三个无符号数(以字为单位),编一程序求它们的和,并将结果存放在这三个数之后的单元中。解DATASEGMENTBUF DW XXH,YYH,ZZHSUM DW ?,?DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV SI,OFFSET BUF MOV DI,OFFSET SUM MOV AX,SIADD AX,SI+2MOV DI,AXMOV AX,0ADDC AX,0MOV DI+2,AXMOV AX,DI ADDC AX,SI+4 MOV DI,AXMOV AX,0ADDC AX,DI+2MOV DI+2,AX MOV AH,4CH INT 21HCODEENDS END START6读下面程序段,问:在什么情况下本段程序的执行结果是AH0?START:IN AL,5FH MOV AH,0 JZ BRCH MOV AH,0 JMP STOPBRCH:MOV AH,0FFHSTOP:INT 20H解 当标志寄存器的ZF=0时,执行结果AH0。(JZ之前的两条指令对零标志没有影响)7下面语句在存储器中分别为变量分配多少字节?0NE DW 10TW0 DW 4 DUP(?),5THREE DB 2 DUP(?,8 DUP(0)COUNT EQU 10FOUR DD COUNT DUP(?)FIVE DBHOW ARE YOU?解ONE DW 10 ;为ONE分配2个字节 TWO DW 4 DUP(?),5 ;为TWO分配10个字节 THREE DB 2 DUP(?,8 DUP(0);为THREE分配18个字节 COUNT EQU 10 ;不给COUNT分配存储单元 FOUR DD COUNT DUP(?) ;为FOUR分配40个字节 FIVE DB HOW ARE YOU? ;为FIVE分配12个字节 8数据定义语句如下所示: FIRST DB 90H,5FH,6EH,69H SECOND DB 5 DUP(?) THIRD DB 5 DUP(?) FORTH DB DUP(?) 自FIRST单元开始存放的是一个四字节的十六进制数(低位字节在前),要求: (1)编一段程序将这个数左移两位后存放到自SECOND开始的单元(注意保留移出部分); (2)编一段程序将这个数右移两位后存放到自THIRD开始的单元(注意保留移出部分); (3)编一段程序将这个数求补后存放到自FORTH开始的单元。解DATASEGMENTFIRST DB 90H,5FH,6EH,69HSECONDDB 5 DUP (?)THIRD DB 5 DUP (?)FORTH DBDUP (?)DATA ENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX CALL SUBP1 CALL SUBP2 CALL SUBP3 MOV AH,4CH INT 21HSUBP1 PROC MOV SI,OFFSET FIRST MOV DI,OFFSET SECOND XOR BL,BL MOV CL,2 MOV AX,SIMOV DX,SI+2LOP1:SHL AX,1 RCL DX,1 RCL BL,1 DEC CL JNZ LOP1 MOV DI,AX MOV DI+2,DX MOV DI+4,BL RET SUBP1ENDP SUBP2PROC MOV SI,OFFSET FIRST MOV DI,OFFSET THIRD XOR BL,BL MOV CL,2 MOV AX,SI MOV DX,SI+2LOP2:SHR DX,1 RCR AX,1 RCR BL,1 DEC CL JNZ LOP2 MOV DI,BL MOV DI+1,AX MOV DI+3,DX RET SUBP2ENDP SUBP3PROC MOV SI,OFFSET FIRST MOV DI,OFFSET FORTH MOV AX,SI MOV DX,SI+2 NOT AXNOT DXADD AX,1 ADC DX,0 MOV DI,AX MOV DI+2,DX RETSUBP3ENDPCODE ENDS END START 9指令语句AND AX,OPD1 AND OPD2中,OPD1和OPD2是两个已赋值的变量,问两个AND操作分别在什么时间进行?有什么区别? 解前面的AND是指令,在程序运行时执行,后面的AND是运算符,在汇编的时候由汇编程序计算,表达式计算结果出现在执行程序中。二者的区别在于,前者是指令,程序运行时执行,后者是运算符,汇编时计算。 10如下指令或程序是否有错,若有错,请指出错在哪里? (1)KI EOU 1024 MOV K1,AX (2)MOV DS,100 MOV 1000,2000 (3)IMP DB ? MOV IMP,AX (4)A1 DB ? A2 DB 10 CMP A1,A2 (5)将1000送入X1单元,用如下程序: X1 DB ? MOV BX,X1 MOV BX,1000 解 (1)MOV K1,AX错。因为K1为立即数,它不能作为目的操作数。 (2)这两条指令都是错的。第一条立即数不能直接送给段寄存器;第二条两个操作数不能同时为内存操作数。 (3)MOV IMP,AX错。两操作数类型不匹配,IMP是一字节内存单元,而AX寄存器中为16位数据。 (4)CMP A1,A2错。两个操作数A1与A2不能同时为内存操作数。(5)MOV BX,1000错。两操作数类型不匹配,BX只定义了一字节单元,而1000是16位数据。 118086汇编语言程序中段的类型有几种?各段如何定义?段定义语句中,定位类型、组合类型、类别各起什么作用?各有什么含义?解8086汇编语言中,段的类型有三种,即代码段、堆栈段、数据段(附加数据段可归属于数据段)。各段可用段定义语句(SEGMENT与ENDS)和段名赋给段寄存器语句(ASSUME)来定义。段定义语句中,定位类型表示此段的起始边界要求,可允许4种段的起始边界,即PAGE、PARA、WORD或BYTE。它们分别表示段的起始值为以页、节、字、字节为边界,若此项省略,则默认值为PARA。组合类型用来告诉连接程序本段与其他段的关系,分别为NONE、PUBLIC、COMMON、AT表达式、STACK或MEMORY。每一种的含义请参看主教材。类别是连接程序(LINK)需要的。它可以是任何合法的名称,必须用单引号括起来,连接程序只使同类别的段发生关联。典型类别如CODE、'STACK'。 12使用DOS功能调用0AH从键盘输入40个字符的字符串并将其送入一输入缓冲区。在按下Enter键后,显示这些字符。解NAMEKBDINPUTCODE SEGMENT ASSUME CS:CODE,DS:CODE ORG 100HSTART:JMP BEGINBUF DB41NUMBDB ?CHARSDB 41 DUP(?)MSG1DB'Type anything,followed by enter',0DH,0AH,'$'MSG2 DB 0DH,0AH,'Contents of the KBD input buf:',0DH,0AH,'$'BEGIN:MOV AX,CS MOV DS,AX MOV DX,OFFSET MSG1 MOV AH,9 INT 21H MOV DX,OFFSET BUF MOV AH,0AH INT 21 H MOV DX,OFFSET MSG2 MOV AH,9 INT 21H XOR BX,BX MOV BL,NUMB MOV CHARSBX,'$' MOV DX,OFFSET CHARS MOV AH,9 INT 21H MOV AH,4CH INT 21HCODEENDS END START 说明 本题把数据区放在代码段中,没有单独定义数据段。并且用ORG 100H语句把程序起始地址的偏移量放在100H开始的单元,用JMP BEGIN指令跳过数据区,这样可以把该程序经汇编、连接后的执行程序(EXE)用EXE2BIN软件生成COM文件。或:DATASEGMENTBUF DB41NUMBDB ?CHARSDB 41 DUP(?)MSG1DB'Type anything,followed by enter',0DH,0AH,'$'MSG2 DB 0DH,0AH,'Contents of the KBD input buf:',0DH,0AH,'$'DATAENDSCODE SEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV DX,OFFSET MSG1 MOV AH,9 INT 21H MOV DX,OFFSET BUF MOV AH,0AH INT 21 H MOV DX,OFFSET MSG2 MOV AH,9 INT 21H XOR BX,BX MOV BL,NUMB MOV CHARSBX,'$' MOV DX,OFFSET CHARS MOV AH,9 INT 21H MOV AH,4CH INT 21HCODEENDS END START 13某软件共可接收10个键盘命令(分别为A,B,C,J),完成这10个命令的程序分别为过程P0,P1,P9。编一程序从键盘接收命令,并转到相应的过程去执行。要求用两种方法: (1)用比较、转移指令实现; (2)用跳转表实现。 解 (1)用比较、转移指令实现 CODE SEGMENT ASSUME CS:CODE ORG 100H START:JMP BEGlN MSG DB 'Error character!',0DH,OAH,'$'BEGlN:MOVAX,CSMOVDS,AXMOV AH,1 INT 21H CMP AL,'A' JZ PS0 CMP AL,'B' JZ PS1 CMP AL,'C' JZ PS2 CMP AL,'D' JZ PS3 CMP AL,'E' JZ PS4 CMP AL,'F' JZ PS5 CMP AL,'G' JZ PS6 CMP AL,'H'JZ PS7CMP AL,'I'JZ PS8CMP AL,'J'JZ PS9MOV DX,OFFSET MSGMOV AH,9INT 21 HJMP BEGINPS0:CALL P0 JMP BEGINPS1:CALL P1 JMP BEGINPS2:CALL P2 JMP BEGINPS9:CALL P9 JMP BEGIN MOV AH,4CH INT 21 HP0 PROC RETP0 ENDPP1 PROC RETP1 ENDPP9 PROC RETP9 ENDPCODE ENDS END START或:DATASEGMENTMSG DB 'Error character!',0DH,OAH,'$'DATAENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA ORG 100HSTART:MOVAX,DATAMOVDS,AXMOV AH,1 INT 21H CMP AL,'A' JZ PS0 CMP AL,'B' JZ PS1 CMP AL,'C' JZ PS2 CMP AL,'D' JZ PS3 CMP AL,'E' JZ PS4 CMP AL,'F' JZ PS5 CMP AL,'G' JZ PS6 CMP AL,'H'JZ PS7CMP AL,'I'JZ PS8CMP AL,'J'JZ PS9MOV DX,OFFSET MSGMOV AH,9INT 21 HJMP BEGINPS0:CALL P0 JMP BEGINPS1:CALL P1 JMP BEGINPS2:CALL P2 JMP BEGINPS9:CALL P9 JMP BEGIN MOV AH,4CH INT 21 HP0 PROC RETP0 ENDPP1 PROC RETP1 ENDPP9 PROC RETP9 ENDPCODE ENDS END START(2)用跳转表实现DATA SEGMENTPTAB DW 0000H ;First program entranceDW 0100HDW 0200HDW 0300HDW 0400HDW 0500HDW 0600HDW 0700HDW 0800HDW 0900H ;Nineteenth program entranceDATAENDSCODE SEGMENT ASSUME CS:CODE,DS:DATA MOV AX,DATA MOV DS,AX MOV BX,OFFSET PTAB MOV AH,1 INT 21H XOR AH,AH SUB AL,41HLOP:SHL AX,1 ADD BX,AX JMP WORD PTRBX讨论实现该题的功能用两种方法都可以,显然,用跳转表实现要简单快捷得多。所以遇到多分支程序结构时采用跳转表比用条件转移指令更方便。 14内存自BUFF单元的缓冲区连续放着512个学生的英文分数,编程序统计其中90100,6089,60分以下者各有多少人,并把结果连续存放到RESULT开始的单元中。 解 DATA SEGMENT BUFlDB 86,92,65,78,45,88,55,100,76 ;共有512个字节数据,数据范围为0100 COUNTEOU $BUF1 RESULTDW 3 DUP(?) DATA ENDS STACKSEGMENT STACK 'STACK' STAPNDB 100H DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACKSTART:MOV AX,DATA MOVDS,AX MOV SI,OFFSET BUF1 MOV DI,OFFSET RESULT MOV CX,COUNT CLD XOR BX,BX ;BX存放90100分的学生个数 XOR DX,DX ;DX存放6089分的学生个数 XOR BP,BP ;BP存放0059分的学生个数NEXT:LODSB ;取学生分数 CMP AL,90 ;是否大干等于90分 JNC NEXT1 ;大于等于90分,转到BX+1 CMP AL,60 ;是否大于等于60分 JNC NEXT2 ;大干等于60分,转到DX+1 INC BP ;小于60分,BP+1 JMP DONENEXT1:INC BX ;90100分的个数加1 JMP DONENEXT2:INC DX ;6089分的个数加1DONE:LOOP NEXT MOV DI,BX ADD DI,2 MOV DI,DX ADD DI,2 MOV DI,BP MOV AH,4CH INT 21HCODE ENDS END START15设有一数据块,共有100个字节,试找出数据块中最大者,并把它送至MAX单元中。解CODESEGMENT ASSUME CS:CODE,DS:CODE 0RG 100HSTART:JMP BEGINBUF DB 12H,56H,0ABH,0FDH,00H;共100个字节无符号数COUNTEQU $-BUFMAX DB ?BEGIN:MOV AX,CS MOV DS,AX MOV SI,OFFSET BUF MOV CX,COUNT MOV AL,SILOP1:INC SI CMP AL,SI JG LOP2 XCHG AL,SI ;用MOVAL,SI似乎要好一些,不会破坏原始数据。LOP2:LOOP LOP1 MOV MAX,AL MOV AH,4CH INT 21H CODEENDS END START或:DATASEGMENTBUF DB 12H,56H,0ABH,0FDH,00H;共100个字节无符号数COUNTEQU $-BUFMAX DB ?DATAENDSCODESEGMENT ASSUME CS:CODE,DS:DATA 0RG 100HSTART:MOV AX,DATA MOV DS,AX MOV SI,OFFSET BUF MOV CX,COUNT MOV AL,SILOP1:INC SI CMP AL,SI JG LOP2 XCHG AL,SI;用MOVAL,SI似乎要好一些,不会破坏原始数据。LOP2:LOOP LOP1 MOV MAX,AL MOV AH,4CH INT 21H CODEENDS END START 19在偏移量为First和Two的内存单元中,分别有两个双字节带符号数X和Y。试编一程序,若XY,则清除中断标志,否则就把方向标志置位。 解 DATA SEGMENT FIRST DW X TW0 DW Y DATA ENDS CODESEGMENT ASSUME CS:CODE,DS:DATASTART:MOV AX,DATA MOV DS,AX MOV SI,OFFSET FIRST MOV AX,SI ADD SI,2 MOV BX,SI CMP AX,BX JL ZCL1 STD JMP STOPZCL1:CLISTOP:MOV AH,4CH INT 21HCODEENDS END START 2l编一程序,把键入的十六进制数转换成十进制数并在屏幕上显示出来。键入的最大数为FFFFH,若键入的不是十六进制数字,则显示出错提示。 解参看例416 26编一子程序,在指定的内存区域中搜索指定的字节,如找到,则返回该字节的位置,否则返回-1。要求使用堆栈传递参数,同时提供子程序清单。要求同时提供一个测试用的主程序,以使所有程序可以运行和验证。解:DATA SEGMENTBUF DB 01H, 02H, 03H, 04H, 05H, 06H, 07H, 08H, 09H;数据块COUNT EQU $-BUF;块长度KEYB DB 05H;搜索的字节值ADDRR DW ?;存放结果单元DATA ENDSSTACK SEGMENT STACK DB 10 DUP ('STACK');堆栈区,填充STACK字符STACK ENDSCODE SEGMENT ASSUME CS:CODE, DS:DATA, SS:STACKSTART: MOV AX, DATA;主程序 MOV DS, AX LEA SI, BUF MOV CX, COUNT LEA DI,ADDRR MOV AL,KEYB PUSH SI;内存区首地址入栈 PUSH CX;数据块长度入栈 PUSH DI;结果单元地址入栈 PUSH AX;待搜索的关键字入栈 CALL FINDK;调用搜索子程序 MOV AH, 4CH INT 21HFINDK PROC;搜索子程序 MOV BP, SP;取栈顶位置到BP MOV AX, BP+2;取搜索的关键字到AX(AL) MOV DI, BP+4;取结果单元地址到DI MOV CX, BP+6;取数据块长度到CX MOV SI, BP+8;取内存区首地址到SI MOV WORD PTRDI, -1;置未搜索到标志-1LOP: CMP AL, SI JNZ NEXT MOV DI,SI;搜索到,将该字节的地址送结果单元 JMP EXITNEXT: INC SI LOOP LOPEXIT: RET 8;返回并清除栈区中传递的参数FINDK ENDPCODE ENDS END START【精品文档】第 14 页