1、习题四 汇编语言程序设计主要内容:汇编语言程序设计。主要介绍汇编语言程序的设计方法与编程原理,重点掌握算术运算程序、字符串处理程序、码制转换程序、子程序设计程序、常用 DOS 和 BIOS 功能调用程序、汇编语言常用伪指令。4.1 分析执行下列指令序列后的结果: 1) MOV AX,1234H MOV BX,00FFH AND AX,BX【答】(AX)=0034H2) MOV AL,01010101B AND AL,00011111B ;(AL)=00010101B OR AL,11000000B ;(AL)=11010101B XOR AL,00001111B ;(AL)=11011010B
2、 NOT AL【答】(AL)=00100101B3) MOV DL,05H MOV AX,0A00H MOV DS,AX MOV SI,0H MOV CX,0FH AGAIN: INC SI CMP SI,DL LOOPNE AGAIN HLT 本程序实现了什么功能?【答】在以 0A001H 开始的 15 个单元中查找 05H。4) MOV AX,DSEGADDR MOV DS, AX MOV ES,AX MOV SI, OFFSET B1ADDR MOV DI,OFFSET B2ADDR MOV CX,N CLD REP MOVSB HLT 本程序实现了什么功能?【答】 将 B1ADDR 中
3、 N 个字节数据传送到 B2ADDR 开始的 15 个存储单元 。 5) MOV AX, 0H MOV DS,AX MOV ES, AX MOV AL,05H MOV DI,0A000H MOV CX,0FH CLD AGAIN: SCASBLOOPNE AGAIN HLT本程序实现了什么功能?【答】从地址 0A000H 开始的 15 个单元中查找字节型数据 05H,用条件循环 LOOPNZ,控制数据 05H 的查找。4.2 阅读程序:1). CLD LEA DI,0100H MOV CX, 0080H XOR AX, AX REP STOSW 本程序实现了什么功能?【答】将 DS 中起始地址
4、为 0100H 的 128 个字节单元清零。2). MOV AL, 08H SAL AL,01H ;(AL)=00010000H MOV BL, AL MOV CL ,02H SAL AL,CL ;(AL)=01000000H ADD AL,BL ;(AL)=01010000H 本程序实现了什么功能? 【答】 将 AL 中的内容乘以 10。4.3 试分析下列程序完成什么功能? MOV DX,3F08HMOV AH,0A2HMOV CL,4 SHL DX,CL ;(DX)=F080H MOV BL,AHSHL BL,CL ;(BL)=20H SHR BL,CL ;(BL)=02H OR DL,B
5、L ;(DL)=82H 【答】将 DX 中的低 4 位数据 8H 分离出来,将 AH 中的低 4 位数据 2H 分离出来,合并为 82H存放在 DL。4.4 已知程序段如下: MOV AX,1234H MOV CL,4 ROL AX,CLDEC AXMOV CX,4MUL CX 试问:(1)每条指令执行后,AX 寄存器的内容是什么?(2)每条指令执行后,CF ,SF及 ZF 的值分别是什么?(3)程序运行结束时,AX 及 DX 寄存器的值为多少? 【答】 MOV AX,1234H ; (AX)=1234H, CF=SF=ZF=0 MOV CL,4 ROL AX,CL ; (AX)=2341H
6、,CF=1,SF=ZF=0 DEC AX ; (AX)=2340H, CF=1,SF=ZF=0 MOV CX,4 ;MUL CX ;(AX)= 8000H ,CF=ZF=0,SF=1,DX=04.5 试分析下列程序段: ADD AX,BX JNC L2 SUB AX,BX JNC L3 JMP SHORTL5 如果 AX、BX 的内容给定如下: AX BX (1)14C6H 80DCH (程序转向 L2)(2)B568H 54B7H (程序转向 SHORTL5 )问该程序在上述情况下执行后,程序转向何处? 【答】 (1) 程序转向 L2。(2) 程序转向 SHORTL5。4.6 以下为某个数据
7、段,试问各个变量分别占多少字节,该数据段共占多少字节? DATA SEGMENT VAR1 DW 9 ;2 字节VAR2 DD 10 DUP(?) ,2 ;44 字节VAR3 DB 2 DUP(?,10 DUP( ?) ;22 字节VAR4 DB HOW ARE YOU ;11 字节DATA ENDS【答】该数据段共占 79 字节。4.7 下列语句在存储器中分别为变量分配多少字节空间?并画出存储空间的分配图。 VAR1 DB 10,2 ;2 字节VAR2 DW 5DUP(?),0 ;12 字节VAR3 DB HOW ARE YOU?,$ ;13 字节VAR4 DD -1,1,0 ;2 字节Va
8、r1 Var2 Var3 Var410 ? H FFH2 ? O FFH? W FFH? FFH? A 01H? R 00H? E 00H? 00H? Y 00H? O 00H0 U 00H0 ? 00H$4.8 编写一段程序,比较两个 5 字节的字符串 OLDS 和 NEWS,若相同,在 RESULT 置 0,否则置 0FFH。【答】 参考程序:OLDS DB 1,2,3,4,5NEWS DB 1,2,3,4,5RESULT DB ?MOV SI,OFFSET OLDSMOV DI,OFFSET NEWSMOV CX,10CLD REP CMPSB JNZ NOEQU ;串不相等转MOV A
9、L,0JMP OUTPT NOEQU: MOV AL,0FFH OUTPT: MOV RESULT,ALSTOP: JMP STOP4.9 编程求和 Y=A1 + A2 + . + A100 。其中 Ai 为字节变量。【答】 参考程序:DATA SEGMENTTABLE DW 12,3,45,YAL DW ?YAH DW ?DATA ENDS .MIAN PROC FARPUSH DSMOV AX, 0PUSH AXMOV AX, DATAMOV DS, AXMOV DX,0XOR AX, AX ;清 AXMOV BX, OFFSET TABLEMOV CX, 4CLCLP: ADD AX,
10、BX ;求和JNC DONINC DXCLC DON: INC BXINC BX ;指向下一个数LOOP LP ;未加完,继续MOV YAL,AX ;存和MOV YAH,DXMAIN ENDPCODE ENDSEND START4.10 内存中以 FIRST 和 SECOND 开始的单元中分别存放着两个 16 位组合的十进制(BCD 码)数,低位在前。编程序求这两个数的组合的十进制和,并存到以 THIRD 开始的单元。【答】 参考程序:1325+9839=?DATA SEGMENTFIRST DB 05H,02H,03H,01H ;SECOND DB 09H,03H, 08H,09H;THIR
11、D DB 20 DUP (?)DATA ENDSSTACK SEGMENTST1 DB 100 DUP (SA)TOP1 EQU LENGTH ST1STACK ENDSCODE SEGMENTASUMME CS:CODE,DS:DATA,SS:STACKMAIN PROC FARSTART: MOV AX, DAT ;初始化数据段MOV DS, AXMOV AX, STACK ;初始化堆栈段MOV SS, AXMOV AX, TOP1MOV SP, AXMOV CX, 4 ;计算 4 次MOV BX, OFFSET DAT1 ;取数据地址MOV SI , OFFSET DAT2 ;取数据地址
12、MOV DI , OFFSET SUM ;取结果地址MOV AH, 00H ;将暂存标志的 AH 清 0DON1: MOV AL, BX ;取第一个数 SAHF ;将 AH 中的标志送标志寄存器ADC AL, DI ;与第二个数带进位加AAA ;十进制校正LAHF ;将标志寄存器内容送 AHOR AL, 30H ;计算值拼成 ASCII 码MOV DI, AL ;存结果的 ASCII 码INC BX ;指向第一个数的下一位INC SI ;指向第二个数的下一位INC DI ;指向结果单元的下一位LOOP DON1 ;未计算完,继续AND AH, 01H ;将最高位的进位标志送 AHOR AH,
13、30H ;最高位的进位位拼成 ASCII 码MOV DI, AH ;存结果的最高位MOV AH, 02H ;调用 DOS 的 02H 功能显示MOV CX, 05H ;显示数据的位数DON2: MOV DL,DI ;显示数据送 DLINT 21H ;显示DEC DI ;显示数据所在存储单元加一LOOP DON2 ;未显示完,继续MOV AH, 4CH ;返回 DOSINT 21H RET MAIN ENDP CODE ENDS END START 4.11 试编程序,统计由 40000H 开始的 16K 个单元中所存放的字符“A “的个数,并将结果存放在 DX 中。【答】 参考程序DATA S
14、EGMENT DATA1 DB DFASFAAAFDFAAFFFACOUNT EQU $-DATA1DATA ENDSSTACK SEGMENTSTA DB 100 DUP (?)TOP EQU LENGTH STA STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKBEGIN: MOV AX,DATAMOV DS,AXMOV AX,STACKMOV SS,AXMOV AX,TOPMOV SP,AXMOV CX,COUNTMOV DX,0LEA SI,DATA1MOV BL,A NEXT : CMP SI,BLJNZ OTHERINC D
15、XOTHER: INC SILOOP NEXTCODE ENDSEND BEGIN4.12 统计数据块中正数与负数的个数,并将正数与负数分别送到两个缓冲区。【答】 参考程序:BLOCK DB -1,-3,5,6,-2,0,20,10 PLUS_D DB 8 DUP(?) ;正数缓冲区MINUS_D DB 8 DUP(?) ;负数缓冲区PLUS DB 0MINUS DB 0MOV SI,OFFSET BLOCKMOV DI,OFFSET PLUS_DMOV BX,OFFSET MINUS_DMOV CX, 8 ;数据个数送 CXGOON: LODSB ;AL SITEST AX, 80HJNZ
16、JMIUS ;为负数,转INC PLUS ;正数个数加一STOSB ;DI AL, 传正数JMP AGAINJMIUS: INC MINUS ;负数个数加一XCHG BX, DISTOSB ;送负数到缓冲区XCHG BX, DIAGAIN: DEC CXJNZ GOON4.13 编写一个子程序将 AX 中的十六进制数,转换成 ASCII 码, 存于 ADR 开始的四个单元中。提示:1)、AX 中的数从左到右,转换成 ASCII 码,用循环左移 ROL 和 AND 指令,把提出的一个十六进制数置 BL 中;2)、0 9 的 ASCII 码: 30 39H,A F 的 ASCII 码:41H 46
17、H。( 先把每个数加 30H,判断是否为数字 0 9?若是 A F,再加 07H,得字母的 ASCII 码。)【答】 参考程序:DATA SEGMENTADR DB 4 DUP(?)DATA ENDSCODE SEGMENTMAIN PROC FARASSUME CS:CODE,DS:DATASTART: MOV AX,7EC3H ;假设 ax 中存放 7ec3hLEA SI,ADRMOV DL,4AGAIN:MOV BX,AXAND BX,000FHADD BL,30HCMP BL,9JG ADUSTJMP STOREADUST: ADD BL ,07HSTORE: MOV SI,BLINC
18、 SIMOV CL,4ROL AX,CLDEC DLJNZ AGAINMAIN ENDPCODE ENDSENDSTART4.14 编写一个子程序将 AX 中的 2 进制数,转换成 10 进制 ASCII 码, 存于 ADR 开始的五个单元中。【答】参考程序:BIN EQU 5555H;假设二进制数为 5555HDATA SEGMENTADR DB 4 DUP(?)DATA ENDSSTACK SEGMENTSTA DB 100 DUP (?)TOP EQU LENGTH STA STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTAR
19、T: MOV AX,DATAMOV DS,AXMOV AX,STACKMOV SS,AXMOV AX,TOPMOV SP,AXMOV AX,BINLEA BX,ADRMOV CX,10000DCALL BINTODECMOV CX,1000DCALL BINTODECMOV CX,100DCALL BINTODEC MOV CX,10DCALL BINTODECMOV CX,01DCALL BINTODECMOV AX,04CH ;返回 DOSINT 21HMAIN ENDP;十进制转二进制,完成一位运算,十进制存于 ax 中,结果存于 bx 所指向的地址中BINTODEC PROC NEAR
20、MOV DX,0DIV CXADD AL,30HMOV BX,ALMOV AX,DXINC BXRETBINTODEC ENDPCODE ENDSEND START 4.15 编写一个子程序,对 AL 中的数据进行偶校验,并将经过校验的结果放回 AL 中。【答】参考程序:JIAOYAN PROC FARMOV AL,1001110BOR AL, ALJNP NEXTMOV AL,0JMP DONENEXT: MOV AL,1DONE: MOV AH,04CHINT 21HJIAOYAN ENDP4.16 从 2000H 单元开始的区域,存放 100 个字节的字符串,其中有几个$符号(ASCII
21、 码为 24),找出第一个$符号,送 AL 中,地址送 BX。【答】参考程序:SEARCH PROC FARMOV DI,2000HMOV CX,100MOV AL,24HCLDREPNZ SCASB JNZ STOPDEC DIMOV BX,DIMOV AL,DISTOP: RETSEARCH ENDP4.17 用串操作指令实现:先将 100H 个数从 2170H 单元处搬到 1000H 单元处,然后从中检索等于AL 中字符的单元,并将此单元换成空格字符。【答】参考程序:MOV AL,24HMOV SI,2170HMOV DI,1000HMOV CX,100HCLDDO: REP MOVSB
22、MOV DI,1000HMOV CX,100HCLDREPNZ SCASBDEC DIMOV DI,20HINC DICMP CX,0JNZ DOHLT4.18 从 60H 个元素中寻找一个最大的值,并放到 AL 中,假设这 60 个元素放在 DATA1 开始的单元中。【答】参考程序:DATA SEGMENT DATA1 DB 0,1,2,3,4,5,6,7,8,9 ;DATA ENDSSTACK SEGMENTSTA DB 20 DUP (?)TOP EQU LENGTH STASTACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTAR
23、T: MOV AX,DATAMOV DS,AXMOV AX,STACKMOV SS,AXMOV AX,TOPMOV SP,AXMOV CX,10MOV AL,0LEA BX,DATA1AGAIN: CMP AL,BXJGE NEXT ;大于等于转移MOV AL,BXNEXT : INC BXLOOP AGAINMOV AH,4CHINT 21HCODE ENDSEND START4.19 排序程序设计: 把表中元素按值的大小升序排列。要求显示排序前和排序后的数据。【答】参考程序:DATA SEGMENT TABDB 8095554 N=$-TAB OK DB 0DH,0AH,OK!$ DATA
24、 ENDSSTACK SEGMENT STA DB 20 DUP(?)TOP EQULENGTH STASTAC ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACKSTAR: MOV AX,DATAMOV DS,AX ;初始化数据段MOV AX,STACKMOV SS,AXMOV AX,TOPMOV SP,AXCALL ARRAYDO: MOV AH,4CHINT 21H ;返回 DOSARRAY PROC NEARPUSH AXPUSH BXPUSH CXPUSH DXMOV DL,N-1 ;置外循环次数MOV DH,1 ;设有交换标志XOR BX
25、, BX UPPER: OR DH,DH ;JZ DISP ;无交换,已排好序,退出 MOV DH,0 ;无交换MOV CX,N-1 SUB CX,BX ;CX=CX-I 内循环次数 MOV SI,0 ;指向表首INNER: MOV AL,TABSI ;字符送 ALINC SI ;指向下个字符CMP AL,TABSI ;比较表中相邻字符JBE DON ;小于 XCHG AL,TABSI ;否则交换,大字符下 MOV TABSI-1,AL ;小字符上浮MOV DH,1 ;有交换,DH=1 DON: LOOP INNER ;内循环结束?CX-1INC BX ;一次内循环完成,加一DEC DL ;外
26、循环次数减一 CMP DL,0JNZ UPPER ;外循环次数非零,继续 DISP: MOV DX,OFFSET TABMOV AH,09HINT 21H ;显示排好序的字符POP DXPOP CXPOP BXPOP AXRETARRAY ENDP CODE ENDSENDSTAR 4.20 编写一段程序,接收从键盘输入的 10 个数,输入回车符表示结束,然后将这些数加密后存于 BUFF 缓冲区中。加密表为:输入数字: 0,1,2,3,4,5,6,7,8,9;密码数字:7,5,9,1,3,6,8,0,2,4。【答】参考程序:DATA SEGMENTTABLE DB 7,5,9,1, 3,6,8
27、,0,2,4;密码表BUFF DB 10 DUP(?) ,$存放转换数字的缓冲区DATA ENDSSTACK SEGMENTSTA DB 20 DUP(?)TOP EQU LENGTH STASTACK ENDSCODE SEGMENTMOV AX,STACKMOV SS,AXMOV DI , OFFSET BUFFLEA BX , TABLEMOV CX,0DHRE1:MOV AH , 1 ;从键盘输入INT 21HCMP AL,0DHJZ DONESUB AL,30HXLATADD AL,30HMOV DI , ALINC DILOOP RE1DONE: MOV DX , OFFSET B
28、UFFMOV AH , 09HINT 21HMOV AH,4CHINT 21HCODE ENDS4.21 编程序从键盘接收一个 4 位 16 进制数,转换为 10 进制数后,送显示。【答】算法:先将输入的十六进制数保存到 BX 中,BX 中的数范围在+32767-32768 之间,先检查 BX 中的符号位,以决定输出“+”还是“-”;若是负数,应先求补,得到原码后即可与正数作统一处理。转换方法为将被转换的二进制数先除;以 10000,商即为万位数,再将余数除以 1000,商为千位数,依此类推,求出百、十位数,剩的为个位数。最后,将各个数加上30H,即成为对应字符。DATA SEGMENTOUT
29、_ASC_SUM db 6 dup(?),$DATA ENDSSTACK SEGMENTSTA DB 20 DUP(?)TOP EQU LENGTH STASTACK ENDSCODE SEGMENTASSUME CS :CODE,DS:DATA,SS:STACKSTART: MOV AX,DATAMOV DS,AXMOV AX,STACKMOV SS,AXMOV AX,TOPMOV SP,AXMOV CX , 4 ;输入 4 次MOV DX , CX ;转换 4 次MOV BX , 0 ;用 BX 保存输入数RE1:MOV AH , 1 ;从键盘输入INT 21HCALL ZH ;通过子程序
30、转换SHL BX , CL ;组合成十六进制数ADD BL , ALDEC DXJNZ RE1 ;循环输入四个数MOV AX,BXMOV OUT_ASC_SUM , +CMP AX , 0JGE L4 ;不是负数,转移 NEG AXMOV OUT_ASC_SUM , -L4: CWDMOV BX , 10000DIV BXADD AL , 30H ;将万位转换为数字(商应在 AX 内,但因为商不大于 9,所以有效部分在 al 内)MOV OUT_ASC_SUM+1 , AL ;保存万位数字MOV AX , DX ;将余数置入 AX 内,以便当作被除数CWDMOV BX , 1000DIV BX
31、ADD AL , 30HMOV OUT_ASC_SUM+2 , AL ;保存千位数字MOV AX , DX ;将余数置入 AX 内,以便当作被除数 MOV BL , 100DIV BLADD AL , 30HMOV OUT_ASC_SUM+3 , AL ;保存百位数字MOV AL , AHCBWMOV BL , 10DIV BLADD AL , 30HMOV OUT_ASC_SUM+4 , AL ;保存十位数字ADD AH , 30HMOV OUT_ASC_SUM+5 , AH ;保存个位数字MOV DX , OFFSET OUT_ASC_SUMMOV AH , 09HINT 21HMOV AH,4CHINT 21HZH PROCCMP AL , 9 ;将 ASCII 码转换为 16 进制JBE A2 ;键入值9(0-9)则减 30HCMP AL, a ;键入值a(A-F) 则减 37HJB A1SUB AL , 20H ;值在a -f则先减 20H,再减 37HA1: SUB AL , 7A2: SUB AL , 30HRETZH ENDP CODE ENDSEND START(以上参考答案由黄玉清整理)