;汇编实验四 HANOI塔谜题
;采用栈传递参数,n表示搬动个数。第一次调用时栈的情况为: (输入的数),one,two,three,IP,ax,dx,bp
;在子程序hanoi中[bp+14]每次和1比较,相等则跳出
;不相等则把[bp+14]中的数减1,再进行递归。
;子函数AscToBin用来把字符转换成数字保存在 Bin中,在增加盘子的移动数目时用了BCD码对chNum中的最后一个字符进行加一
;并用指令AAA把它转换成0~9之间,如果高位ha为1的话(表示有进位),则dec si,继续操作
;
;
.model small,stdcall
.stack 64
.data
Bin dw 0 ;保存用户输入的大小
chNum db 10 dup(‘0′),’$’ ;保存移动盘子的个数
one dw ‘A’ ;符号
two dw ‘B’
three dw ‘C’
strShow db ‘->$’
chLine db 0dh,0ah,’$’ ;换行
prompt db ‘Please input the plate num(1~99): $’ ;提示
chTimes1 db 0dh,0ah,’I have moved $’
chTimes2 db ‘ times’,0dh,0ah,’$’
InputList LABEL BYTE ;用户输入的大小,用AscToBin转换成数字保存在Bin中
MaxLen db 3 ;最多两位(1~99)
ActLen db 0
chInput db 3 dup(‘0′),’$’
multFact dw 1
.code
;main
;———————————————————————————————
main PROC
mov ax,@data
mov ds,ax
;show prompt
loopAgain:
lea dx,prompt
mov ah,09h
int 21h
;input the num
lea dx,InputList
mov ah,0Ah
int 21h
call AscToBin
mov ax,1
cmp ax,Bin
ja loopAgain
mov ax,99
cmp Bin,ax
ja loopAgain
push Bin
push one
push two
push three
;change line
lea dx,chLine
mov ah,09h
int 21h
call hanoi
;显示总共移动次数
lea dx,chTimes1
mov ah,09h
int 21h
mov cx,0010
lea si,chNum
showNum:
cmp BYTE PTR [si],’0′
je notAdd
add BYTE PTR [si],48
notAdd:
inc si
loop showNum
lea dx,chNum
mov ah,09h
int 21h
lea dx,chTimes2
mov ah,09h
int 21h
;重新初始化,一直循环直到按下回车
mov Bin,0
mov ActLen,0
mov [chInput],’0′
mov [chInput+1],’0′
mov cx,0010
lea si,chNum
put0:
mov BYTE PTR [si],’0′
inc si
loop put0
jmp loopAgain
loopEnd:
mov ah,4ch
int 21h
main ENDP
;从ASCII到数字
;—————————————————————————————————————–
AscToBin proc
push ax
push cx
cmp ActLen,0
je loopEnd
cmp ActLen,1
je L2
jmp L3
L2:
xor ah,ah
mov al,[chInput]
sub al,48
add Bin,ax
jmp out1
L3:
xor ah,ah
mov al,[chInput+1]
sub al,48
add Bin,ax
mov al,[chInput]
sub al,48
mov cl,10
mul cl
add Bin,ax
out1:
pop cx
pop ax
ret
AscToBin endp
;func hanoi
;————————————————————————————————————-
hanoi proc
push ax
push dx
push bp
mov bp,sp
mov ax,1
cmp ax,WORD ptr [bp+14]
je equal
jmp unequal
equal:
;show 类似A->C
lea si,chNum+10
loopNum0:
xor ah,ah
dec si
mov al,[si]
add al,1
aaa
mov [si],al
cmp ah,1
je loopNum0
mov dx,WORD ptr [bp+12]
mov ah,2
int 21h
lea dx,strShow
mov ah,09h
int 21h
mov dx,WORD ptr [bp+8]
mov ah,02h
int 21h
lea dx,chLine
mov ah,09h
int 21h
jmp exit
;不相等则递归
unequal:
mov ax,[bp+14]
sub ax,1
push ax
push [bp+12]
push [bp+8]
push [bp+10]
call hanoi
;show
lea si,chNum+10
loopNum1:
xor ah,ah
dec si
mov al,[si]
add al,1
aaa
mov [si],al
cmp ah,1
je loopNum1
mov dx,WORD ptr [bp+12]
mov ah,2
int 21h
lea dx,strShow
mov ah,09h
int 21h
mov dx,WORD ptr [bp+8]
mov ah,02h
int 21h
lea dx,chLine
mov ah,09h
int 21h
;再次递归
mov ax,[bp+14]
sub ax,1
push ax
push [bp+10]
push [bp+12]
push [bp+8]
call hanoi
exit: pop bp
pop dx
pop ax
ret 8
hanoi endp
end main