论坛: 编程破解 标题: 莱鸟学编程之20130108 复制本贴地址    
作者: 黄勇刚 [hyg0817]    论坛用户   登录
本莱鸟想自学编程,但不能空想,得干点什么。千里之行,始于足下,那么现在就开始练习。
以下习题虽出自书上,但完全由本人独立完成,同时希望能够得到各位高手的指点。
题目如下:
    试编制一个比赛程序。七个评委分别给分在10-20之间的整数,七个评分中去掉一个最高分,去掉一个最低分,将剩下五个分的平均值作为最后得分。程序要求如下:(1)评委给分以两位十进制数制从键盘输入;(2)最后得分以十进制形式在屏幕上显示;(3)最后得分取小数1-2位。

此程序对于初学者的我来说,是比较复杂的。所以我决定先理清思路,想好解决问题的步骤。然后分解成几个模块,各各击破。

首先,我想完成程序的第一部份功能,就是从键盘接收七个两位十进制数,并转化为二进制进行存储。

第一部分功能实现思路:

定义一个字节型变量,占两个字节,用来存储输入的十位和个位。
定义一个字节型变量,占一个字节,用来存储前面双字节变量经转化后的的二进制形式。
定义一个字节型变量,用来存储字符串:“请输入10-20之间的分数:”
定义一个字节型变量,用来存储字符串:“十位数必须为1或者2!”
定义一个字节型变量,用来存储字符串:“个位数字必须为0到9,并且十位数为2,则必须为0”
实现要点:
1,定义一个循环,在第一次循环时(即十位数输入时),判断输入的字符必须为‘2’或者‘1’
2,在第二次循环时,先判断所存入的十位数,如果为1,则个位可以为‘0’至‘9’,如果为2,则个位必须为’0‘
3,将双字节变量中的十位和个位转化为二进制形式,并且存入单字节变量。
4,如此循环七次,得到七个分数。

下面开始编写代码(第一部份功能已完成):

DATA SEGMENT
            INPUT DB 02H DUP(0)  ;存放输入的十进制数
            MESSAGE1 DB  '请输入七个10-20之间的评分:',13,10,'$'
            MESSAGE2 DB  '十位数只能输入0或者1',13,10,'$'
            MESSAGE3 DB  '十位数为1,则个位只能输入0-9之间的数',13,10,'$'
            MESSAGE4 DB  '十位数为2,则个位只能输入0',13,10,'$'
            MESSAGE5 DB  '最后得分为:',13,10,'$' 
            SAVE DB 07H DUP(0) ;存放转化后的二进制数
            ZHDF DB 03H DUP(0) ;存放最后所得平均分
            XSBL DB 'ABCDE',13,10,'$'

DATA ENDS

PUBLIC SAVE,ZHDF,XSBL,MESSAGE5
EXTRN PFXJ:FAR


CODE SEGMENT
      ASSUME CS:CODE,DS:DATA
START:
      MOV AX,DATA
      MOV DS,AX
      MOV BP,OFFSET SAVE
      MOV DX,OFFSET MESSAGE1
      MOV AH,9
      INT 21H

      MOV CX,7
XH7C:              ;循环7次,实现7个评分的输入.
      PUSH CX
      LEA SI,INPUT
      MOV CX,2
     
SRPF:            ;输入10-20之间的评分。
      MOV AH,1
      INT 21H
      CMP CX,1 ;判断,如果是第二次循环,则转入各位的输入规则。
      JE SRGW  ;否则输入十位
SRSW:     
      CMP AL,'1'  ;十位数非1或者2,则转入错误提示。
      JB ERR1
      CMP AL,'2'
      JA ERR1
      JMP BCSR  ;否则保存输入的十位数。
SRGW:
      CMP BYTE PTR -1[SI],1 ;判断,如果十位为1,则各位可以为0-9
      JNE ZNW0              ;否则,个位只能为0
      CMP AL,'0'
      JB ERR2
      CMP AL,'9'            ;十位为1,个位非0-9则提示错误。
      JA ERR2
      JMP BCSR
ZNW0:
      CMP AL,'0'          ;十位为2,如果个位输入不为0,则提示错误.
      JNZ ERR3


BCSR:
      MOV DL,AL            ;输入正确,则保存所输入的十进制数(为非压缩BCD码)
      AND DL,0FH
      MOV [SI],DL
      INC SI
LOOP SRPF
MOV AH,2
MOV DL,13
INT 21H
MOV DL,10
INT 21H            ;回车换行
JMP SRWC          ;输入完成
ERR1:
    LEA DX,MESSAGE2
    JMP DISP
ERR2:
    LEA DX,MESSAGE3
    JMP DISP
ERR3:
    LEA DX,MESSAGE4
   
DISP:              ;回车,换行,显示错误提示。
      MOV BX,DX
      MOV AH,2
      MOV DL,13
      INT 21H
      MOV DL,10
      INT 21H
      MOV DX,BX
      MOV AH,9
      INT 21H

SRWC:
      MOV SI,10
      XOR AX,AX
      MOV CX,2
      LEA DI,INPUT
JZZH:                  ;完成输入评分从十进制到二进制的转化。
      MUL SI     
      ADD AL,[DI]
      ADC AH,0
      INC DI
LOOP JZZH

      MOV [BP],AL
      INC BP
      POP CX
      DEC CX
      CMP CX,0
JNZ JMP7      ;如果CX=0,则7个评分输入完成,退出输入程序.否则,继续输入评分.
JMP EXIT

JMP7:
    JMP XH7C
EXIT:
      CALL PFXJ
      MOV AH,4CH
      INT 21H       
CODE ENDS
      END START

(未完待续......)

小结:到今天为止,完成了第一部份的功能,即实现了7个评分的输入并存储.


[此贴被 黄勇刚(hyg0817) 在 01月14日02时17分 编辑过]

地主 发表时间: 13-01-08 01:33

回复: 黄勇刚 [hyg0817]   论坛用户   登录
今天开始第二部分功能:

实现思路:首先,将SAVE变量中的七个评分由大到小排序,然后指针从第二个到第六个,实现抛弃最高和最低分。最后将五个评分相加。
我打算将这第二部分功能做为单独的一个模块,然后在上面的模块中调用。

下面开始编写代码:

PUBLIC PFXJ
EXTRN SAVE:BYTE,ZHDF:BYTE,DISPPF:FAR


CODE SEGMENT
ASSUME CS:CODE

PFXJ PROC FAR

MOV BX,OFFSET SAVE
MOV CX,6

DXH:            ;大循环,实现七个数的排序。
    PUSH CX
    MOV SI,0
    MOV AL,[BX][SI]
XXH:                ;小循环,实现将本轮最大数放入AL。
    CMP AL,BYTE PTR 1[BX][SI]
    JB JHWZ          ;AL小于下一个,相交换,否则跳到下一个进行比较。
    JMP XYG
JHWZ:
    XCHG AL,1[BX][SI]
XYG:
    INC SI
LOOP XXH
MOV [BX],AL
INC BX
POP CX
LOOP DXH
LEA BX,SAVE
INC BX
MOV CX,5
XOR AX,AX
WSXJ:
    ADD AL,[BX]
    INC BX
LOOP WSXJ
LEA SI,ZHDF
MOV BL,5
DIV BL
MOV [SI],AL
INC SI
MOV CX,2
MOV DL,10
XSW:
 
  MOV AL,AH
  MUL DL
  XOR AH,AH
  DIV BL
  MOV [SI],AL
  INC SI
LOOP XSW
CALL DISPPF
RET
PFXJ ENDP
CODE ENDS
    END

(未完待续......)

小结:今天实现了第二部份功能中的五个评分相加,并将所得平均分存入变量ZHDF的功能。


[此贴被 黄勇刚(hyg0817) 在 01月11日23时40分 编辑过]

B1层 发表时间: 13-01-09 23:32

回复: 黄勇刚 [hyg0817]   论坛用户   登录
今天完成最后一部分功能,实现将十六进制的评分转化为十进制评分,并显示的功能。

实现思路:将变量ZHDF转化为十进制非压缩BCD码,并且保存于变量XSBL处。将XSBL处的非压缩BCD码转化为ASCII码,最后调用中断显示。这个功能也用单独的一个模块完成。

代码如下:

PUBLIC DISPPF
EXTRN ZHDF:BYTE,MESSAGE5:BYTE,XSBL:BYTE

CODE SEGMENT
ASSUME CS:CODE
DISPPF PROC FAR
MOV BL,10
LEA SI,ZHDF
LEA DI,XSBL
XOR AH,AH
MOV AL,BYTE PTR [SI]
DIV BL
MOV [DI],AL
MOV 1[DI],AH
MOV BYTE PTR 2[DI],'.'
MOV AL,1[SI]
MOV 3[DI],AL
MOV AL,2[SI]
MOV 4[DI],AL
MOV CX,5
ZHASC:
      ADD BYTE PTR [DI],30H
      INC DI
LOOP ZHASC
LEA DI,XSBL
MOV BYTE PTR 2[DI],'.'
LEA DX,MESSAGE5
MOV AH,9
INT 21H
LEA DX,XSBL
INT 21H
RET
DISPPF ENDP
CODE ENDS
    END

至此,此习题可以说基本上已由本人独立完成,基本功能均已实现,但仍有细节之有待日后完善。本莱鸟在此班门弄斧,还望各位高手批评指正。

本程序在MASM 5.0下编译通过。
本程序及源码下载地址:

ftp://ftp.20cn.net/pub/scandisk/PFCX.zip

                   
                  THE END

      鸣谢:
               
                    20CN网络安全小组提供技术论坛
                    20CN网络安全小组提供FTP空间





[此贴被 黄勇刚(hyg0817) 在 01月13日00时06分 编辑过]

B2层 发表时间: 13-01-11 22:42

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号