본문 바로가기

KNU_study/마이크로프로세서

마이크로프로세서(17) Stack과 Subroutine

728x90
반응형

 

 

1. Stack

 

Stack : 메모리의 일부분, 프로그램 실행 중에 저장해야 하는 것을 잠시 저장해두는 공간이다. 

-> SP : Stack 번지의 첫주소

    SP를 사용하는 명령어는 LXI가 유일하다. 

프로그램을 짤 때마다 Stack의 양을 계산하는 것은 쉽지 않다. 

-> 그 대신, 메모리의 맨 끝 번지에 저장해두자.

    저절로 감소하면서 저장될 것이다.

    (PC는 1씩 증가하면서 저장되듯이, SP는 2씩 감소하면서 저장된다는 느낌으로 ~~)

 

<LXI SP, 3009H>

사실 3009H 말고, 실수로 <LXI SP 300AH>로 작성해도 오류가 나지 않는다. 아래 알고리즘 참고

Stack : [300AH에 저장] -> [1 감소] -> [3009H에 저장] -> [1 감소]

Stack : [1 감소] -> [3009H에 저장] -> [1 감소] -> [3008H에 저장]

반대 상황의 Stack : [해당 주소에서 뽑고] -> [1 증가] -> 다음 주소에서 뽑고] -> [1 증가]

 

 

<Stack 명령어>

PUSH rp : rp의 data를 SP가 가리키는 주소에서 하나 감소한 주소에 넣고, 또 감소한 곳에 넣어

POP rp : SP가 가리키는 주소에서 data를 하나 rp로 가져와, 1 증가시키고 하나 더 가져와

-> rp로는 PSW(A,F), B, D, H를 사용할 수 있다.

-> 둘다 1byte 명령어이다.

-> PUSH는 o.f + MEMW + MEMW, POP은 o.f + MEMR + MEMR의 machine cycle을 가진다. 

 

PUSH PSW, PUSH D

 

아래는 각각 잘못 짜인 코드와 옮게 짜진 코드다. 

PUSH PSW
PUSH D
...
...
POP PSW // 순서대로 POP되지 않아서 실제로는 D,E가 POP된다.
POP D // 실제로는 PSW가 POP된다.
PUSH PSW
PUSH D
...
...
POP D // D, E가 POP된다.
POP PSW // PSW가 POP된다.

 

<PUSH의 타이밍도>

SP, 즉 Stack을 사용하는 명령어들은 무조건 6T짜리 opcode cycle을 가진다. 

왜냐하면 자동적으로 PC의 값을 1씩 감소시켜가며 명령어를 수행해야 하기 때문이다. (총 2 감소)

 

 

PUSH B의 타이밍도

 

<POP의 타이밍도>

1씩 감소하던 PUSH와 다르게, POP은 1씩 증가이므로 4T opcode cycle로도 충분하다. 

그리고 아마.. D, E에 저렇게 들어가는게 맞을꺼야.. 답을 못들었서 아마 맞겟지..

 

POP D의 타이밍도

 

 

2. Subroutine

 

 

main 함수에서 반복되는 부분을 따로 뽑아 (필요할 때마다) 불러서 쓰는 방식이다. 

main과 반드시 함께 동작해야 한다. 

-> Service routine은 반드시 필요 없으나, Subroutine은 반드시 필요한 개념.

 

<RET에 대한 이야기>

다음 코드를 실행하면 이상하게 동작할 것이다.

CALL 3000H
RET 2001H

해당 코드의 작동 순서, main이 제대로 실행되지 못한다.

 

그 대안으로, CALL 명령어는 자동적으로 [돌아올 주소 번지]를 Stack에 집어넣는다. 

-> 위의 case에서는 2001H를 SP에 집어넣는다. 

 

<CALL 명령어>

JMP : 가서 명령어를 실행 -> 끝남

CALL : subroutine 호출 후 가서 명령어를 실행 -> 끝내고 다시 돌아옴

-> machin cycle : opcode fetch + MEMR + MEMR + MEMW + MEMW

-> 아래 그림은 <CALL 2050H>를 수행한 address bus와 타이밍도다. 

 

2000H : CALL // 1번으로 수행
2001H : 50H // 2번으로 수행
2002H : 20H // 3번으로 수행
2003H : // 6번으로 수행
..
..
2050H : // 4번으로 수행
..
..
2080H : RET // 5번으로 수행

 

<RET 명령어>

위에서 언급한 '돌아옴'의 기능을 수행하기 위한 명령어다. 

-> machin cycle : opcode fetch + MEMR + MEMR

 

 

** RET과 POP 구별하기 !! (stack을 사용하는 유일한.. 명령어들)

POP : 어디갔다 오는거, 2080H - 3000H - 30001H 후에 2081H면 POP

RET : 어디갔다 오는거, 2080H - 3000H - 3001H 후에 2003H?면 RET

-> 뜬금없고, 관련 없는 곳으로 가는 명령어가 RET이다. 

 

 

 

 

 

 

 

728x90
반응형