题意描述:
用汇编语言实现汉诺塔。只需要显示移盘次序,不必显示所移盘的大小,例如: 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文件,打开即有如下执行效果..
============================此为原创文章,转载请注明。谢谢。======================================