동적 체인, 지역 오프셋, 재귀
같은 함수가 세 겹으로 쌓이면, 변수 n은 어느 칸일까?
예제
차례로 부르는 네 함수
이 강의가 따르는 교재의 예제입니다. main이 fun1을, fun1이 fun2를, fun2가 fun3을 부릅니다. 함수마다 매개변수와 지역 변수가 조금씩 다릅니다.
괄호 안이 매개변수, 중괄호 안에서 선언한 것이 지역 변수입니다. float는 소수점 있는 수, int는 정수 타입입니다.
스택의 모습
호출이 깊어질수록 위로 자랍니다
호출할 때마다 인스턴스가 위로 쌓이고, 동적 링크는 자기를 부른 쪽 인스턴스를 가리킵니다. 인스턴스 안의 칸은 아래부터 반환 주소, 동적 링크, 매개변수, 지역 변수 순서입니다.
인스턴스는 호출 한 번의 칸 묶음입니다. 반환 주소 칸의 이름은 돌아갈 함수입니다.
동적 체인
링크를 따라가면 부른 순서가 나옵니다
스택에 있는 동적 링크를 이은 것을 동적 체인(dynamic chain) 또는 호출 체인(call chain)이라고 합니다. 맨 위에서 따라 내려가면 누가 누구를 불렀는지가 거꾸로 나옵니다.
지역 오프셋
EP에서 몇 칸 위인지로 찾습니다
변수는 EP에서 몇 칸 떨어져 있는지로 찾습니다. 이 거리가 지역 오프셋(local offset)입니다. 칸의 순서(활성 레코드의 형식)가 정해져 있어 컴파일러가 실행 전에 미리 압니다.
컴파일러는 소스 코드를 기계어로 번역하는 프로그램입니다. 칸 수는 교재 그림을 센 것입니다.
재귀 예제
자기 자신을 부르는 factorial
교재의 재귀 예제입니다. factorial은 n이 1 이하이면 1을 반환하고, 아니면 n에 factorial(n − 1)을 곱해 반환합니다. 재귀는 함수가 자기 자신을 다시 부르는 것입니다.
C 코드입니다. *는 곱하기, <=는 작거나 같다는 뜻이고, 마지막 줄은 main 안에 있는 문장입니다.
쌓일 때
같은 함수, 서로 다른 인스턴스
factorial이 세 번 불리면 인스턴스도 세 개 쌓입니다. 코드에 적힌 n의 지역 오프셋은 늘 2이고 EP만 바뀌므로, 지금 실행 중인 호출의 n을 짚게 됩니다.
실행 중인 인스턴스만 칸을 펼치고 나머지는 한 줄로 접었습니다. 함수값은 반환할 값을 담는 칸입니다.
걷힐 때
값이 아래로 전해집니다
맨 위 호출부터 끝납니다. 3번째 호출이 1을, 2번째가 2 × 1 = 2를, 1번째가 3 × 2 = 6을 반환합니다. 반환할 때마다 인스턴스가 걷히고 EP는 동적 링크를 따라 내려옵니다.
점선 상자는 값을 넘기고 걷힌 인스턴스입니다. 반환 주소와 동적 링크 칸은 앞 카드에서 봤으므로 뺐습니다.
다음 편