汇编语言、与C语言、实现--汉诺塔--

时间:2022-11-25 10:15:07

题意描述:  

   用汇编语言实现汉诺塔。只需要显示移盘次序,不必显示所移盘的大小,例如: X>Z,X>Y,Z>Y,X>Z,....。

(n阶Hanoi塔问题)假设有三个分别命名为X、Y、Z的塔座,在塔座X上插有n个直径大小各不相同、依小到大编号为1,2,…,n的圆盘。现要求将X轴上的n个圆盘移至塔座Z上并仍按同样顺序叠排,圆盘移动时必须遵循下列规则:

1)每次只能移动一个圆盘;

2)圆盘可以插在X、Y、Z中的任一塔座上;

3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。

 

汉诺塔的实现,用C语言来解释就是函数递归调用实现

如果转为汇编实现,就直接进入栈进行相应的操作就行(当然你也可以用汇编语言宏实现高级的递归调用..)

C语言方式:

void move(char one,char three){    //one 移到thre

printf(
"%c--->%c",one,three);

}

void HANOI(int n,char one,char two,char three){

if(n==1){ //如果只有一个圆盘,直接将这个圆盘从one移到three

move(one,three);
}

else{ //如果大于一个圆盘

HANOI(n
-1,one,three,two); //首先将n-1个从one经过three移到two上,此时one上剩最大的一个圆盘

move(one,three);
//将最大的圆盘从one移到three上

HANOI(n
-1,two,one,three); //之后将n-1个从two经过one移到three上,完成。

}

} // end of void

HANOI(
5,'X','Y','Z'); //即可5阶汉诺塔从X盘移到Z盘

递归操作仔细想想就可以了,这样栈的操作逐渐明朗,你就可以用汇编语言实现它了(通过bp栈指针的运算进栈push出栈pop就可以实现相应递归调用)。

汇编代码实现如下:

  1 DATA    SEGMENT
2 n db ?
3 msg db 0dh,0ah,'Enter the number you want : $'
4 msg1 db 0dh,0ah,'HANOI-MOVE Procedure with : $',0ah,0dh
5 to db '--->$'
6 count dw 0 ; 5个一组输出显示
7 DATA ENDS
8
9 CODE SEGMENT
10 ASSUME CS:CODE,DS:DATA
11 START:
12 MOV AX,DATA
13 MOV DS,AX
14
15 LEA DX,msg
16 CALL intro
17 KEYIN:
18 MOV AH,01H ;字符输入并回显
19 INT 21H
20 MOV byte ptr[n],Al ;接收键入的n值
21
22 LEA DX,msg1
23 CALL intro
24 MOV DL,0ah
25 CALL DISPLAY
26
27 MOV AL,byte ptr[n]
28 SUB AL,30H
29 CBW
30 MOV DX,AX
31 MOV AX,'X'
32 MOV BX,'Y'
33 MOV CX,'Z'
34 ;MOV DX,[n]
35
36 PUSH DX
37 PUSH CX
38 PUSH BX
39 PUSH AX
40
41 CALL HANOI_MOVE
42 ADD SP,8
43
44 MOV DL,0ah
45 CALL DISPLAY
46 LEA DX,msg
47 CALL intro
48 JMP KEYIN
49
50 GroupMake:
51 INC [count]
52 MOV AX,[count]
53 MOV BL,5 ;5 个一组
54 DIV BL
55 CMP AH,0
56 JNE SPACE
57 MOV DL,0ah
58 CALL DISPLAY ;输出换行
59 JMP CLOSE
60 SPACE:
61 MOV DX,20H
62 CALL DISPLAY ;输出空格
63 CLOSE:
64 RET
65
66 STEP: ;输出步骤号
67 MOV AX,[count] ;防止count多位数不正确输出--hexTOdec
68 MOV CX,0
69 MOV BX,10
70 DISP1:
71 MOV DX,0
72 DIV BX
73 PUSH DX
74 INC CX
75 OR AX,AX
76 JNZ DISP1
77
78 MOV DL,5BH ; 输出显示[
79 CALL DISPLAY
80 DISP2:
81 POP DX
82 ADD DL,30H ; 输出显示对应十进制
83 CALL DISPLAY
84 LOOP DISP2
85
86 MOV DL,5DH ; 输出显示]
87 CALL DISPLAY
88 RET
89
90 intro proc near ;提示语
91 MOV AH,09H
92 INT 21H
93 ret
94 intro endp
95
96 DISPLAY proc near ;输出字符
97 MOV AH,02H
98 INT 21H
99 RET
100 DISPLAY endp
101
102 HANOI_MOVE proc near
103 MOV BP,SP
104 MOV AX,[BP+8]
105 CMP AX,1
106 JG moreThanOne ;n 不等于1则跳转
107 CALL STEP
108 MOV DX,[BP+2] ;取第一个值
109 CALL DISPLAY
110 LEA DX,to
111 CALL intro
112 MOV DX,[BP+6] ;取第三个值
113 CALL DISPLAY
114 CALL GroupMake
115
116 RET
117
118
119 moreThanOne:
120 MOV AX,[BP+2]
121 MOV BX,[BP+4]
122 MOV CX,[BP+6]
123 MOV DX,[BP+8]
124 DEC DX ;n-1
125 PUSH DX
126 PUSH BX
127 PUSH CX
128 PUSH AX
129 CALL HANOI_MOVE ;递归一次,进行下一循环
130 ADD SP,8
131
132 MOV BP,SP
133 CALL STEP
134 MOV DX,[BP+2] ;取第一个值
135 CALL DISPLAY
136 LEA DX,to
137 CALL intro
138 MOV DX,[BP+6] ;取第三个值
139 CALL DISPLAY
140 CALL GroupMake
141
142 MOV AX,[BP+2]
143 MOV BX,[BP+4]
144 MOV CX,[BP+6]
145 MOV DX,[BP+8]
146 DEC DX ;n-1
147 PUSH DX
148 PUSH CX
149 PUSH AX
150 PUSH BX
151 CALL HANOI_MOVE ;递归一次,进行下一循环
152 ADD SP,8
153
154 RET
155 HANOI_MOVE endp
156
157 EXIT: MOV AH,4CH ;退出系统
158 INT 21H
159 CODE ENDS
160 END START

耐心看看就行了,不是很难,栈的第一个参数是从bp+2开始的,别搞错了。
此为MASM语言格式汇编程序,链接成功后生成相应exe文件,打开即有如下执行效果..

汇编语言、与C语言、实现--汉诺塔--

汇编语言、与C语言、实现--汉诺塔--

汇编语言、与C语言、实现--汉诺塔--

汇编语言、与C语言、实现--汉诺塔--

============================此为原创文章,转载请注明。谢谢。======================================