汇编题2-5

汇编题2-5

使用8086指令编写一个比赛得分程序。共有7个评委,按百分制打分,计分原则是去掉一个最高分和一个最低分,求平均值。要求:
(1)评委的打分以十进制从键盘输入。
(2)成绩以十进制给出,并保留1位小数。

enterline macro			;换行回车模块
	mov dl,13
	mov ah,2
	int 21h
	mov dl,10
	mov ah,2
	int 21h
endm
	
DATAS SEGMENT
    buf DB 10,?,10 dup(0)		;ASCTONUM用
    num DW 10 dup(0)
    err db 'Illegal input! Please Try Again$'	;ASCTONUM用
    flag db 0						;NUMTOASC用
DATAS ENDS

STACKS SEGMENT PARA STACK
	DW 100H DUP(0)
STACKS ENDS

CODES SEGMENT
    ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
    MOV AX,DATAS
    MOV DS,AX
;————————————代码开始段——————————————   
    XOR DI,DI		    	;接收10个10-999的整数
BEGREC:			
	CALL ASCTONUM
    MOV num[DI],SI
    ADD DI,2
    CMP DI,14				;(2n,n为待排数字个数)
    JB	BEGREC				;接收完成
	CALL ORDER				;排序
	
	XOR AX,AX
	MOV SI,2
	MOV CX,5
BEGINADD:
	ADD AX,num[SI]
	add SI,2
	LOOP BEGINADD			;此时AX保存去掉最高分最低分后的得分总和

	mov bx,5
	div bl
	xor bx,bx
	mov bl,ah
	xor ah,ah
	mov si,ax
	call NUMTOASC			;输出整数部分
	mov dl,'.'
	mov ah,2
	int 21h
	
	mov al,bl
	xor ah,ah
	mov bx,10
	mul bl
	mov bx,5
	div bl
	xor ah,ah
	mov si,ax
	call NUMTOASC			;输出小数部分
	
;————————————代码结束段——————————————       
    MOV AH,4CH
    INT 21H
    
    
    
;--------------------子程序部分---------------------
    
ASCTONUM PROC;ascii码转换为十进制数字并保存至SI(无传入参数为,传出参数为SI,使用内存单元buf、err,含输入限制:0-100整数)
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX
	PUSH DI
	
BEGIN1:
    lea dx,buf
    mov ah,10
    int 21h
    enterline
    						;思路:从最低位不断向高位扫描,每位-30H后*权重(1/10/100)
    mov cl,buf+1			;cl记录输入数据个数
    xor ch,ch			
    xor di,di
    xor dx,dx
    mov bx,1				;BX为权重,储存当前位的数字(储存在AX中)应该乘的数(1/10/100)
    lea si,buf+2			;si为当前位置下标
    add si,cx
    dec si
    
cov:mov al,[si]				;确认当前位符合要求(0-9)
	cmp al,'0'
	jb error
	cmp al,'9'
	ja error

    sub al,30h				;AL储存当前位的数字(非ASCII码)
    xor ah,ah				;AX储存当前位的数字(非ASCII码)
    mul bx					;AX乘该位的权重
    
    cmp dx,0				;有溢出,报错
    jne error
    
    add di,ax				;将结果储存到DI,有溢出则报错
    jc error
    
    mov ax,bx				;BX(权重)乘10
    mov bx,10
    mul bx
    mov bx,ax
    
    dec si					;SI指针移向高一位
    loop cov    			;CX--,循环,直至CX为0,所有数据处理完毕
   
   	mov SI,DI				;接收数字部分完成,数字保存在SI中
   	
   	CMP SI,100				;范围控制,当前范围为0-100
	JA error
   	
    jmp stop

error:
	lea dx,err
    mov ah,9
    int 21h
    enterline     
    jmp BEGIN1   
        
stop:
	POP DI
	POP DX
	POP CX
	POP BX
	POP AX
	RET

ASCTONUM ENDP

NUMTOASC PROC;将SI寄存器中的十进制数转换为ASCII码并输出(传入参数为SI,无传出参数,使用内存单元flag,无空格无回车)
		PUSH AX
		PUSH BX
		PUSH CX
		PUSH DX
	    
	    mov ax, SI			;(有效数值为0~65535)										;准备阶段
	    mov flag,0	     	;从高位向低位扫描,第一次遇到不为0的位时flag置为1
	    mov bx,10000		;BX为权重(目前为最高位权重)
	    
	cov2:																				;循环开始
		xor dx,dx
		div bx				;AX/BX,余数(低于当前位的内容)存入DX,商(当前位)存入AX
		mov cx,dx			;余数(低于当前位的内容)存入CX
		
		cmp flag,0
		jne nor2
		cmp ax,0
		je cont2
		
	nor2:					;当flag==0且AX!=0 或 flag!=0时执行nor2
		mov dl,al			;将AL中数字转为ascii码输出同时将flag置1
		add dl,30h
		mov ah,2
		int 21h		
		mov flag,1
		
	cont2:					;仅当flag==0且AX==0时,跳过nor2,不输出当前AL中的数字
		cmp bx,10
		je outer2			;如果bx==0(已扫描到十位仍没发现不是0的数),跳到outer2
		
		xor dx,dx			;BX/10
		mov ax,bx
		mov bx,10
	    div bx
	    mov bx,ax
	    
	    mov ax,cx			;将AX的值改为 CX中储存的余数
	    jmp cov2   																		;循环结束
	   
	outer2:					;将cl中数字转为ascii码输出
		mov dl,cl
		add dl,30h
		mov ah,2
		int 21h
		
		
	stop2:
		POP DX
		POP CX
		POP BX
		POP AX
		RET
NUMTOASC ENDP

ORDER PROC;选择排序法
	PUSH DI
	PUSH SI
	PUSH AX
	PUSH BX
	PUSH CX
	PUSH DX
	
	XOR SI,SI;SI记录搜索轮次,第一次从0~18,第二次从2~18(2n-2,n为待排数字个数)
	XOR DI,DI;DI为每轮搜索动态下标
	MOV BX,DI;BX为每轮搜索最小值下标
BEGINSEARCH:

	MOV DX,num[BX]
	CMP DX,num[DI]

	JB SKIP
	MOV BX,DI
SKIP:
	ADD DI,2
	CMP DI,14		;(2n,n为待排数字个数)
	JAE FINISHALOOP
	JMP BEGINSEARCH
	
FINISHALOOP:
	MOV DX,num[SI];AX,DX为临时变量,交换num[SI],num[BX]
	MOV AX,num[BX]
	MOV num[SI],AX
	MOV num[BX],DX
	
	ADD SI,2
	CMP SI,12		;(2n-2,n为待排数字个数)
	MOV DI,SI
	MOV BX,DI
	JBE BEGINSEARCH


	POP DX
	POP CX
	POP BX
	POP AX
	POP SI
	POP DI
	RET
ORDER ENDP
;--------------------子程序部分结束---------------------
CODES ENDS
    END START
  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值