• 301.00 KB
  • 2022-04-22 11:28:59 发布

汇编语言程序设计习题及答案.doc

  • 47页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'习题一1.1把下列2、8、16进制数转换成为十进制数(1)(1011011)2(2)(0.10110)2(3)(111111.01)2(4)(1000001.11)2(5)(377)8(6)(0.24)8(7)(3FF)16(8)(2A.4)16解:(1)(1011011)2=64+16+8+2+1=91另解:原式=(5B)16=5×16+11=91(2)(0.10110)2=0.5+0.125+0.0625=0.6875(3)(111111.01)2=32+16+8+4+2+1+0.25=63.25另解:原式=(1000000-1+0.01)2=64-1+0.25=63.25(4)(1000001.11)2=64+1+0.5+0.25=65.75(5)(377)8=3×64+7×8+7=255另解:原式=(400-1)8=4×64-1=255(6)(0.24)8=2×0.125+4×0.015625=0.3125(7)(3FF)16=3×256+15×16+15=1023另解:原式=(400-1)16=4×256-1=1023(8)(2A.4)16=2×16+10+4×0.0625=42.25另解:原式=2×16+10+4÷16=42.251.2把下列十进制数转换为2、16进制数(1)(127)10(2)(33)10(3)(0.3)10(4)(0.625)10(5)(1023.5)10(6)(377)10(7)(1/1024)10(8)(377/32)10解:(1)(127)10=64+32+16+8+4+2+1=(1111111)2=(7F)16另解:原式=(128-1)10=(10000000-1)2=(1111111)2=(7F)16(2)(33)10=32+1=(100001)2=(21)16(3)(0.3)10=(0.010011001……)2=(0.4CCC……)16(4)(0.625)10=0.5+0.125=(0.101)2=(0.A)16(5)(1023.5)10=512+256+128+64+32+16+8+4+2+1+0.5=(1111111111.1)2=(3FF.8)16(6)(377)10=256+64+32+16+8+1=(101111001)2=(179)16(7)(1/1024)10=(0.0000000001)2=(0.004)16(8)(377/32)10=(256+64+32+16+8+1)÷(32)=(101111001)2÷(100000)2=(1011.11001)2=(0B.C1)161.3把下列二进制数转换为十六进制数(1)(100011)2(2)(0.11101)2(3)(11111.11)2(4)(0.00101)2解:(1)(100011)2=(10’0011)2=23H(2)(0.11101)2=(0.1110’1000)2=0.E8H(3)(11111.11)2=(1’1111.1100)2=1F.CH(4)(0.00101)2=(0.0010’1000)2=0.28H1.4把下列十六进制数转换为二进制数 (1)(3B6)16(2)(100)16(3)(80.2)16(4)(2FF.A)16解:(1)(3B6)16=(001110110110)2(2)(100)16=(000100000000)2(3)(80.2)16=(10000000.0010)2(4)(2FF.A)16=(001011111111.1010)21.5如果用24b储存一个无符号数,这个数的范围是什么?如果储存的是一个补码表示的有符号数,那么这个数的范围又是什么?答:如果用24b储存一个无符号数,这个数的范围应为:0~224-1如果用24b储存一个补码表示的有符号数,这个数的范围应为:-223~+223-11.6两个无符号数,它们的大小等于十进制数210和303,用N位二进制存储时,相加产生了进位,用N+1位二进制存储时,相加没有产生进位。这个N等于多少?为什么?答:210+303=513,29<513<210,取N=9时,相加会产生进位,取N=10,相加就不会产生进位,因此,本题中N=9。1.7两个8位二进制无符号数相加后没有产生进位,符号标志SF=1,它们和应在什么范围内?如果SF=0,那么和又在什么范围内?答:如果SF=1,它们的和应在27~28-1,也就是128~255之内。如果SF=0,它们的和应在0~27-1,也就是0~127之内。1.8两个8位补码表示的有符号数相加时,什么情况下会使进位标志等于“1”?相减时,又是什么情况下会使借位标志等于“1”?答:两个8位补码表示的有符号数相加时,下列情况会使进位标志等于“1”:两个负数相加;两个异号数相加,和为正(不会产生溢出)。两个8位补码表示的有符号数相减时,下列情况会使借位标志等于“1”:两个同号数相减,差为负(不会产生溢出);正数减负数(有可能产生溢出);1.9用符号“〉”把下面的数按从大到小的顺序“连接”起来[X1]补=10110111[X2]原=10110111[X3]反=10110111[X4]补=10110110[X5]无符号数=10110111解:X1=-01001001B,X2=-0110111B,X3=-01001000B,X4=-01001010B,X5=+10110111B因此:X5>X2>X3>X1>X41.10用8位补码完成下列运算,用二进制“真值”的格式给出运算结果,并指出运算后CF、OF、ZF、SF、PF标志位的状态。(1)127+126(2)126-127(3)-100-120(4)-100-(-120)解:(1)127+126[127]补=01111111,[126]补=01111110,[127+126]补=11111101,[127+126]=-00000011(溢出)COZSP=01010(2)126-127[126]补=01111110,[-127]补=10000001,[126-127]补=11111111,[126-127]=-0000001 COZSP=10011(3)-100-120[-100]补=10011100,[-120]补=10001000,[-100-120]补=00100100,[-100-120]=+00100100(溢出)COZSP=01001(4)-100-(-120)[-100]补=10011100,[-120]补=10001000,[[-120]补]求补=01111000,[-100-(-120)]补=00010100,[-100-(-120)]=+00010100COZSP=000011.11把二进制代码1001011101011000分别“看作”是:(1)二进制无符号数(2)二进制补码(3)压缩BCD码(4)非压缩BCD码哪一种情况下它代表的“值”最大?答:看作二进制无符号数时,它代表的“值”最大。分析:看作二进制补码时,它代表一个负数,而其它的情况下,它均为正数。因此,看作二进制补码时,它代表的值最小。把这组代码用十六进制数字形式写出:9758对于无符号数,它的值等于十六进制的9758H;对于压缩BCD码,它的值等于十进制的9758,显然小于9758H;对于非压缩BCD码,它的值等于十进制的78,显然更小于9758H;因此,看作二进制无符号数时,它代表的“值”最大。1.12CPU使用“寄存器”有什么好处?为什么?答:CPU使用寄存器主要有两个好处:(1)寄存器位于CPU内部,访问寄存器比访问内存储器速度快;(2)寄存器数量大大少于内存储器单元个数,标识寄存器使用的二进制代码比标识内存储器单元使用的二进制代码少得多,可以缩短指令长度。1.13已知8086系统某存储单元物理地址为12345H,写出4个可以与它对应的“逻辑地址”。答:可以与物理地址12345H对应的逻辑地址有:1234H:0005H,1230H:0045H,1220H:0145H,1224H:0105H,……1.14已知8086系统某存储单元物理地址为12345H,可以与它对应的“逻辑地址”中,段基址最大值,最小值分别是多少?答:可以与物理地址12345H对应的逻辑地址中,段基址的最大值为1234H,最小值为0235H。分析:偏移地址取最大值时,对应的段基址为最小。偏移地址可选的最大值为0FFF5H(最后一位必须为5),因此最小的段基址=(12345H-0FFF5H)/10H=0235H。偏移地址取最小值时,对应的段基址最大。偏移地址可选的最小值为0005H(最后一位必须为5),因此最大的段基址=(12345H-0005H)/10H=1234H。1.158086微机最多可以有多少个不同的“段基址”?为什么?答:由于段基址由16位二进制数表示,因此可以有216=65536个不同的段基址。1.16在图1-6中,假设已有(R1)=X,(R2)=Y,分别用它的机器指令和符号指令写出计算R0← 4X+2Y的程序。想一想,怎样做才能尽量减少指令数量?答:假设已有(R1)=X,(R2)=Y,可以编制如下计算R0←4X+2Y的程序:符号指令机器指令注释MOVR0,R110000001(81H)R0←XADDR0,R110010001(91H)R0←X+XADDR0,R210010010(92H)R0←2X+YADDR0,R010010000(90H)R0←4X+2Y减少指令的方法是先计算出2X+Y,然后再计算4X+2Y。可以有多种不同的写法。1.17什么是“逻辑地址”?什么是“线性地址”?什么是“物理地址”?它们如何转换?答:由段的起始地址(段基址)或者段的编号和段内相对地址两部分表示的地址称为“逻辑地址”。经过“分段机构”处理后,用一组二进制代码表示的地址称为“线性地址”。经过“分页机构”处理后,用一组二进制代码表示的存储单元的“真实”的地址称为“物理地址”。物理地址的位数等于地址总线的宽度。工作在实地址模式下的80X86MPU不使用线性地址,物理地址=段基址×16+段内偏移地址。80X86MPU工作在保护模式下时,分段机构用段的编号在“段描述符表”中找到段的起始地址,加上偏移地址得到“线性地址”。分页机构把线性地址从高位到低位分解为“页组地址:页地址:页内地址”三部分,由页组地址(页组号)查找“页组表”,获得该页组对应的“页表”首地址。然后用页地址(页号)去查“页表”,得到该页的起始地址,拼接上页内地址,得到“物理地址”。保护模式下也可以关闭分页机构,此时线性地址等于物理地址。1.1832位80X86和16位80X86中央处理器的段寄存器有什么不同?答:16位80X86CPU的段寄存器长度为16位,存放的是一个段起始地址的高16位。32位80X86CPU的段寄存器长度仍然为16位,存放的是一个段在“段描述符表”中的序号,表的编号(对每一个程序,有两张段描述符表)和这个段的优先级别。1.19叙述“保护模式”和“虚拟8086方式”之间的关系。答:保护模式是32位80X86MPU的工作方式,对当前运行的所有任务实施保护。虚拟8086方式是保护模式下某一个任务的工作模式,该任务使用类似于实地址方式下的物理地址产生方式,使用1MB的虚拟内存空间,主要用于运行8086程序。 习题二2.1某数据段内有如下数据定义:Xdb30,30H,‘ABC’,2-3,?,11001010Bdw0FFH,-2,“CD”Ydd20dup(15,3dup(?),0)Zdb3dup(?)WdwZ-X假设变量X的偏移地址为20H。(1)按照图2-1的格式写出变量X各数据在内存中的具体位置和相关内存单元的值。(2)写出变量Y,Z的偏移地址。(3)写出变量W的值答:(1)变量X各数据在内存中的具体位置和相关内存单元的值如右图。(2)变量Y的偏移地址为002EH;变量Z的偏移地址为002EH+4×5×20=01BEH(3)变量W的值等于变量Z和X偏移地址之差01BEH-0020H=019EH它等于变量X、Y所占用内存单元的字节数。2.280x86指令系统有哪几种类型的指令操作数?比较使用不同类型操作数后的指令长度和指令执行时间。答:80X86指令系统按照长度划分,有以下四种指令操作数:(1)寄存器操作数,指令短,执行速度快;(2)立即操作数,指令较长,执行速度快;(3)寄存器间接寻址和基址变址寻址表示的内存储器操作数,这类指令长度较短,执行速度较慢(需要访问存储器);(4)直接地址,寄存器相对寻址,相对的基址变址寻址表示的内存储器操作数,这类指令长度较长,执行速度较慢(需要计算物理地址,访问存储器)。2.3下列指令的源操作数段基址在哪个段寄存器中?(1)MOVAX,[BP][SI](2)MOVAX,CS:8[DI](3)MOVAX,2[EBP*1](4)MOVAX,FS:4[ESP](5)MOVAX,2[EBP][EAX](6)MOVAX,[ECX][EBP*4](7)MOCAX,[EDX][EBP](8)MOVAX,ES:10[EBP][EAX*2]答:各指令源操作数段基址使用的段寄存器如下:(1)SS(2)CS(3)SS(4)FS(5)SS(6)DS(7)DS(8)ES2.4判断下列指令是否正确。若不正确,指出错误原因(1)MOVAX,[EBX](2)MOVSI,DL(3)MOVEBP,[ESP][EAX*3](4)LEAAX,3006H(5)MOV[BP][DI],0(6)MOV[SI],[DI](7)MOVES,1000H(8)MOVAX,X+2(9)MOVAX,CX+2(10)MOV[EAX][EAX*2],AL 答:(1)指令MOVAX,[EBX]是正确的。(2)指令MOVSI,DL是错误的,两个操作数类型不匹配。(3)指令MOVEBP,[ESP][EAX*3]是错误的,比例因子不能为3。(4)指令LEAAX,3006H是错误的,LEA指令的源操作数必须为内存操作数。(5)指令MOV[BP][DI],0是错误的,操作数类型无法确定。(6)指令MOV[SI],[DI]是错误的,不能同时出现两个内存操作数。(7)指令MOVES,1000H是错误的,装载段寄存器时,源操作数不能为立即数。(8)如果“X”是用常数表达式定义的符号(例如:XEQU5+6),或者是用“DW”定义的内存变量,指令MOVAX,X+2是正确的。否则这条指令是错误的。(9)指令MOVAX,CX+2是错误的,源操作数表达式CX+2不是一个可以直接计算的“常数表达式”。(10)指令MOV[EAX][EAX*2],AL是正确的。2.5现有(DS)=2000H,(BX)=0100H,(SI)=0002H,(20100H)=12H,(20101H)=34H,(20102H)=56H,(20103H)=78H,(21200H)=2AH,(21201H)=4CH,(21202H)=0B7H,(21203H)=65H,说明下列指令执行后AX寄存器的内容。(1)MOVAX,1200H(2)MOVAX,BX(3)MOVAX,[1200H](4)MOVAX,[BX](5)MOVAX,1100H[BX](6)MOVAX,[BX][SI](7)MOVAX,1100H[BX][SI]答:(1)指令MOVAX,1200H执行后,(AX)=1200H(立即数操作数)。(2)指令MOVAX,BX执行后,(AX)=0100H(寄存器操作数)。(3)指令MOVAX,[1200H]执行后,(AX)=4C2AH(直接地址,EA=1200H)(4)指令MOVAX,[BX]执行后,(AX)=3412H(寄存器间接寻址,EA=0100H)(5)指令MOVAX,1100H[BX]执行后,(AX)=4C2AH(相对地址,EA=1200H)(6)指令MOVAX,[BX][SI]执行后,(AX)=7856H(基址变址寻址,EA=0102H)(7)指令MOVAX,1100H[BX][SI]执行后,(AX)=65B7H(相对基址变址寻址,EA=1202H)2.6已经定义字符串MYSTRING如下:MYSTRINGDB‘ASampleforaddressing.’用适当的指令把这个字符串的第5,12个字符(注:第0个字符是’A’)送入BX寄存器。答:可以用如下两条指令完成:MOVBL,MYSTRING[5]MOVBH,MYSTRING[12]2.7下面两条指令的功能有什么区别?MOVAX,BXMOVAX,[BX]答:指令“MOVAX,BX”把BX寄存器的内容装入到AX中。指令“MOVAX,[BX]”把内存储器一个字的内容装入AX寄存器。该字的段基址在DS中,偏移地址在BX中。2.8已经定义数据段如下: DATASEGMENTNUM=56XDBNUMYDB27ZDW148DATAENDS指出下列指令中的错误:(1)MOVY,X(2)MOVBL,04B8H(3)MOVAL,Z(4)MOV[BX],3(5)MOV[BX],[DI](6)MOVDS,DATA(7)MOVNUM,AX(8)MOVES,DS(9)MOVAX,FLAGS(10)MOVCS,AX答:(1)指令MOVY,X同时出现了两个存储器操作数。(2)指令MOVBL,04B8H操作数类型不匹配(04B8H是16位立即数,BL是8位寄存器)。(3)指令MOVAL,Z操作数类型不匹配(Z是16位操作数,BL是8位寄存器)。(4)指令MOV[BX],3操作数类型不能确定。(5)指令MOV[BX],[DI]出现了两个存储器操作数。(6)指令MOVDS,DATA不能把立即数装入段寄存器。(7)指令MOVNUM,AX立即数不能用作目的操作数。(8)指令MOVES,DS不能在段寄存器之间直接传输。(9)指令MOVAX,FLAGS中,FLAGS寄存器只能隐含在少量指令中使用。(10)指令MOVCS,AX中,CS寄存器不能用作目的操作数。2.9用适当的指令,把下面字符串STRING中的“&”字符用空格代替。STRINGDB“TheDateisFEB&03”答:可以使用如下指令:MOVSTRING[15],20H;20H是空格的ASCII代码 习题三3.1根据以下要求,写出对应的汇编语言指令(1)把BX和DX寄存器内容相加,结果存入DX寄存器。(2)使用BX和SI寄存器进行基址变址寻址,把存储器中一字节内容与AL内容相加,结果存入存储单元。(3)用寄存器BX和位移量0B2H的寄存器相对寻址方式,把存储器中一个双字与ECX相加,结果存入ECX。(4)用偏移地址1020H直接寻址,把存储单元一个字内容与立即数3相加,结果存入存储单元。(5)将AL寄存器内容与立即数120相加,结果存入AL寄存器。答:(1)ADDDX,BX(2)ADD[BX][SI],AL(3)ADDECX,[BX+0B2H](4)ADDWORDPTR[1020H],3(5)ADDAL,1203.2求以下各十六进制数与62A8H之和,并根据结果写出标志位SF、CF、ZF、OF的值。(1)1234H(2)4321H(3)0CFA0H(4)9D60H(5)0FFFFH答:(1)1234H+62A8H=74DCHSCZO=0000(2)4321H+62A8H=0A5C9HSCZO=1001(3)0CFA0H+62A8H=3248HSCZO=0100(4)9D60H+62A8H=0008HSCZO=0100(5)0FFFFH+62A8H=62A7HSCZO=01003.3求以下各十六进制数与4AE0H之差,并根据结果写出标志位SF、CF、ZF、OF的值。(1)1234H(2)5D90H(3)9076H(4)0EA04H(5)0FFFFH答:(1)1234H-4AE0H=0C754HSCZO=1100(2)90H-4AE0H=12B0HSCZO=0000(3)9076H-4AE0H=4597HSCZO=0001(4)0EA04H-4AE0H=9F24HSCZO=1000(5)0FFFFH-4AE0H=0B51FHSCZO=10003.4写出执行以下计算的指令序列,其中各变量均为16位有符号数。(1)Z←W+(Z-X)(2)Z←W-(X+6)-(R+9)(3)Z←(W*X)/(Y+6),R←余数(4)Z←(W-X)/(5*Y)*2解:(1)MOVAX,WMOVBX,ZSUBBX,XADDAX,BXMOVZ,AX(2)MOVAX,WMOVBX,X ADDBX,6SUBAX,BXMOVBX,RADDBX,9SUBAX,BXMOVZ,AX(3)MOVAX,WIMULXMOVBX,YADDBX,9IDIVBXMOVZ,AXMOVR,DX(4)MOVAX,YMOVBX,5IMULBXMOVBX,AXMOVAX,WSUBAX,XMOVCX,2IMULCXIDIVBXMOVZ,AX3.5一个双字长有符号数存放在DX(高位)AX(低位)中,写出求该数相反数的指令序列。结果仍存入DX,AX寄存器解:NOTDX;首先将(DX,AX)取反NOTAXADDAX,1;最低位加1,注意:不能用INC指令ADCDX,0;把进位(如果有)传递到高位3.6指令DECBX和SUBBX,1的执行结果一样吗?请分析。解:指令DECBX和SUBBX,1分别执行后,BX寄存器内的值相同,但是CF标志位的状态可能不同,这是由于DEC指令执行后不改变CF的状态。3.7已知内存变量X,Y,Z均由“DB”伪操作定义,按照以下要求,使用MOVZX或MOVSX指令进行位数扩展,求三个数的16b和。(1)如果X,Y,Z为无符号数(2)如果X,Y,Z为有符号数解:(1)MOVZXAX,XMOVZXBX,YADDAX,BXMOVZXBX,ZADDAX,BX (2)MOVSXAX,XMOVSXBX,YADDAX,BXMOVSXBX,ZADDAX,BX3.8内存缓冲区BUFFER定义如下,按照要求,写出指令序列BUFFERDB20DUP(?)(1)将缓冲区全部置为0,并使执行时间最短(2)将缓冲区全部置为空格字符(ASCII代码20H),使用的指令条数最少(3)将缓冲区各字节依次设置为0,1,2,3,4,……,19(4)将缓冲区各字节依次设置为0,-1,-2,-3,-4,……,-19(5)将缓冲区各字节依次设置为30,29,28,27,……,11(6)将缓冲区各字节依次设置为0,2,4,6,8,……,38(7)将缓冲区各字节依次设置为0,1,2,3,0,1,2,3,……,3解:(1)XOREAX,EAXMOVDWORDPTR[BUFFER],EAXMOVDWORDPTR[BUFFER+4],EAXMOVDWORDPTR[BUFFER+8],EAXMOVDWORDPTR[BUFFER+12],EAXMOVDWORDPTR[BUFFER+16],EAX(2)MOVAL,20HMOVCX,20LEABX,BUFFERONE:MOV[BX],ALINCBXLOOPONE(3)XORBX,BXMOVCX,20ONE:MOVBUFFER[BX],BLINCBXLOOPONE(4)XORBX,BXXORAL,ALMOVCX,20ONE:MOVBUFFER[BX],ALINCBXDECALLOOPONE(5)XORBX,BXMOVAL,30MOVCX,20ONE:MOVBUFFER[BX],AL INCBXDECALLOOPONE(6)XORBX,BXXORAL,ALMOVCX,20ONE:MOVBUFFER[BX],ALINCBXADDAL,2LOOPONE(7)XORBX,BXMOVCX,5ONE:MOVBUFFER[BX],0MOVBUFFER[BX+1],1MOVBUFFER[BX+2],2MOVBUFFER[BX+3],3ADDBX,4LOOPONE3.9编写循环结构程序,进行下列计算,结果存入RESULT内存单元(1)1+2+3+4+5+6+……+100(2)1+3+5+7+9+11+……+99(3)2+4+6+8+10+……+100(4)1+4+7+10+13+……+100(5)11+22+33+44+……+99解:(1)CODESEGMENTASSUMECS:CODERESULTDW?START:XORAX,AXMOVCX,100AGAIN:ADDAX,CXLOOPAGAINMOVRESULT,AXMOVAX,4C00HINT21HCODEENDSENDSTART(2)CODESEGMENTASSUMECS:CODERESULTDW?START: XORAX,AXMOVCX,50MOVBX,1AGAIN:ADDAX,BXADDBX,2LOOPAGAINMOVRESULT,AXMOVAX,4C00HINT21HCODEENDSENDSTART(3)CODESEGMENTASSUMECS:CODERESULTDW?START:XORAX,AXMOVCX,50MOVBX,2AGAIN:ADDAX,BXADDBX,2LOOPAGAINMOVRESULT,AXMOVAX,4C00HINT21HCODEENDSENDSTART(4)CODESEGMENTASSUMECS:CODERESULTDW?START:XORAX,AXMOVCX,34MOVBX,1AGAIN:ADDAX,BXADDBX,3LOOPAGAINMOVRESULT,AXMOVAX,4C00HINT21HCODEENDSENDSTART (5)CODESEGMENTASSUMECS:CODERESULTDW?START:XORAX,AXMOVCX,9MOVBX,11AGAIN:ADDAX,BXADDBX,11LOOPAGAINMOVRESULT,AXMOVAX,4C00HINT21HCODEENDSENDSTART3.10已知ARRAY是5行5列的有符号字数组,编写程序,进行下列计算(假设和仍然为16b,不会产生溢出)(1)求该数组第4列所有元素之和(列号从0开始)(2)求该数组第3行所有元素之和(行号从0开始)(3)求该数组正对角线上所有元素之和(4)求该数组反对角线上所有元素之和解:假设数据段已定义如下:DATASEGMENTARRAYDW1,6,9,23,12;定义数组ARRAYDW54,23,15,-92,37;每一行5个数据DW-99,231,76,81,90;共5行DW33,67,81,-99,0;共计25个数据DW123,-52,77,-180,89SUMDW?;SUM存放结果DATAENDS(1)CODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVAX,0;累加器在循环之前清零MOVCX,5;计数器置初值MOVSI,4*2;第1行第4列元素在数组内的位移NEXT:ADDAX,ARRAY[SI]ADDSI,5*2;SI指向下一行第4列元素LOOPNEXTMOVSUM,AXMOVAX,4C00H INT21HCODEENDSENDSTART(2)CODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVAX,0;累加器在循环之前清零MOVCX,5;计数器置初值MOVSI,3*5*2;第3行第0列元素在数组内的位移NEXT:ADDAX,ARRAY[SI]ADDSI,2;SI指向本行下一列元素LOOPNEXTMOVSUM,AXMOVAX,4C00HINT21HCODEENDSENDSTART(3)CODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVAX,0;累加器在循环之前清零MOVCX,5;计数器置初值MOVSI,0;第0行第0列元素在数组内的位移NEXT:ADDAX,ARRAY[SI]ADDSI,5*2+2;SI指向正对角线上下一个元素LOOPNEXTMOVSUM,AXMOVAX,4C00HINT21HCODEENDSENDSTART(4)CODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVAX,0;累加器在循环之前清零MOVCX,5;计数器置初值MOVSI,4*2;第0行第4列元素在数组内的位移NEXT:ADDAX,ARRAY[SI] ADDSI,(5-1)*2;SI指向反对角线上下一个元素LOOPNEXTMOVSUM,AXMOVAX,4C00HINT21HCODEENDSENDSTART3.11编写程序,利用公式:N2=1+3+5+……+(2N-1)计算N2的值,假设N=23。解:DATASEGMENTNDW23SQUAREDW?;存放结果DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVCX,N;循环计数器置初值XORAX,AX;累加器清零MOVBX,1;数列第一项ONE:ADDAX,BXADDBX,2LOOPONEMOVSQUARE,AXMOVAX,4C00HINT21HCODEENDSENDSTART3.12变量X,Y,Z均为一字节压缩BCD码表示的十进制数,写出指令序列,求它们的和(用2字节压缩BCD码表示)。解:XORAX,AX;清AX,用于存放2字节结果MOVAL,XADDAL,Y;完成X+YDAA;压缩BCD码加法调整ADCAH,0;把可能的进位收集到AH中;AH中最大的可能值为2,因此不需要BCD加法调整ADDAL,Z;完成X+Y+ZDAA;压缩BCD码加法调整ADCAH,0;把可能的进位收集到AH中;计算完成,结果(2字节压缩BCD码)在AX中3.13数组LIST1内存有20个非压缩BCD码表示的单字节十进制数,写出完整程序,求这20个BCD数之和,结果(非压缩BCD码)存入SUM1双字单元。解:CODESEGMENT ASSUMECS:CODELIST1DB‘6705762998’;20个非压缩BCD数DB‘4322687310’SUM1DD?;存放结果(20个数之和)START:XORAX,AX;累加器清零MOVCX,20;循环计数器置初值LEABX,LIST1;地址指针置初值ONE:ADDAL,CS:[BX];加入一个非压缩BCD数AAA;调整,结果在AH(百位、十位),AL(个位)中INCBX;修改指针LOOPONE;循环控制MOVBYTEPTRSUM1,AL;保存个位MOVAL,AHMOVAH,0;百位、十位(二进制)存入AXAAM;分解百位到AH,十位到ALMOVWORDPTRSUM1+1,AX;保存百位、十位MOVBYTEPTRSUM1+3,0;千位清零(和最大为9*20=180)MOVAX,4C00HINT21HCODEENDSENDSTART3.14数组LIST2内存有20个压缩BCD码表示的单字节十进制数,写出完整程序,求这20个BCD数之和,结果(压缩BCD码)存入SUM2双字单元。解:CODESEGMENTASSUMECS:CODELIST2DB12H,34H,56H,15H,82H,52H,48H,19H,31H,63HDB22H,33H,44H,55H,66H,77H,88H,99H,11H,39HSUM2DD?START:XORAX,AX;累加器清零XORBX,BX;地址指针置初值MOVCX,20;循环计数器置初值ONE:ADDAL,LIST2[BX];加入一个压缩BCD数DAA;调整XCHGAH,AL;交换AH和ALADCAL,0;收集进位(百位、千位)DAA;高位(百位、千位)调整XCHGAH,AL;恢复AH和AL;(AH)=千位、百位,(AL)=十位、个位INCBX;修改指针LOOPONE;循环控制MOVWORDPTRSUM2,AX;保存千、百、十、个位MOVWORDPTRSUM2+2,0;高位清零MOVAX,4C00H INT21HCODEENDSENDSTART3.15数组LIST3内存有20个压缩BCD码表示的双字节十进制数,写出完整程序,求这20个BCD数之和,结果(压缩BCD码)存入SUM3双字单元。解:CODESEGMENTASSUMECS:CODELIST3DW1234H,3456H,5678H,1523H,8263H,DW5234H,4856H,1926H,3177H,6389HDW2211H,3322H,4433H,5544H,6655HDW7766H,8877H,9988H,1167H,3944HSUM3DD?START:XORDX,DXXORAX,AX;累加器清零LEABX,LIST3;地址指针置初值MOVCX,20;循环计数器置初值ONE:ADDAL,CS:[BX];加入第一字节压缩BCD数(十位、个位)DAA;调整XCHGAH,AL;交换AH和ALINCBX;修改指针,指向高位字节(千位、百位)ADCAL,CS:[BX];高位累加,并收集低位进位DAA;高位(百位、千位)调整XCHGAH,AL;恢复AH和AL;(AH)=千位、百位,(AL)=十位、个位INCBX;修改指针XCHGDX,AX;交换AX和DXADCAL,0;收集千位上的进位DAA;调整,得到和的十万位和万位XCHGDX,AX;恢复DX和AXLOOPONE;循环控制MOVWORDPTRSUM3,AX;保存千、百、十、个位MOVWORDPTRSUM3+2,DX;保存十万位和万位MOVAX,4C00HINT21HCODEENDSENDSTART3.16设(BX)=0E3H,变量VALUE中存放内容为79H,指出下列指令单独执行后的结果。(1)XORBX,VALUE(2)ANDBX,VALUE(3)ORBX,VALUE(4)XORBX,0FFH(5)ANDBX,BX (6)ANDBX,0答:(1)指令“XORBX,VALUE”执行后,(BX)=009AH(2)指令“ANDBX,VALUE”执行后,(BX)=0061H(3)指令“ORBX,VALUE”执行后,(BX)=00FBH(4)指令“XORBX,0FFH”执行后,(BX)=001CH(5)指令“ANDBX,BX”执行后,(BX)=00E3H(6)指令“ANDBX,0”执行后,(BX)=0000H3.17某密码的加密规则为:‘0’→‘A’,‘1’→‘B’,‘2’→‘C’,……。按照以下要求编写程序。(1)把明文“96541833209881”翻译为密文。(2)把密文“JJBDAHCFFGA”翻译成明文。答:(1)明文“96541833209881”翻译为密文。CODESEGMENTASSUMECS:CODETEXT1DB‘96541833209881’TEXT2DB14DUP(?)START:MOVBX,0MOVCX,14NEXT:MOVAL,TEXT1[BX];取出一字节明文ADDAL,‘A’-‘0’;转换成密文MOVTEXT2[BX],AL;保存INCBXLOOPNEXTMOVAX,4C00HINT21HCODEENDSENDSTART(2)密文“JJBDAHCFFGA”翻译成明文。CODESEGMENTASSUMECS:CODETEXT1DB‘JJBDAHCFFGA’TEXT2DB11DUP(?)START:MOVBX,0MOVCX,11NEXT:MOVAL,TEXT1[BX];取出一字节密文SUBAL,‘A’-‘0’;转换成明文MOVTEXT2[BX],AL;保存 INCBXLOOPNEXTMOVAX,4C00HINT21HCODEENDSENDSTART3.18编写程序,从键盘上输入一行明文,按照题3.17的规则翻译成密文,向显示器输出。答:DATASEGMENTMESSDB0DH,0AH,“Inputsometextplease:$”OUTMESSDB0DH,0AH,‘Thetextafterconvert:’BUFFERDB81,?,81DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEADX,MESSMOVAH,09HINT21H;输出提示信息LEADX,BUFFERMOVAH,0AHINT21H;输入一行明文MOVCL,BUFFER+1MOVCH,0;输入字符个数送CXLEABX,BUFFER+2;首字符地址送BXNEXT:MOVAL,[BX]ADDAL,‘A’-‘0’;将一字节明文转换成密文MOV[BX],AL;保存INCBXLOOPNEXTMOVBYTEPTR[BX],‘$’;送字符串结束标记MOVWORDPTRBUFFER,2020H;缓冲区前2字节改为空格LEADX,OUTMESSMOVAH,09HINT21H;输出转换以后的结果MOVAX,4C00HINT21HCODEENDSENDSTART3.19变量X用DT定义,存有80b有符号数,编写程序,求X的相反数,存入同样用DT定义的变量Y。答:CODESEGMENT ASSUMECS:CODEXDT1234567890HYDT?START:MOVCX,10;循环计数器置初值XORBX,BX;地址指针置初值ONE:MOVAL,BYTEPTRX[BX]NOTAL;X的一字节内容取反MOVBYTEPTRY[BX];存入Y的一个字节内INCBXLOOPONEADDBYTEPTRY,1;Y的低位字节加1LEABX,Y+1;从Y的第2字节开始处理MOVCX,9;共9个字节TWO:ADCBYTEPTRCS:[BX],0;收集低位来的进位INCBX;修改指针LOOPTWO;循环控制MOVAX,4C00HINT21HCODEENDSENDSTART3.20编写程序,使用库子程序,从键盘上输入8个有符号字数据,求它们的和,以十进制格式输出。答:INCLUDEYLIB.HDATASEGEMNTMESS1DB0DH,0AH,‘Inputanumberplease:$’MESS2DB0DH,0AH,‘Thesumis:$’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXXORBX,BX;BX用作累加器,清零MOVCX,8;循环计数器置初值AGAIN:LEADX,MESS1CALLREADINT;输入一个数据(在AX中)ADDBX,AX;累加LOOPAGAIN LEADX,MESS2MOVAX,BXCALLWRITEINT;输出8个数的和CALLCRLFMOVAX,4C00HINT21HCODEENDSENDSTART3.21编写程序,从键盘上输入20个十进制数字,求这些数字的和,向显示器输出。答:INCLUDEYLIB.HDATASEGEMNTMESS1DB0DH,0AH,‘Input20decimaldigitsplease:$’MESS2DB0DH,0AH,‘Theirsumis:$’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEADX,MESS1MOVAH,09HINT21H;输出提示信息XORBX,BX;BX用作累加器,清零MOVCX,20;循环计数器置初值AGAIN:MOVAH,01HINT21H;输入一个数字(在AL中)ANDAL,0FH;转换成二进制数ADDBL,AL;累加ADCBH,0LOOPAGAINLEADX,MESS2MOVAX,BXCALLWRITEDEC;输出20个数字的和CALLCRLFMOVAX,4C00HINT21HCODEENDSENDSTART3.22阅读以下程序,指出它的功能。MOVCL,04 SHLDX,CLMOVBL,AHSHLAX,CLSHRBL,CLORDL,BL答:把32位二进制代码(DX,AX)联合左移4位。3.23已知(DX)=0B9H,(CL)=3,(CF)=1,确定下列指令单独执行以后DX寄存器的值。(1)SHRDX,1(2)SARDX,CL(3)SHLDX,CL(4)SHLDL,1(5)RORDX,CL(6)ROLDX,CL(7)SALDH,1(8)RCLDX,CL(9)RCRDL,1答:(1)指令“SHRDX,1”执行之后,(DX)=005CH(2)指令“SARDX,CL”执行之后,(DX)=0017H(3)指令“SHLDX,CL”执行之后,(DX)=05C8H(4)指令“SHLDL,1”执行之后,(DX)=0172H(5)指令“RORDX,CL”执行之后,(DX)=2017H(6)指令“ROLDX,CL”执行之后,(DX)=05C8H(7)指令“SALDH,1”执行之后,(DX)=00B9H(8)指令“RCLDX,CL”执行之后,(DX)=05CCH(9)指令“RCRDL,1”执行之后,(DX)=00DCH3.24下面程序段执行完成后,BX寄存器的内容是什么?MOVCL,3MOVBX,0B7HROLBX,1RORBX,CL答:上面程序段执行完成后,(BX)=0C02DH3.25写程序,从键盘上输入一个0~65535之间的十进制无符号数,然后用二进制格式输出这个值。例如,键盘输入“35”,显示器输出“0000000000100011”。答:INCLUDEYLIB.HDATASEGEMNTMESS1DB0DH,0AH,‘Inputaunsigneddecimalintegernumberplease:$’MESS2DB0DH,0AH,‘Thenumberinbinaryis:$’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATA START:MOVAX,DATAMOVDS,AXLEADX,MESS1CALLREADDEC;输入一个无符号整数MOVBX,AX;转存入BXLEADX,MESS2MOVAH,09HINT21H;输出提示信息MOVCX,16;循环计数器置初值AGAIN:SHLBX,1;向左外移一位,进入CFMOVDL,30HADCDL,0;形成一位二进制数字的ASCII代码MOVAH,2INT21H;输出一个二进制数字LOOPAGAIN;循环16次CALLCRLFMOVAX,4C00HINT21HCODEENDSENDSTART3.26无符号数变量X用DD定义,编写程序,用十六进制格式输出变量X的值。答:.386DATASEGEMNTUSE16XDD36895471;一个32B长整数MESSDB0DH,0AH,‘TheXinhexdecimalis:$’HEXTABDB‘0123456789ABCDEF’DATAENDSCODESEGMENTUSE16ASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEADX,MESSMOVAH,09HINT21H;输出前导信息MOVESI,X;将X存入ESIMOVCX,8;循环计数器置初值LEABX,HEXTAB;换码表首地址装入BXAGAIN:ROLESI,4;把最高4位移到最低4位上MOVAX,SI;低8位转入ALANDAX,0004H;清除高4位XLAT;转换成十六进制数字的ASCII代码 MOVDL,ALMOVAH,2INT21H;输出一个十六进制数字LOOPAGAIN;循环16次MOVAX,4C00HINT21HCODEENDSENDSTART3.27从键盘上输入两个有符号字整数A和B,计算并输出它们的和、差、积、商和余数。答:INCLUDEYLIB.HDATASEGEMNTMESS1DB0DH,0AH,‘Inputaintegernumberplease:$’MESS2DB0DH,0AH,‘Thesumof2numberis:$’MESS3DB0DH,0AH,‘Thedifferenceof2numberis:$’MESS4DB0DH,0AH,‘Theproductof2numberis:$’MESS5DB0DH,0AH,‘Thequotientof2numberis:$’MESS6DB0DH,0AH,‘Theremainderof2numberis:$’ADW?BDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEADX,MESS1CALLREADINT;输入第一个有符号整数MOVA,AXLEADX,MESS1CALLREADINT;输入第二个有符号整数MOVB,AXADDAX,A;求两个数的和LEADX,MESS2CALLWRITEINT;输出两个数的和MOVAX,ASUBAX,B;求两个数的差LEADX,MESS3CALLWRITEINT;输出两个数的差MOVAX,AIMULB;求两个数的积,假设仍然是16位LEADX,MESS4CALLWRITEINT;输出两个数的积MOVAX,A CWDIDIVB;求两个数的商和余数PUSHDXLEADX,MESS5CALLWRITEINT;输出两个数的商POPAXLEADX,MESS6CALLWRITEINT;输出两个数的余数CALLCRLFMOVAX,4C00HINT21HCODEENDSENDSTART3.28数组ARRAY中存有10个无符号字整数(元素序号0~9),现在要删除其中的第5个元素。编写程序,把第6~9个元素移到第5~8个元素的位置上,并把第9个元素清零。答:DATASEGEMNTARRAYDW-386,97,213,21,77,-91,56,7,123,65DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVBX,6*2;第六个元素在数组内的位移MOVCX,4;循环计数器置初值AGAIN:MOVAX,ARRAY[BX];取出一个元素MOVARRAY[BX-2],AX;向前移动一个位置ADDBX,2;修改指针LOOPAGAIN;循环4次MOVARRAY[BX],0;最后一个元素清零MOVAX,4C00HINT21HCODEENDSENDSTART3.29编写指令序列,把AX中的16b二进制分为4组,每组4b,分别置入AL,BL,CL,DL中。答:MOVDX,AX;最低4位直接进入DXMOVCX,4ROLAX,CL;最高4位移入最低4位PUSHAX;压入堆栈保存(准备送入AL)ROLAX,CL;次高4位移入最低4位MOVBX,AX;送入BLROLAX,CL;第3组4位移入最低4位 MOVCX,AX;送入CLPOPAX;从堆栈中弹出原最高4位ANDAX,000FH;清除高12位ANDBX,000FH;清除高12位ANDCX,000FH;清除高12位ANDDX,000FH;清除高12位 习题四4.1什么是“三种基本结构”?解释“基本”两个字在其中的含义。答:三种基本结构指:顺序结构,选择结构、循环结构。使用这3种结构,可以编制出任何所需要的程序,因此冠以“基本”结构。4.2什么叫做“控制转移指令”?它和数据传送、运算指令有什么区别?它是怎样实现它的功能的?答:控制转移指令是可以改变指令执行顺序的指令。数据传送、运算指令总是顺序执行的,而控制转移指令通过改变IP和/或CS寄存器的值,改变了程序指令的执行顺序。4.3指令“JMPDI”和“JMPWORDPTR[DI]”作用有什么不同?请说明。答:上述两条指令都是段内近转移指令,但是偏移地址的来源不同。指令“JMPDI”执行时,新的偏移地址在DI寄存器内,“JMPWORDPTR[DI]”时,目的偏移地址在存储单元中,该存储单元的地址在DS:DI中。4.4什么是“近程”转移?什么是“远程”转移?它们的实现方法有什么不同?答:执行“近程”转移时,转移的目的地与出发地在同一个段内,它们具有相同的段基址。因此,为了实现“近程”转移,只需要改变IP寄存器的值。“远程”转移的目的地与出发地不在同一个段,为了实现这个转移,必须同时改变CS和IP寄存器的值。4.5已知(AX)=836BH,X分别取下列值,执行“CMPAX,X”后,标志位ZF、CF、OF、SF各是什么?(1)X=3000H(2)X=8000H(3)X=7FFFFH(4)X=0FFFFH(5)X=0答:上述指令执行后,标志位ZF、CF、OF、SF的状态分别是:(1)ZCOS=0010(2)ZCOS=0000(3)ZCOS=0010(4)ZCOS=0101(5)ZCOS=00014.6已知(AX)=836BH,X分别取下列值,执行“TESTAX,X”后,标志位ZF、CF、OF、SF各是什么?(1)X=0001H(2)X=8000H(3)X=0007H(4)X=0FFFFH(5)X=0答:上述指令执行后,标志位ZF、CF、OF、SF的状态分别是:(1)ZCOS=0000(2)ZCOS=0001(3)ZCOS=0000(4)ZCOS=0001(5)ZCOS=10004.7测试名为X的一个字节,如果X的第1,3位均为1,转移到L1,如果只有一位为1,转移到L2,如果两位全为0,转移到L3。写出对应的指令序列。答:MOVAL,XANDAL,00001010BJZL3CMPAL,00001010BJEL1JMPL24.8假设X和X+2字单元存放有双精度数P,Y和Y+2字单元存放有双精度数Q,下面程序完成了什么工作?MOVDX,X+2MOVAX,X;双精度数P送入DX,AXADDAX,X ADCDX,X+2;计算2*P送入DX,AXCMPDX,Y+2;2P与Q的高位比较JLL2;2PQ,转L1(Z=1)CMPAX,Y;如果高位相等,则比较低位JBEL2;2P的低位小于等于Q的低位,转L2(Z=2)L1:MOVZ,1JMPSHORTEXITL2:MOVZ,2EXIT:……答:程序根据2P与Q的大小,确定Z的值。如果2P≤Q,则Z=2如果2P>Q,则Z=1请参阅程序注解4.9编写指令序列,将AX和BX中较大的绝对值存入AX,较小的绝对值存入BX。答:ANDAX,AXJGESKIP1NEGAXSKIP1:ANDBX,BXJGESKIP2NEGBXSKIP2:CMPAX,BXJGESKIP3XCHGAX,BXSKIP3:……4.10编写指令序列,比较AX、BX中的数的绝对值,绝对值较大的数存入AX,绝对值较小的数存入BX。答:PUSHAXPUSHBXANDAX,AXJGESKIP1NEGAXSKIP1:ANDBX,BXJGESKIP2NEGBXSKIP2:CMPAX,BXPOPBXPOPAXJGESKIP3XCHGAX,BXSKIP3:…… 4.11编写指令序列,如果AL寄存器存放的是小写字母,把它转换成大写字母,否则不改变AL内容。答:CMPAL,‘a’JBDONECMPAL,‘z’JADONESUBAL,‘a’-‘A’DONE:……4.12计算分段函数:X的值从键盘输入,Y的值送显示器输出。答:INCLUDEYLIB.HDATASEGEMNTMESS1DB0DH,0AH,‘InputvalueofXplease:$’MESS2DB0DH,0AH,‘Y=:$’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEADX,MESS1CALLREADINT;输入X的值CMPAX,-2JGEL2L1:SUBAX,3;AX←X-3JMPDONEL2:CMPAX,3JGL3MOVBX,AXADDAX,AX;AX←2XADDAX,AX;AX←4XADDAX,BX;AX←5XADDAX,6;AX←5X+6JMPDONEL3:MOVAX,2;AX←2DONE:LEADX,MESS2CALLWRITEINT;输出Y的值CALLCRLFMOVAX,4C00HINT21H CODEENDSENDSTART4.13计算分段函数:A,B的值从键盘输入,Y的值送显示器输出(∧表示“并且”,∨表示“或者”)。答:INCLUDEYLIB.HDATASEGEMNTMESS1DB0DH,0AH,‘InputthevalueofAplease:$’MESS2DB0DH,0AH,‘InputthevalueofBplease:$’MESS3DB0DH,0AH,‘Y=:$’ADW?BDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEADX,MESS1CALLREADINT;输入AMOVA,AXLEADX,MESS2CALLREADINT;输入BMOVB,AXANDAX,AXJLL1;B<0,转L1CMPA,0JLL1;A<0,转L1JNZSKIP1CMPB,0JZL2;A=0&&B=0,转L2JMPEXIT;A=0&&B≠0,无定义,转EXITSKIP1:CMPB,0JLEEXIT;A≠0&&B=0,无定义,转EXITL3:MOVAX,ASUBAX,BJMPDISPL2:MOVAX,2JMPDISPL1:MOVAX,A ADDAX,BDISP:LEADX,MESS2CALLWRITEINT;输出Y的值CALLCRLFEXIT:MOVAX,4C00HINT21HCODEENDSENDSTART说明:如果把A、B看作是平面直角坐标的两根轴,那么这个函数在A,B的正轴上无定义。无法计算,也无法输出结果。4.14编写程序,求10元素字数组LIST中绝对值最小的数,存入MIN单元。答:DATASEGEMNTLISTDW-56,+12,88,-126,-5,16,32,-99,72,-18MINDW?MINABSDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVAX,LISTMOVMIN,AX;将数组第一个元素假设为绝对值最小的数MOVMINABS,32767;最小的绝对值假设为32767LEASI,LISTMOVCX,10AGAIN:MOVAX,[SI]CMPAX,0JGESKIP1NEGAX;求绝对值SKIP1:CMPAX,MINABS;绝对值与假设的最小绝对值比较JGESKIP2;假设的绝对值较小,跳过MOVMINABS,AX;保存新的最小绝对值MOVAX,[SI];取出新的绝对值最小的数MOVMIN,AX;保留新的绝对值最小的数SKIP2:ADDSI,2LOOPAGAINMOVAX,4C00HINT21HCODEENDSENDSTART说明:一定要预设最小的绝对值和绝对值最小的数,而且这个绝对值最小的数必须来自LIST数组。4.15编写程序,求20元素无符号字数组ARRAY中最小的奇数,存入ODD单元,如果不存在奇数,将ODD单元清零。 答:DATASEGEMNTARRAYDW56,12,88,126,5,16,32,99,72,18DW116,34,92,32,156,42,816,16,15,218ODDDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVBX,0MOVODD,65535;将65535假设为最小的奇数LEASI,ARRAYMOVCX,20AGAIN:MOVAX,[SI]TESTAX,1;测试是否为奇数JZSKIP;不是奇数跳过INCBX;记录奇数个数CMPAX,ODD;奇数与预设的最小奇数比较JGESKIP;大于预设奇数,跳过MOVODD,AX;小于预设奇数,保留SKIP:ADDSI,2LOOPAGAINCMPBX,0;判有无出现过奇数JNZDONEMOVODD,0;未出现过,把ODD单元清零DONE:MOVAX,4C00HINT21HCODEENDSENDSTART4.16一个有符号字数组以0为结束标志,求这个数组的:最大值、最小值、平均值。答:DATASEGEMNTLISTDW-56,+12,88,-126,-5,16,32,-99,72,-18,0MINDW?MAXDW?AVGDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVMIN,32767;将32767假设为最小的数 MOVMAX,-32768;将-32768假设为最大的数MOVAVG,0;AVG用作累加器,清零LEASI,LISTMOVCX,0AGAIN:MOVAX,[SI]CMPAX,0JZDONE;找到零元素,转DONE结束处理INCCX;纪录非零元素个数ADDAVG,AX;累加CMPAX,MINJGESKIP1MOVMIN.AX;比预设最小值还小,保留SKIP1:CMPAX,MAXJLESKIP2MOVMAX,AX;比预设最大值还大,保留SKIP2:ADDSI,2JMPAGAINDONE:JCXZNULL;元素个数为零,转NULL处理MOVAX,AVGCWDIDIVCXMOVAVG,AX;计算平均值JMPEXITNULL:MOVMIN,0;元素个数为0,将“最大值”、“最小值”MOVMAX,0;“平均值”清零MOVAVG,0EXIT:MOVAX,4C00HINT21HCODEENDSENDSTART4.17数组SCORE中存有一个班级40名学生的英语课程成绩。按照0~59,60~74,75~84,85~100统计各分数段人数,存入N0,N1,N2,N3变量内。答:DATASEGEMNTSCOREDW40DUP(?);运行前置入具体数据N0DW?N1DW?N2DW?N3DW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATA MOVDS,AXMOVN0,0;各计数器清零MOVN1,0MOVN2,0MOVN3,0LEASI,SCOREMOVCX,40AGAIN:MOVAX,[SI]CMPAX,59;分段测试JAL1L0:INCN0JMPNEXTL1:CMPAX,74JAL2INCN1JMPNEXTL2:CMPAX,84JAL3INCN2JMPNEXTL3:CMPAX,100JANEXTINCN3NEXT:ADDSI,2LOOPAGAINEXIT:MOVAX,4C00HINT21HCODEENDSENDSTART4.18STRING是一个16个字符组成的字符串,RULE是一个字整数。编写程序,测试STRING中的每一个字符,如果该字符为数字字符,把RULE中对应位置1,否则置0。答:DATASEGEMNTSTRINGDB16DUP(?);运行前置入具体字符RULEDW?DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXMOVRULE,0;RULE置为初始状态LEASI,STRINGMOVCX,16 AGAIN:SHLRULE,1;右侧空出一位MOVAL,[SI]CMPAL,‘0’;测试是否数字JBNEXTCMPAL,‘9’JANEXTORRULE,1;将RULE对应位置1NEXT:INCSILOOPAGAINEXIT:MOVAX,4C00HINT21HCODEENDSENDSTART4.19S_ARRAY是一个5个字符串组成的字符串数组,每个字符串由16个字符组成,S_RULE是一个5个元素的字数组。编写程序,按照4.18题的规则,用S_RULE数组记录S_ARRAY数组的特征。答:DATASEGEMNTS_ARRAYDB5DUP(16DUP(?));运行前置入具体字符S_RULEDW5DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEABX,S_RULEMOVCX,5INIT:MOVWORDPTR[BX],0;S_RULE置为初始状态ADDBX,2LOOPINITLEASI,STRING;设置指针LEADI,S_RULEMOVCX,5;外层循环计数器置初值LOOPOUT:PUSHCXMOVCX,16;内层循环计数器置初值LOOPIN:SHLWORDPTR[DI],1;右侧空出一位MOVAL,[SI]CMPAL,‘0’;测试是否数字JBSKIPCMPAL,‘9’JASKIPORWORDPTR[DI],1;S_RULE数组元素置位 SKIP:INCSILOOPLOOPINPOPCXADDDI,2LOOPLOOPOUTEXIT:MOVAX,4C00HINT21HCODEENDSENDSTART4.20编写程序,从键盘上输入一个无符号字整数,用“四进制”格式输出它的值(也就是,每2位二进制看作一位四进制数,使用数字0~3)。答:INCLUDEYLIB.HDATASEGEMNTMESS1DB0DH,0AH,‘Inputanumberplease:$’MESS2DB0DH,0AH,‘Thenumberinquardri_systemis:$’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEADX,MESS1CALLREADDEC;输入一个无符号整数MOVBX,AX;转存到BXLEADX,MESS2MOVAH,9INT21H;输出前导信息MOVCX,8ONE:ROLBX,1ROLBX,1;最高2位移到最低位MOVDL,BL;转存到DLANDDL,00000011B;保留最低2位ORDL,30H;转换成ASCII代码MOVAH,2INT21H;输出LOOPONECALLCRLFMOVAX,4C00HINT21HCODEENDSENDSTART 4.21编写程序,把一个30个元素的有符号字数组ARRAY按照各元素的正负分别送入数组P和M,正数和零元素送P数组,负数送M数组。答:DATASEGEMNTARRAYDW30DUP(?);汇编之前置入数据PDW30DUP(?)MDW30DUP(?)DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEABX,ARRAY;ARRAY数组指针MOVSI,0;P数组指针MOVDI,0;M数组指针MOVCX,30ONE:MOVAX,[BX];从ARRAY数组取出一个数据ANDAX,ALJGEPLUS;正数、零转PLUSMINUS:MOVM[DI],AX;负数存入M数组ADDDI,2JMPNEXTPLUS:MOVP[SI],AX;正数、零存入P数组ADDSI,2NEXT:ADDBX,2LOOPONEMOVAX,4C00HINT21HCODEENDSENDSTART4.22缓冲区BUFFER中存放有字符串,以0为结束标志。编写程序,把字符串中的大写字母转换成小写字母。答:DATASEGEMNTBUFFERDB‘AStringforTest.’,0DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEABX,BUFFER;BUFFER缓冲区指针ONE:MOVAL,[BX];从缓冲区取出一个字符ANDAL,ALJZQUIT;为零,处理完成CMPAL,‘A’ JBNEXTCMPAL,‘Z’JANEXTADDAL,‘a’-‘A’MOV[BX],ALNEXT:INCBXJMPONEQUIT:MOVAX,4C00HINT21HCODEENDSENDSTART4.23编写程序,从键盘上输入无符号字整数X,Y的值,进行X+Y的运算,然后按以下格式显示运算结果和运算后对应标志位的状态。SUM=XXXXZF=Y,OF=Y,SF=Y,CF=Y(其中X为十进制数字,Y为0或1)答:INCLUDEYLIB.HCODESEGMENTASSUMECS:CODEMESS1DB0DH,0AH,‘Inputaunsignedintegerplease:$’MESS2DB0DH,0AH,‘SUM=$’MESS3DB0DH,0AH,‘ZF=’ZFDB?DB‘,OF=’OFDB?DB‘,SF=’SFDB?DB‘,CF=’CFDB?DB0DH,0AH,‘$’START:PUSHCSPOPDSLEADX,MESS1CALLREADDECMOVCX,AX;输入XLEADX,MESS1CALLREADDEC;输入YADDAX,CX;求和PUSHF;保留标志位状态LEADX,MESS2CALLWRITEDEC;输出两个数的和POPBX;标志寄存器内容转存入BX MOVAL,‘0’TESTBX,1000000B;测试ZFJZSKP1INCALSKIP1:MOVZF,ALMOVAL,‘0’TESTBX,100000000000B;测试OFJZSKP2INCALSKIP2:MOVOF,ALMOVAL,‘0’TESTBX,10000000B;测试SFJZSKP3INCALSKIP3:MOVSF,ALMOVAL,‘0’TESTBX,1;测试CFJZSKP4INCALSKIP4:MOVCF,ALLEADX,MESS3MOVAH,9INT21H;输出标志位状态MOVAX,4C00HINT21HCODEENDSENDSTART4.24编写程序,从键盘上输入一个字符串,统计其中数字字符,小写字母,大写字母,空格的个数并显示。答:INCLUDEYLIB.HCODESEGMENTASSUMECS:CODEMESS1DB0DH,0AH,‘Inputastringplease:$’BUFFERDB81,?,81DUP(?)MESS2DB0DH,0AH,‘Digits:$’MESS3DB0DH,0AH,‘Uppercasealphabet:$’MESS4DB0DH,0AH,‘Lowercasealphabet:$’MESS5DB0DH,0AH,‘Space:$’START:PUSHCSPOPDSLEADX,MESS1MOVAH,09H INT21H;输出提示信息LEADX,BUFFERMOVAH,0AHINT21H;输入字符串XORDX,DX;各计数器清零XORBX,BXMOVCL,BUFFER+1MOVCH,0;字符个数送CXLEASI,BUFFER+2;设置字符指针ONE:MOVAL,[SI];取出一个字符CMPAL,‘‘JNEL2L1:INCDL;空格字符计数JMPNEXTL2:CMPAL,‘0’JBNEXTCMPAL,‘9’JAL4L3:INCDH;数字字符计数JMPNEXTL4:CMPAL,‘A’JBNEXTCMPAL,‘Z’JAL6L5:INCBH;大写字符计数JMPNEXTL6:CMPAL,‘a’JBNEXTCMPAL,‘z’JANEXTINCBL;小写字母计数NEXT:INCSILOOPONE;循环控制PUSHDXMOVAL,DHLEADX,MESS2MOVAH,0CALLWRITEDEC;输出数字字符个数LEADX,MESS4MOVAL,BLMOVAH,0CALLWRITEDEC;输出小写字母个数LEADX,MESS3MOVAL,BH MOVAH,0CALLWRITEDEC;输出大写字母个数POPDXMOVAL,DLMOVAH,0LEADX,MESS5CALLWRITEDEC;输出空格个数MOVAX,4C00HINT21HCODEENDSENDSTART4.25编写程序,从键盘输入一个无符号字整数,判断它是否为素数,输出判断结果。答:INCLUDEYLIB.HCODESEGMENTASSUMECS:CODEMESS1DB0DH,0AH,‘Inputaunsignednumberplease:$’YESDB0DH,0AH,“It’saprimenumber.$”NODB0DH,0AH,‘Itisn’taprimenumber.$’START:PUSHCSPOPDSLEADX,MESS1CALLREADDEC;输入一个无符号整数MOVCX,AXSHRCX,1;测试最大值装入CXMOVBX,2;第一个测试值TST:CMPBX,CXJAL_YES;测试完成,转L_YESPUSHAXCWDDIVBX;测试:是否整除?POPAXCMPDX,0JZL_NO;已整除,转L_NOINCBX;形成下一个测试数据JMPTST;继续测试L_YES:LEADX,YESJMPOUTPUTL_NO:LEADX,NOOUTPUT:MOVAH,09HINT21H MOVAX,4C00HINT21HCODEENDSENDSTART4.26编写程序,按学号(1~40)输入一个班的汇编语言考试成绩,统计每个学生成绩在班内的排名,按学号顺序输出这个排名。(提示:排名等于成绩高于他/她的人数加1)答:DATASEGEMNTSCOREDB40DUP(?)ORDERDB40DUP(?)MESS1DB0DH,0AH,‘InputascoreofNO.$’MESS2DB0DH,0AH,‘NO.=$’MESS3DB0DH,0AH,‘Order=$’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEASI,SCOREMOVCX,40MOVBX,1INPUT:LEADX,MESS1MOVAX,BXCALLWRITEDEC;输出提示信息和学号MOVDX,-1CALLREADDEC;输入一名学生的成绩MOV[SI],AL;保存成绩INCBXINCSILOOPINPUTLEABX,ORDERMOVCX,40INIT:MOVBYTEPTR[BX],1;将全部学生的“名次”初始值设为1INCBXLOOPINITMOVDI,0;DI为被统计名次学生学号-1MOVCX,40STAT0:PUSHCXMOVCX,40MOVSI,0;SI为其它同学的学号-1 MOVAL,SCORE[DI];取出被统计同学成绩STAT1:CMPAL,SCORE[SI];与其他同学成绩比较JGESKIPINCORDER[DI];低于其他同学成绩,名次加1SKIP:INCSILOOPSTAT1LEADX,MESS2;输出被统计学生学号MOVAX,DIINCAXCALLWRITEDECLEADX,MESS3;输出被统计学生名次MOVAL,ORDER[DI]MOVAH,0CALLWRITEDECPOPCXINCDILOOPSTAT0CALLCRLFMOVAX,4C00HINT21HCODEENDSENDSTART4.27编写程序,读入20个数据,统计每个相同数据出现的次数。答:INCLUDEYLIB.HDATASEGEMNTNUMBERDW20DUP(?)TIMESDW20DUP(?)MESSDB0DH,0AH,‘InputanumberofNO.$’DATAENDSCODESEGMENTASSUMECS:CODE,DS:DATASTART:MOVAX,DATAMOVDS,AXLEASI,NUMBERMOVCX,20MOVBX,1INPUT:LEADX,MESSMOVAX,BX CALLWRITEDEC;输出提示信息和序号MOVDX,-1CALLREADDEC;输入一项数据MOV[SI],AL;保存成绩INCBXADDSI,2LOOPINPUTLEABX,TIMESMOVCX,20INIT:MOVBYTEPTR[BX],-1;将“出现次数”初始值设为-1ADDBX,2LOOPINITMOVDI,0;DI为被统计数据指针MOVCX,20STAT0:PUSHCXMOVCX,20MOVSI,0;SI为其它数据的指针MOVAL,NUMBER[DI];取出被统计数据STAT1:CMPAL,NUMBER[SI];与其他数据相比较JNESKIPINCTIMES[DI];出现相同数据,次数加1SKIP:ADDSI,2LOOPSTAT1;比较下一个数据POPCXADDDI,2LOOPSTAT0MOVAX,4C00HINT21HCODEENDSENDSTART可以看出,本题与4.26虽然题目看上去有明显区别,但是程序的结构十分类似。4.28编写程序,打印九九乘法表。答:INCLUDEYLIB.HCODESEGMENTASSUMECS:CODESPACEDB‘$’;乘积不足两位时补一个空格START:CALLCRLFMOVSI,1;SI为被乘数 MOVCX,9LOOP0:PUSHCXMOVCX,9MOVDI,1;DI为乘数LOOP1:MOVAX,SIMULDIMOVDX,-1CMPAX,10JAESKIPLEADX,SPACE;乘积不足两位时补一个空格SKIP:CALLWRITEDEC;输出乘积INCDILOOPLOOP1CALLCRLF;结束一行INCSIPOPCXLOOPLOOP0MOVAX,4C00HINT21HCODEENDSENDSTART子程序WRITEDEC输出时,数据前后各留出一个空格。程序中对一位数的乘积补上一个空格,这样每个数据共占用4个字符位置,使输出对齐。4.29编写程序,显示1000以内的所有素数。答:INCLUDEYLIB.HCODESEGMENTASSUMECS:CODESTART:CALLCRLFMOVSI,2;SI为被测试的1000以内的整数MOVCX,0;CX记录一行上已输出数据个数(每行输出10个素数)ONE:MOVDI,SISHRDI,1;计算测试范围MOVBX,2;第一个测试数据TST:CMPBX,DI;测试完成?JAOK;测试完成,是素数,转OKMOVAX,SICWDDIVBX;除法测试CMPDX,0JZNEXT;整除,本数据非素数,转NEXTINCBX;形成下一个测试数据 JMPTST;继续测试OK:INCCX;统计本行输出数据个数CMPCX,10JLEOUTPUT;本行数据未满10个,直接输出XORCX,CX;本行数据已满10个,清计数器CALLCRLF;输出回车换行OUTPUT:MOVDX,-1MOVAX,SICALLWRITEDEC;输出一个素数NEXT:INCSI;产生下一个被测试数据CMPSI,1000JBONE;未完成,继续CALLCRLF;结束一行MOVAX,4C00HINT21HCODEENDSENDSTART4.30编写程序,输入N,计算:S=1*2+2*3+……+(N-1)*N答:INCLUDEYLIB.HCODESEGMENTASSUMECS:CODEMESS1DB0DH,0AH,‘InputNplease:$’MESS2DB0DH,0AH,‘S=$’START:PUSHCSPOPDSLEADX,MESS1CALLREADDEC;输入NMOVCX,AXXORBX,BX;BX用作累加器ONE:MOVAX,CXMOVSI,AXDECSIMULSI;计算J*(J-1)ADDBX,AX;累加LOOPONELEADX,MESS2MOVAX,BXCALLWRITEDEC;输出结果CALLCRLFMOVAX,4C00HINT21HCODEENDS ENDSTART4.31编写程序,输入N,输出如下矩阵(设N=5)1111122221333214432154321答:设I为行(1~5),J为列(1~5),则(I,J)位置上的数据为:I>(6-J)?I:6-J。INCLUDEYLIB.HCODESEGMENTASSUMECS:CODESTART:CALLCRLFMOVSI,1;SI为行号ROW:MOVCX,5;CX为6-列号COL:CMPSI,CX;判断当前位置JBUPDOWN:MOVAX,CX;下半三角,取6-列号JMPOUTPUTUP:MOVAX,SI;上半三角,取行号OUTPUT:MOVDX,-1CALLWRITEDEC;输出一个数据LOOPCOLCALLCRLF;结束本行INCSI;修改行号CMPSI,5JBEROW;未满5行,继续MOVAX,4C00HINT21HCODEENDSENDSTART'