함수 호출과 스택 구조 2 편입니다.


이번에는 함수를 한줄 한줄 넘어가면서 어떻게 스택이 생성되며

r5(프레임 포인터 레지스터, 인텔계열-ebp)

r6(스택포인터-sp, 인텔계열 - esp) 가 어떻게 변하는지 보겠습니다.



1. 먼저 main 함수가 시작될때 그림입니다.

R5 와 R6가 100으로 초기화 됩니다.

별다른 설명이 없어도 되겠죠?

아 그리고 코드 실행 위치가 1(라인) 이 됩니다.

코드실행 위치를 저장하는 레지스터가 R7(pc 라고도 합니다 program counter)입니다.

위에서는 R7 = 1 이겠군요.


R5(프레임포인터) = 100

R6(스택포인터) = 100

R7(프로그램카운터) = 1


2. main 함수 2라인 - m1 지역 변수 할당



일단 R6 가 가르키는 곳에 변수 m1를 할당합니다.

그리고 R6를 1 감소 시킵니다.


R6 = R6 -1;


R5 = 100

R6 = 99 (100 -1)

R7 = 2




3. main 함수 3라인 - m2 지역 변수 할당


또 다시 R6 가 가르키는 곳에 변수 m2를 할당합니다.

그리고 R6를 1 감소 시킵니다.


R5 = 100

R6= 98 (99 -1)

R7 = 3





4. A 함수 호출 9라인 - A함수 호출



여기가 조금 중요한 곳입니다. 일단 몇가지를 생략했다는걸 알아 주시기 바랍니다.


함수가 바뀌므로

R5를 R6가 가르키는 것으로 대입시킵니다.


R5 = R6(98) --> R5 = 98

R6 = 98

R7 = 9






5. A 함수 10라인~12 - 지역 변수 a1, a2 할당








6. A 함수 종료 1


여기서  A함수가 종료 됩니다.

R6(스택 포인터)를 R5값인 98로 바꿉니다

R6 = R5(98)


R5 = 98

R6 = R5(98) --> R6 = 98

R7 = 13




7. A 함수 종료 2



이제 main 함수 5라인으로 복귀합니다.

여기서 다시 R5 = 100으로 바꾸고

R7를 5로 바꿉니다.


R5 = 100(?)

R6 = 98

R7 = 5(?)



****** 중요

여기서 의문인점이 생깁니다.

도대체 main 함수의 스택 위치100은 어디에서 왔으며(어디에 저장되어 있나?)

다음 실행라인(pc, R7)5라인은 어디에서 왔을까요?(어디에 저장되어 있나?)

이것은 다음 게시물에서 다루겠으며 어디에 저장할지 추측해 보세요.



7. 지역 변수 m1 에 값 1을 대입하기



이제 R5(프레임 포인터)는 도대체 언제 쓰이는지 알아 볼 단계가 왔습니다.


지역 변수 m1에 1을 할당하려고 합니다.


m1 = 1;


그러면 m1 주소인 100번지에 값을 1을 넣으면 되겠지요.

하지만 위의 main() 함수니까 그나마 주소값이 고정 되어 있을지도 모르지만

A() 함수 값은 함수는 main()에 호출할수도 있고 또한 여기에 없는 또다른 함수에서 호출 할수도 있습니다. 여기서는 2번째에 호출되었지만 3, 4번째로 호출 할수 있으므로 주소가 수시로 바뀔수 있습니다.


그래서 지역변수를 접근할때  R5(프레임 포인터)가 사용됩니다.

R6(스택 포인터)는 값을 넣을때마다 수시로 변경이 되기 때문에

해당 함수가 끝나기 전까지 바뀌지 않는 R5를 사용하게 됩니다.


변수 m1는 100번지이지만

R5로 만들어 보면 R5 - 0(100-0) 값이 됩니다.

이런식으로 m2도 R5 - 1(100-1) 99가 됩니다.


그러므로 C언어로 한다면

m1 = 1; 은

(int*)(R5 - 0) = 1; --> (int*)(100) = 1;


m2 = 2; 는

(int*)(R5 - 1) = 2; --> (int*)(99) = 2;


또한 함수가 종료 될때 R6(스택 포인터)를 초기화 할때도 쓰입니다.(6. A 함수 종료 1 참고)


지역 변수는 해당 함수가 실행될때만 살아 있으므로 이는 R5를 사용하기에 알맞습니다.



그럼 다음 게시물에서  위에 빨간 글씨로 쓰인 뜻을 알아 보도록 하겠습니다.





마지막으로  지금까지의 강좌 gif 이미지



+ Recent posts