No older revisions available
No older revisions available
헛소리 ¶
- 음... 어셈블리 언어로 짜니 줄 수가 엄청나게 나오는 군요...
- 그리고 이게 이틀이나 걸린 이유는 전 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 ;프로그램 종료