匯編語言、與C語言、實現--漢諾塔--
imwtr
匯編語言、與C語言、實現--漢諾塔--
題意描述:
用匯編語言實現漢諾塔。只需要顯示移盤次序,不必顯示所移盤的大小,例如: 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開始的,別搞錯了。