打印水仙花数(汇编)

这里水仙花数指严格意义上的水仙花数,即若一个数满足这个数等于它的百位数、十位数、个位数的立方和,那么这个数是水仙花数。

一、设计要求

具体的设计任务及要求:

  1. 输入一个三位整数n;
  2. 将小于n的水仙花数打印出来(各位数字的立方和等于该数本身);
  3. 程序采用子程序结构或宏指令,结构清晰;
  4. 友好清晰的用户界面,能识别输入错误并控制错误的修改。

二、功能简述

​ 程序可以输入一个三位数,若输入有误则提示错误,并提示重新输入,若输入正确,系统将显示出所有大于等于100,并且小于等于输入数字的水仙花数。

​ 然后提示是否继续,若用户输入y或Y,则系统回到最开始的状态,若输入n或N,则退出系统,若为其他则提示错误,并重新输入。

三、模块说明

子程序名功能基本实现
GET_INPUT获取键盘输入三位数字通过INT 21H号中断获取键盘输入
INPUT_CHECK输入检测,判断是否为数字通过两次比较,第一次与‘0’比较,判断是否不小于,第二次与‘9’比较,判断是否不大于,都满足则ok
JUDGE_lOW_BORDER判断输入数字是否是大于100的CMP与0进行比较判断即可
INPUT_ERROR输入错误处理模块输出错误信息,同时自增CX,让循环仍然能够获取三位数字,在继续循环
INPUT_RIGHT输入正确处理模块存储输入数字,循环继续
CONTINUE循环继续通过LOOP S2来使循环得到三位数字,同时输出三位数字以检测模块是否正确执行
SWITCH_INPUT输入转换,即将输入字符转换为一个二进制数字将输入数字减去’0’即可获取输入数字(字符),的二进制(原因:ASCII码),再讲位数乘上10或者100
SWITCH_NUM_SYS进制转换及存储将当前循环中的数字转化为三个数存储,如123转化为1, 2, 3分别存储,用于后面计算水仙花数
CAL_CUBE计算水仙花立方将存储的三个数字分别计算立方并相加
JUDGE_NARC_NUM判断水仙花数,是则显示通过CMP指令比较数字或者立方和是否相等,相等则显示
IF_CONTINUE一轮之后是否继续通过获取键盘输入判断
CONTINUE_CHECK是否继续输入判断通过CMP指令,让输入字符与 y,Y,n,N比较并跳转到相应模块
CONTINUE_NEXT_ROUND继续下一轮跳转到START
CONTINUE_ERROR继续下一轮判断的时候输入错误显示输入错误信息,并JMP到IF_CONTINUE继续输入模块
STOP输入n退出通过MOV AX, 4C00H 和INT 21H结束程序

四、测试用例

  • 测试结果说明:

    (1) 输入789 ,输出水仙花数407, 371, 370, 153

    (2) 输入y,程序继续,重新输入上限数值

    (3) 输入367,输出水仙花数 153

    (4) 输入y,程序继续,重新输入上限数值

    (5) 输入067,程序发现其输入数字小于100,提示输入数字太小,重新输入

    (6) 输入a,提示输入错误重新输入数值

    (7) 输入 371,输出水仙花数 371,370,153

    (8) 输入N,退出程序

  • 测试结果:

代码如下:

COMMENT /**
Copyright <2018> <Zhao Nan>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

USERNAME: Zhao Nan
COMPLETE TIME: 2018-1-4
DESCRIBE: Print the number of daffodils between 100 and n(the number you input)
*/
.386
ASSUME CS:CODES, DS:DATA, SS:STACK
DATA SEGMENT  USE16
    MSG1   DB    0AH, 0DH, 'The shuixianhuashu is : $'           ;0AH, 0DH 代表换行和回车
    MSG2   DB    0AH, 0DH, 'Please input a three-digit number: ', '$'
    MSG3   DB    0AH, 0DH, 'Input Error, Please the number again:', '$'
    MSG4   DB    0AH, 0DH, 'The three-digit number is: ', '$'
    MSG5   DB    0AH, 0DH, 'Do you want to continue(y or Y/n or N): ', '$'
    MSG6   DB    0AH, 0DH, 'Input Error, Please input again:', '$'
    MSG7   DB    0AH, 0DH, 'The number you input is too little.$'
    NUMS   DB    3 DUP(0), 0AH, 0DH, '$'    ; 存储三位数字,后续中可以存储当前的三位数字,如:循环到了456,则分别存储4,5,6
    CUBES  DW    3 DUP(0)                   ; 存储立方数字,分别是 百位,十位,个位数字的立方
DATA ENDS

STACK SEGMENT USE16 STACK
    DB   100 DUP(0)
STACK ENDS


CODES SEGMENT USE16        ;使用 16位
;------------------------main-----------------------------
START:
    CALL  GET_INPUT        ;获取键盘输入
    CALL  JUDGE_lOW_BORDER ;判断输入数字是否是大于100的
    CALL  SWITCH_INPUT     ;输入转换存在 CX 中,CX控制循环
    SUB   CX, 100          ;不能输出100以下,所以这里减100,注意后面使用的时候加100或者用其他操作
LOOP1:
  CALL  SWITCH_NUM_SYS   ;将二进制转化为三个数字到 NUMS[0] NUMS[1] NUMS[2] 中
    CALL  CAL_CUBE         ;求水仙花立方
    JMP   JUDGE_NARC_NUM   ;判断水仙花数,是则显示
NEXT:
    LOOP  LOOP1            ;循环到 0为止
    JMP NEAR PTR IF_CONTINUE
    MOV   AX, 4C00H        ;程序终止
    INT   21H
;---------------------------------------------------------

;---------------------------------------------------------
;判断是否为水仙花数
JUDGE_NARC_NUM:
    MOV   AX, CUBES[0]
    ADD   AX, CUBES[2]
    ADD   AX, CUBES[4]
    SUB   AX, 100          ;由于不能输出100,注意
    CMP   AX, CX
    JNE   NEXT
    JE    DISPLAY          ;相等则显示


;显示水仙花数
DISPLAY:
    LEA   DX, MSG1         ;显示水仙花数
    MOV   AH, 09H
    INT   21H
    MOV   AH, 2

    MOV   DL, NUMS[0]      ;百位数字
    ADD   DL, 30H          ;转换为数字显示, ASCII加上 48 即为字符
    INT   21H
    MOV   DL, NUMS[1]      ;十位数字
    ADD   DL, 30H
    INT   21H
    MOV   DL, NUMS[2]      ;个位数字
    ADD   DL, 30H

    INT   21H
    JMP   NEXT


;键盘输入
GET_INPUT:
    MOV   CX, 3            ;三次输入数字
  MOV   AX, DATA
    MOV   DS, AX
    MOV   BX, 0            ;输入次数

  LEA   DX, MSG2         ;显示提示输入
  MOV   AH, 09H
    INT   21H

LOOP2:
  MOV    AH, 01H          ;从键盘输入一个字符, 其ASCII存放在 AL 中
    INT   21H

  JMP   INPUT_CHECK      ;输入检测判断


;输入检测
INPUT_CHECK:
  CMP   AL, '0'
  JB    INPUT_ERROR      ;输入ASCII码小于 0 输入错误
  CMP   AL, '9'
  JA    INPUT_ERROR      ;输入ASCII码大于 9 输入错误
  JNA   INPUT_RIGHT      ;否则输入正确


;输入错误
INPUT_ERROR:
  LEA   DX, MSG3         ;输出错误的信息模板
    MOV   AH, 09H
    INT   21H

    ;INC   CX
    MOV   CX, 4
    MOV   BX, 0
    JMP   CONTINUE


;输入正确
INPUT_RIGHT:
  MOV   NUMS[BX], AL     ;存储输入
    INC   BX
    JMP   CONTINUE         ;继续循环


;继续
CONTINUE:
  LOOP  LOOP2

    LEA   DX, MSG4         ;输出正确的数字
    MOV   AH, 09H
    INT   21H
    LEA   DX, NUMS
    MOV   AH, 09H
    INT   21H

  RET                    ;返回主程序,RET从堆栈中取出 IP

;-----------------------------------------------------

; 判断输入数字是否是大于100的
JUDGE_lOW_BORDER:
    CMP   NUMS[0], '0'
    JE    NUM_IS_LIttle
    RET

;输入数字太小
NUM_IS_LIttle:
    LEA   DX, MSG7
    MOV   AH, 09H
    INT   21H
    JMP   START

;输入转换存在  CX 中,CX控制循环
SWITCH_INPUT:
  MOV   CX, 0
  MOV   CL, NUMS[2]
    SUB   CL, '0'
  MOV   AL, 10
    MOV   BL, NUMS[1]
    SUB   BL, '0'
  MUL   BL
  ADD   CX, AX
  MOV   AL, 100
    MOV   BL, NUMS[0]
    SUB   BL, '0'
  MUL   BL
  ADD   CX, AX
  RET


;----------------------------------------------------------
;进制转换存在 NUMS[0], NUMS[1], NUMS[2] 中
SWITCH_NUM_SYS:
  MOV   AX, CX
    ADD   AX, 100
    MOV   BL, 100
    DIV   BL                    ;AL=百位数, AH=余数
    MOV   NUMS[0], AL           ;百位数字
    MOV   AL, AH
    MOV   AH, 0
    MOV   BL, 10
    DIV   BL
    MOV   NUMS[1], AL           ;十位数字
    MOV   NUMS[2], AH           ;个位数字
  RET


;求水仙花立方
CAL_CUBE:
    MOV   AL, NUMS[0]           ;三次连乘即可
    MOV   AH, 0
    MOV   BX, AX
    MUL   BX
    MUL   BX
    MOV   CUBES[0], AX

    MOV   AL, NUMS[1]
    MOV   AH, 0
    MOV   BX, AX
    MUL   BX
    MUL   BX
    MOV   CUBES[2], AX

    MOV   AL, NUMS[2]
    MOV   AH, 0
    MOV   BX, AX
    MUL   BX
    MUL   BX
    MOV   CUBES[4], AX
    RET

;-----------------------------------------------------------------

;-----------------------------------------------------------------
;输出水仙花数之后的判断是否继续
IF_CONTINUE:
    LEA   DX, MSG5        ;显示提示输入
    MOV   AH, 09H
    INT   21H
    MOV   AH, 01H         ;从键盘输入一个字符, 其ASCII存放在 AL 中
    INT   21H

    JMP CONTINUE_CHECK

;是否继续输入判断
CONTINUE_CHECK:           ;判断是否输入的是 y, Y, n, N
    CMP   AL, 'y'
    JE    CONTINUE_NEXT_ROUND
    CMP   AL, 'Y'
    JE    CONTINUE_NEXT_ROUND
    CMP   AL, 'n'
    JE    STOP
    CMP   AL, 'N'
    JE    STOP
    JNE   CONTINUE_ERROR

;继续
CONTINUE_NEXT_ROUND:
    JMP  NEAR PTR START


;退出
STOP:
    MOV   AX, 4C00H       ;程序终止
    INT   21H


;继续输入错误
CONTINUE_ERROR:
    LEA   DX, MSG6        ;输出错误的信息模板
    MOV   AH, 09H
    INT   21H
    JMP   IF_CONTINUE

;----------------------------------------------------

CODES ENDS
    END START

复制代码

参考教材:王爽的《汇编语言》

转载于:https://juejin.im/post/5a630db9f265da3e38499665

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值