CIL 어셈블리 언어

스택 포인터와 프로시저

3.8) 스택 포인터와 프로시저

방금 스택 포인터 변수 sp는 프로시저와도 관계가 있다고 했다정확히 어떤 관계일까이를 이해하기 위해 먼저 스택 메모리가 왜 스택 메모리인지부터 알아야겠다이를 위해 먼저 스택 메모리에 관한 명령을 보이겠다.

- PUSH(param): param 값을 스택 메모리에 푸시 한다.

- POP(param): 스택 메모리에서 팝 한 값을 param에 저장한다.

이전까지 우리는 PUSH를 함수를 호출하기 위해 값을 인자로 전달할 때 사용하는 명령으로 알고 있었다하지만 위에서 말했듯 실제로 PUSH는 스택 메모리에 값을 푸시 하는 역할을 하는데이것이 어떤 식으로 수행되는지를 알아보자다음은 이를 설명하기 위한 예제 코드다.

PushPop.c

#include "CIL.h"

 

// main

PROC(main)

 

PUSH(10)

PUSH(20)

PUSH(30)

POP(a)

POP(b)

POP(c)

 

ENDP

별도로 주석을 달지 않았지만스택을 이해하고 있는 여러분이라면 전혀 어렵다고 느끼지 않았을 것이다먼저main 프로시저가 호출되면 다음 상태가 된다.

10을 푸시 한다.

20을 푸시 한다.

30을 푸시 한다.

팝 한 값을 a에 저장한다.

팝 한 값을 b에 저장한다.

팝 한 값을 c에 저장한다.

그림으로 보면 아주 간단한데혹시 스택 포인터의 움직임을 자세히 보았는가그렇다면 이것이 왼쪽 방향으로 향하는 배열 기반의 스택임을 알 수 있을 것이다우리가 앞으로 구현할 컴파일러는 메모리를 바이트 배열로 생각하고스택 영역은 위와 같이 배열 스택으로 간주한다위 과정에 익숙해져야 앞으로 프로젝트를 진행할 수 있다.

이제 지역 변수와 스택 메모리 사이의 관계를 이해했으니 다음을 보자다음은 10을 출력하는 단순한 프로그램의 코드다.

SpProc.c

#include "CIL.h"

 

// main

PROC(main)

 

// get_sum2(10, 20)을 호출합니다.

PUSH(20)

PUSH(10)

INVOKE(get_sum2)

 

// 반환된 값을 출력합니다.

PUSH(a)

INVOKE(print_int)

 

ENDP

 

// get_sum2

PROC(get_sum2)

 

// d에 두 번째 인자의 값을 대입합니다.

GETL(d, m+bp+12)

// a에 첫 번째 인자의 값을 대입합니다.

GETL(a, m+bp+8)

// a += d;

ADD(a, d)

// 함수 종료 시에는 a의 값이 항상 반환됩니다.

// return a;

RETURN()

 

ENDP

참고로 꽤 길다프로시저가 호출되면 다음 상태가 된다.

 

인자를 스택에 모두 푸시하고 프로시저를 호출한다.

 

 

기본적으로 프로시저를 호출하면프로시저가 종료되었을 때 어느 위치부터 프로그램을 다시 실행해야 하는가즉 다음 명령의 주소 값을 넣어야 한다또한프로시저 시작 시에 새롭게 스택의 시작 지점이 정의되도록 bp 기본 변수의 값을 수정해야 한다일단 복귀 주소로 어떻게 돌아가는지에 대해서는 지금 설명하지 않겠다다음은get_sum2 프로시저 내부에서 일어나는 루틴이다.

 

 

이 과정이 모두 끝나면 RETURN 명령을 이용해 get_sum2 프로시저를 호출한 main 프로시저로 복귀해야 한다.

먼저 마지막으로 스택에 들어간 원소에서 팝 연산을 수행하여 bp를 스택의 복귀 주소로 맞춘다그 다음 다시 팝 연산을 수행하여 복귀 주소를 획득하고 해당 주소로 점프한다따라서 팝 연산을 2번 수행하므로 sp는 4바이트 * 2 = 8바이트만큼 이동하게 된다.

나머지는 반환 값을 출력하는 부분에 대한 것이며위의 그림을 이해하는 데 도움이 될 것이다.

 

 

 

 

이와 같이 INVOKE 매크로와 RETURN 매크로로 프로시저를 호출하고 원래 주소로 복귀하는 방법을 알아보았다.다만 완전히 설명이 끝난 것은 아닌데지금은 너무 많은 내용을 배웠으므로 단원을 잘라서 한 번 심호흡을 한 다음에 학습을 계속하자.

 

 

 

 

이제 심호흡이 끝났을 테니 다음으로 넘어갈 수 있겠다.

댓글

댓글 본문
graphittie 자세히 보기