您的位置:首页 > 编程语言

80x86 汇编语言编程:显示一个螺旋数据方阵

2016-01-25 12:11 726 查看
;微机原理课程设计题目:

;根据键盘输入的一个数字,显示相应的数据螺旋方阵。

;如输入 4,则显示:

; 1   2   3   4
;12  13  14   5
;11  16  15   6
;10   9   8   7

;共需要显示 4 * 4 = 16 个数字。

;要求:根据键盘输入的数字(2~15),显示相应的数据方阵。

;题目链接:http://zhidao.baidu.com/question/128743688.html

;这是 2009 年的题目,已经有了正确的答案。

;但是,答案中的程序,竟有 370 行 !有些太夸张了吧 !

;做而论道实在也没有耐心往下看,自己编了编,也就用了大约一半的篇幅,就实现了相同的功能。

;=========================================================
ASSUME    CS:CC, DS:QWER
;-------------------------------------
QWER  SEGMENT
    MSG1   DB  13, 10, 'This program can generate a clockwise spiral matrix of order N.'
           DB  13, 10, 'If you type 4, the matrix of order 4 will appear : '
    CRLF   DB  13, 10, 36
    MSG2   DB  13, 10, 'Please input a number(2~15): $'
    MSG9   DB  13, 10, 13, 10, 'Press any key to continue...$', 36 
;--------------------------------
    BUF    DB  15 * 15  DUP(?)   ;定义15阶矩阵空间
    HH     DB  8                 ;实际矩阵阶数(待输入)
;--------------------------------
    BUF3   DB  1, 2, 3, 4, 12,13,14, 5, 11,16,15, 6, 10, 9, 8, 7 ;样例矩阵
    HH3    DB  4                 ;4阶
;--------------------------------
    NN     DB  1       ;从1开始填充
    DIR_X  DB  1       ;1横向填充0竖向填充
    DIR_H  DB  1       ;1递增填充0递减填充行
    DIR_L  DB  1       ;1递增填充0递减填充列
    N_H    DB  ?
    N_L    DB  ?
    N_H2   DB  ?
    N_L2   DB  ?
QWER  ENDS
;-------------------------------------
CC  SEGMENT 
START:
    MOV   AX, QWER
    MOV   DS, AX
    LEA   DX, MSG1
    MOV   AH, 9
    INT   21H
    CALL  CR_LF
    MOV   SI, OFFSET BUF3 ;显示样例矩阵
    MOV   CH, HH3
    CALL  DISP_MATRIX
    LEA   DX, MSG2
    MOV   AH, 9
    INT   21H
    MOV   HH, 0
    MOV   CX, 2
IN_X:
    MOV   AH, 7
    INT   21H
    CMP   AL, 13
    JZ    IN_END
    CMP   AL, '0'
    JB    IN_X
    CMP   AL, '9'
    JA    IN_X
    MOV   DL, AL
    MOV   AH, 2
    INT   21H
    MOV   AL, DL
    AND   AL, 15
    XCHG  AL, HH
    MOV   BL, 10
    MUL   BL
    ADD   HH, AL
    LOOP  IN_X
IN_END:
    CMP   HH, 2
    JB    EXIT
    CMP   HH, 15
    JA    EXIT
    CALL  CR_LF
    CALL  CR_LF
;----------------------------
    MOV   AL, HH       ;矩阵阶数
    MOV   N_H, AL      ;行数
    DEC   AL
    MOV   N_H2, AL     ;行数
    MOV   N_L, AL      ;列数
    MOV   N_L2, AL     ;列数
    MOV   BX, 0        ;每行中序号
    MOV   DI, 0        ;每列中序号
    MOV   NN, 1        ;从1开始填充
LOOPS:
    MOV   AL, NN       ;取出数字
    MOV   BUF[BX][DI], AL  ;填入矩阵
    TEST  DIR_X, 1
    JZ    LX
    CALL  HH_HH        ;行(横向)序号BX变化,加减1
    JMP   NEXT
LX:
    CALL  LL_LL        ;列(竖向)序号DI变化,加减阶数
NEXT:
    INC   NN           ;下一个数字
    MOV   AL, HH
    MUL   HH           ;矩阵阶数的平方
    CMP   AL, NN
    JNC   LOOPS        ;大于等于当前数字则循环
;----------------------------
    MOV   SI, OFFSET BUF   ;显示结果矩阵
    MOV   CH, HH
    CALL  DISP_MATRIX
EXIT:
    MOV   AX, 4C00H    ;退出程序
    INT   21H
;---------------------------------------------
HH_HH:                 ;修改行序号
    TEST  DIR_H, 1
    JZ    HH_SUB1
HH_ADD1:               ;行序号递增
    INC   BX
    JMP   HH_NEXT
HH_SUB1:               ;行序号递减
    DEC   BX
HH_NEXT:
    DEC   N_H2
    CMP   N_H2, 0
    JNZ   E_HH
    DEC   N_H
    MOV   AL, N_H
    MOV   N_H2, AL
    INC   DIR_H
    INC   DIR_X
E_HH:
    RET
;---------------------------------------------
LL_LL:                 ;修改列序号
    TEST  DIR_L, 1
    JZ    LL_SUB1
LL_ADD1:               ;列序号递增
    MOV   AL, HH
    MOV   AH, 0
    ADD   DI, AX
    JMP   LL_NEXT
LL_SUB1:               ;列序号递减
    MOV   AL, HH
    MOV   AH, 0
    SUB   DI, AX
LL_NEXT:
    DEC   N_L2
    CMP   N_L2, 0
    JNZ   E_LL
    DEC   N_L
    MOV   AL, N_L
    MOV   N_L2, AL
    INC   DIR_L
    INC   DIR_X
E_LL:
    RET
;---------------------------------------------
DISP_MATRIX:           ;显示矩阵
    MOV   NN, CH
DP0:MOV   CL, CH
DP1:MOV   AL, [SI]
    CALL  DISP3
    INC   SI
    DEC   CL
    CMP   CL, 0
    JNZ   DP1
    CALL  CR_LF
    DEC   NN
    CMP   NN, 0
    JNZ   DP0
    RET
;---------------------------------------------
DISP3:                 ;显示矩阵中的数字
    MOV   AH, 0
    MOV   BL, 100
    DIV   BL
    ADD   AL, 30H
    MOV   DL, AL       ;百位
    MOV   AL, AH       ;十位个位
    MOV   AH, 0
    MOV   BL, 10
    DIV   BL
    ADD   AX, 3030H
    MOV   BX, AX
    MOV   AH, 2
    CMP   DL, '0'
    JNZ   D_ALL
    MOV   DL, ' '      ;消除无效零
    INT   21H
    CMP   BL, '0'
    JNZ   D_SG
    MOV   BL, ' '      ;消除无效零
    JMP   D_SG
D_ALL:
    INT   21H
D_SG:
    MOV   DL, BL       ;显示十位数
    INT   21H
    MOV   DL, BH       ;显示个位数
    MOV   AH, 2
    INT   21H
    MOV   DL, ' '      ;显示空格
    INT   21H
    RET
;---------------------------------------------
CR_LF:                 ;回车_换行
    LEA   DX, CRLF
    MOV   AH, 9
    INT   21H
    RET
;---------------------------------------------
CC  ENDS
    END   START
;=========================================================

在汇编语言程序里面定义 N 阶方阵,和定义数组没有什么两样。

在样例矩阵中已经看到,其中的元素都是顺序排列成一条直线:

    BUF3   DB  1, 2, 3, 4, 12,13,14, 5, 11,16,15, 6, 10, 9, 8, 7 ;样例矩阵

此时,是看不出来“螺旋”的,但是,按照 4 行 4 列显示的时候,效果可就不同了:

  1,  2,  3,  4
 12, 13, 14,  5
 11, 16, 15,  6
 10,  9,  8,  7

把 1~16 这 16 个数,依次填入数组,填充的位置,是怎么变化呢?

填充的位置,开始是:第 0 位,以后是:第 1、第 2、第 3,依次是加 1。
然后是向下走,填充的位置,分别是:第 7、第 11、第 15,依次是加 4。
然后是向左走,填充的位置,依次是减 1。
然后是向上走,填充的位置,依次是减 4。

呵呵,如果看不出来,就仔细看看样例矩阵吧。

加一、加四、减一、减四,反复执行这四步,确定目的位置后再进行填充。

那么,每一步,要加(或者减)多少次呢?这可是本题目的关键。

总结这些个规律,实际上是中小学的数学问题。

呵呵,详细地就不说了。看样例矩阵,就能找出答案。

找到了规律,再用语言,以最简单的形式把规律表述出来,让计算机能够理解执行,这可就不是很容易做到的。

用 C 语言编程,比较简单,编写程序比较方便。

用汇编语言编程,就复杂多了。
但是,追求就能高一些,不仅要逻辑正确,还要使程序代码简短一些、运行的速度快一些。

网上的 370 行程序,功能虽正确,可是,不知道在什么地方,写得有些过于罗嗦了。

;=========================================================

本程序执行时的人机交互界面如下:

c:\masm510>mm

This program can generate a clockwise spiral matrix of order N.
If you type 4, the matrix of order 4 will appear :

  1   2   3   4
 12  13  14   5
 11  16  15   6
 10   9   8   7

Please input a number(2~15): 6

  1   2   3   4   5   6
 20  21  22  23  24   7
 19  32  33  34  25   8
 18  31  36  35  26   9
 17  30  29  28  27  10
 16  15  14  13  12  11

c:\masm510>mm

This program can generate a clockwise spiral matrix of order N.
If you type 4, the matrix of order 4 will appear :

  1   2   3   4
 12  13  14   5
 11  16  15   6
 10   9   8   7

Please input a number(2~15): 10

  1   2   3   4   5   6   7   8   9  10
 36  37  38  39  40  41  42  43  44  11
 35  64  65  66  67  68  69  70  45  12
 34  63  84  85  86  87  88  71  46  13
 33  62  83  96  97  98  89  72  47  14
 32  61  82  95 100  99  90  73  48  15
 31  60  81  94  93  92  91  74  49  16
 30  59  80  79  78  77  76  75  50  17
 29  58  57  56  55  54  53  52  51  18
 28  27  26  25  24  23  22  21  20  19

c:\masm510>

;=========================================================

欢迎转载,但是希望注明来源。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: