MOV [DI],20H INC DI CMP CX,0 JNZ DO
HLT
4.18 从60H个元素中寻找一个最大的值,并放到AL中,假设这60个元素放在BUF开始的单元中。
【答】参考程序: DATA SEGMENT
BUF DB 0,1,2,3,4,5,6,7,8,9 ; DATA ENDS
STACK SEGMENT
STA DB 20 DUP (?) TOP EQU $- STA STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START: MOV AX,DATA
MOV DS,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX MOV CX,10 MOV AL,0 LEA BX,BUF
AGAIN: CMP AL,[BX]
JGE NEXT ;大于等于转移 MOV AL,[BX]
NEXT : INC BX
LOOP AGAIN MOV AH,4CH INT 21H
CODE ENDS
END START
4.19 排序程序设计: 把表中元素按值的大小升序排列。要求显示排序前和排序后的数据。 【答】参考程序: DATA SEGMENT
TAB DB '8095554'
N=$-TAB
OK DB 0DH,0AH,'OK!$' DATA ENDS
STACK SEGMENT STA DB 20 DUP(?) TOP EQU $-STA STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
STAR: MOV AX,DATA
MOV DS,AX ;初始化数据段 MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX CALL ARRAY
DO: MOV AH,4CH
INT 21H ;返回DOS
ARRAY PROC NEAR
PUSH AX PUSH BX PUSH CX PUSH DX MOV DL,N-1 ;置外循环次数 MOV DH,1 ;设有交换标志 XOR BX, 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,TAB[SI] ;字符送AL
INC SI ;指向下个字符 CMP AL,TAB[SI] ;比较表中相邻字符 JBE DON ;小于
XCHG AL,TAB[SI] ;否则交换,大字符下 MOV TAB[SI-1],AL ;小字符上浮 MOV DH,1 ;有交换,DH=1
DON: LOOP INNER ;内循环结束?CX-1
INC BX ;一次内循环完成,加一 DEC DL ;外循环次数减一 CMP DL,0 JNZ UPPER ;外循环次数非零,继续
DISP: MOV DX,OFFSET TAB
MOV AH,09H INT 21H ;显示排好序的字符 POP DX POP CX POP BX POP AX RET
ARRAY ENDP CODE ENDS
END STAR
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 SEGMENT
TABLE DB 7,5,9,1,3,6,8,0,2,4;密码表 BUFF DB 10 DUP(?) ,'$'存放转换数字的缓冲区 DATA ENDS
STACK SEGMENT
STA DB 20 DUP(?)
TOP EQU LENGTH STA STACK ENDS
CODE SEGMENT
MOV AX,STACK MOV SS,AX
MOV DI , OFFSET BUFF LEA BX , TABLE MOV CX,0DH
INPUT: MOV AH , 1 ;从键盘输入
INT 21H CMP AL,0DH ;0DH为回车符 JZ DONE
SUB AL,30H XLAT ADD AL,30H MOV [DI] , AL INC DI LOOP INPUT
DONE: MOV DX , OFFSET BUFF
MOV AH , 09H INT 21H MOV AH,4CH INT 21H
CODE ENDS
4.21 编程序从键盘接收一个4位16进制数,转换为10进制数后,送显示。
【答】算法:(1)先将输入的十六进制数的ASCII码,处理成16进制数保存到BX中,BX中的数范围在+32767~-32768之间;(2)先检查BX中的符号位,以决定输出“+”还是“-”;若是负数,应先求补,得到原码后即可与正数作统一处理。转换方法可以调用题4.14中的BINASCII子程序。
DATA SEGMENT
ADR DB 6 DUP(0),'$' ;十进制数以ASCII码存储 DATA ENDS
STACK SEGMENT
STA DB 20 DUP(0) TOP EQU $- STA STACK ENDS
CODE SEGMENT
ASSUME CS :CODE,DS:DATA,SS:STACK main proc far START: MOV AX,DATA
MOV DS,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX MOV CX , 4 ;输入4次 MOV DX , CX ;转换4次 MOV BX , 0 ;用BX保存输入数 INPUT: MOV AH , 1 ;从键盘输入 INT 21H
CALL COVERT ;通过子程序转换 SHL BX , CL ;组合成十六进制数 ADD BL , AL DEC DX JNZ INPUT ;循环输入四个数 MOV AX,BX LEA DI,ADR
CALL BINASCII ;十六位二进制数转换为十进制ascii码 MOV AH,4CH INT 21H ;返回DOS
main endp
;-------------------------------------------------------------------
;将ASCII码转换为16进制,入口=AL=ascii码,出口AL=16进制数 COVERT PROC CMP AL, '9' ;将ASCII码转换为16进制 JBE A2 ;键入值≤'9'('0'-'9')则减30H CMP AL, 'a' ;键入值<'a'('A'-'F') 则减37H JB A1 SUB AL , 20H ;值在'a' -'f'则先减20H,再减37H A1: SUB AL, 7
A2: SUB AL ,30H RET
COVERT ENDP
;----------------------------------------------------------------------------
;子程序BINASCII功能:将16位二进制数转换为ASCII码,存于ADR开始的连续6个单元,并显示
;入口参数:AX=待转换的数, 预定义一个缓存区ADR,7个字节,最末字节为'$'字符。 ;出口参数:DI=转换好的ASCII码首地址,显示该十进制数据
BINASCII PROC PUSH BX PUSH CX PUSH DX TEST AX,8000H ;判断数据的符号 JNS PLUS
MINUS: MOV BYTE PTR[DI],'-' ;将符号存储
NEG AX ;如是负数,取相反数去掉符号位 JMP GO
PLUS: MOV BYTE PTR[DI],'+' ;将符号码存储
GO: ADD DI,5 ;DI指向个位
MOV CX,5 MOV BX,10
LP: MOV DX,0
DIV BX ;算法为a/10 ,余数为一个低位十进制数 ADD DL,30H ;转换为ASCII码 MOV BYTE PTR[DI],DL ;从个位开始存储 DEC DI LOOP LP MOV DX,DI MOV AH,09H INT 21H ;显示 POP DX POP CX POP BX RET
BINASCII ENDP
;------------------------------------------------------ CODE ENDS
END START