헛소리

  • 음... 어셈블리 언어로 짜니 줄 수가 엄청나게 나오는 군요...
  • 그리고 이게 이틀이나 걸린 이유는 전 push를 하면 각 변수 별로 스택이 있는 줄 알아서 pop의 순서가 상관이 없다고 생각했는데, 그게 아니라 스택은 하나라서 push의 반대 순서로 pop을 해야 하는 것이더군요.

코드

~cpp 
;하노이의 탑
.model small
.stack 100h

.data
message1 db "have move ", '$'
message2 db "th disk from ", '$'
message3 db "to ", '$'
n dw 5			;disk의 갯수
from dw 1		;시작 기둥(1번)
by dw 2			;중간 기둥(2번)
to dw 3			;목적지 기둥(3번)	

.code
extrn Crlf:proc
extrn Writeint:proc

main proc
	mov ax, @data
	mov ds, ax
	mov bx, 10	;Writeint사용시에 10진수 출력

	call Move	;Move함수 호출
			;Move(from, to, by)
	mov ax, 4C00h	;종료
	int 21h
main endp

Move proc		;Move 프로시저(재귀호출되는 부분)
	cmp n, 0	;n=0이면
	jz endmove	;Move 프로시저의 끝으로 감
	
	push n		;n값을 스택에 넣음
	dec n		;n-1

	push from	;from을 스택에 넣음
	push by		;by를 스택에 넣음
	push to		;to를 스택에 넣음
	
	mov ax, by	;by와 to의 위치를 바꿔줌.(ax를 temp로 사용)
	mov si, to	;메모리 간의 대입이 안 되므로
	mov by, si	;si를 이용해 대입
	mov to, ax

	call Move	;Move(n-1, from, by, to)
			;(by와 to의 위치를 바꿔서 함수 호출)
	pop to		;다시 to, by, from, n을 순서대로 꺼냄
	pop by		;스택이므로 빼는 순서에 유의해야 한다
	pop from		
	pop n
	
	mov ah, 9	;message1을 출력
	mov dx, offset message1
	int 21h
	
	mov ax, n	;몇번째 디스크를 옮기는지 출력
	call Writeint
	
	mov dx, offset message2
	mov ah, 9	;message2를 출력
	int 21h

	mov ax, from	;옮기는 시작점 출력
	call Writeint
	call Space	;한칸 띄고

	mov dx, offset message3
	mov ah, 9	;message3을 출력
	int 21h

	mov ax, to	;목적지 출력
	call Writeint

	call Crlf	;줄바꿈

	push n		;n을 다시 스택에 넣고
	dec n		;n-1

	push from	;from, by, to를 차례로 스택에 넣음
	push by
	push to

	mov ax, from	;from과 by를 바꿈(ax를 temp로 하여)
	mov si, by	;메모리 간 대입 허용 안 하므로
	mov from, si	;si를 이용해서 대입
	mov by, ax
	
	call Move	;Move(by, to, from) 호출 
	
	pop to		;to, by, from, n순으로 스택에서 뺌
	pop by
	pop from	
	pop n

	endmove:	
	ret		;프로시저 끝
Move endp

Space proc		;띄어쓰기 함수
	mov dl, " "
	mov ah, 2
	int 21h		;빈칸을 출력
	ret
Space endp

end main		;프로그램 종료

작성자: Yggdrasil

Retrieved from http://wiki.zeropage.org/wiki.php/HanoiProblem/영동
last modified 2021-02-07 05:23:21