제8장 제어 II- 프로시저 및 환경 (Procedures and Environments)

Download Report

Transcript 제8장 제어 II- 프로시저 및 환경 (Procedures and Environments)

제8장 제어 II- 프로시저 및 환경
(Procedures and Environments)
8.1 프로시저 정의 및 호출
프로시저란?

프로시저(Procedure)




한 그룹의 계산과정을 추상화하는 메커니즘으로
반환 값 없으며
매개변수나 비지역 변수를 변경한다.
함수(Function)



반환 값이 있으므로
식에 나타날 수 있고
매개변수나 비지역 변수 값 변경은 선택사항
프로시저 선언

명세 혹은 인터페이스(Specification or Interface)


프로시저 이름, 매개변수들의 타입과 이름
반환 타입 (함수의 경우)

몸체(Body)

선언 예
void intswap(int x, int y)
{
int t = x;
x = y;
y = t;
}

호출 예
intswap(a, b);
// 명세
// 몸체
함수 선언

선언 예
int max (int x, int y)
{
return x > y ? x : y;
}

호출 예
max(a, b);
// 명세
// 몸체
사례 연구

C, C++, Java



Ada


오직 함수만 있고
프로시져는 반환 타입이 void 이다.
procedure 와 function를 구분한다.
Modula-2


모두 프로시저이다.
함수는 반환 값이 있는 프로시저이다.
8.2 매개변수 전달
(Parameter Passing)
매개변수 전달

실 매개변수(Actual parameter)



형식 매개변수(Formal parameter)


호출에서 사용된 매개변수로
인자(argument)라고도 한다.
선언에서 사용된 매개변수
매개변수 전달

호출 시에 실 매개변수와 형식 매개변수를 매칭하는 것
매개변수 전달 방법

값 전달(pass by value)

참조 전달(pass by reference)

값-결과 전달(pass by value-result)

이름 전달(pass by name)
값 전달

값 전달 과정




1. 식(expression)인 실 매개변수 값들을 계산한다.
2. 계산된 값들을 대응되는 형식 매개변수에 전달
(복사 혹은 초기화)한다.
3. 몸체를 실행한다.
호출 예



max(10, 2 + 3);
x = 10; y = 5;
return x > y ? x : y;
// 값 전달
// 몸체 실행 및 반환
값 전달의 문제점 ?

intswap(a,b)
참조 전달

참조 전달 방법




형식 매개변수 사용



실 매개변수의 위치(주소)가 계산되어
형식 매개변수에 전달된다.
따라서 실 매개변수는 할당된 위치가 있는 변수이어야 한다.
형식 매개변수를 사용할 때마다 자동적으로 주소 참조
(dereferencing)가 이루어져 실 매개변수를 접근하게 된다.
따라서 형식 매개변수를 변경하면 자동적으로 실 매개변수
가 변경된다.
실 매개변수와 형식 매개변수의 이명(aliasing)
참조 전달 예(C++)

선언
void intswap(int& x, int& y)
{
int t = x;
x = y;
y = t;
}

사용
i = 2;
A[2]= 10;
intswap(i, A[i]);
// 명세
// 몸체
C에서 참조 전달 효과 내기

기본 아이디어


C는 원칙적으로 값 전달만 제공하나 포인터 타입이 있다.
참조전달 효과


주소 참조(dereferencing)


포인터 값(위치/주소)을 명시적으로 전달하여 낼 수 있다.
함수 내에서 주소참조는 프로그래머가 명시적으로 해야 한다.
사실상 프로그래머가 참조전달을 구현한다.
예제

intswap의 C 버전
void intswap(int *px; int *py) {
int t;
t = *px;
*px = *py;
*py = z;
}

사용
int a, b;
intswap(&a, &b);
예제(C++)
int a;
void ack(int& x, int& y)
{
x = 2;
y = 3;
a = 4;
}
...
ack(a, a);
참조 전달의 문제점 ?
값-결과 전달

기본 아이디어

호출할 때


반환할 때



실 매개변수 값은 형식 매개변수에 전달(복사)한다.
형식 매개변수 값을 실 매개변수에 역으로 전달(복사)한다.
copy-in, copy-out이라고도 한다.
참조 전달과 뭐가 다른가 ?
예제
void p(int x, int y)
{
x++;
y++;
}
main()
{
int a = 1;
p(a,a);
…
}
이름 전달

기본 아이디어



방법 1



실 매개변수는 대응 형식 매개변수가 사용될 때까지 계산되지 않고
형식 매개변수가 사용될 때 비로소 계산된다.
방법 2


게으른 계산 !
사용될 때까지 버틴다.
형식 매개변수를 실 매개변수 이름으로 대치하고 실행한다고 생각
할 수 있다.
함수형 언어의 지연 계산(delayed evaluation)에서 사용된다.
예제
int i;
int a[10];
void p(x)
{ i := i + 1;
x := x + 1;
}
main()
{ i := 1;
a[1] := 10;
a[2] := 20;
p(a[i]);
}
이름 전달의 문제점?

intswap(i, a[i]);
사례 연구

Ada





값 전달
참조 전달
Java



값 전달
포인터를 이용한 참조 전달 효과
C++, Pascal, Modula-2


값 전달
값-결과 전달
C


in 매개변수:
in out 매개변수:
기초 타입(primitive type)은 값 전달
객체는 참조 전달
FORTRAN

참조 전달
8.3 블록 구조 언어
Block-Structured Languages
Nested blocks, local variables
 Example
new variables declared in nested blocks
{ int x = 2;
{ int y = 3;
outer
inner
local variable
x
=
y+2;
block
block
global variable
}
}


Storage management
 Enter block: allocate space for variables
 Exits block: some or all space may be deallocated
Examples

Blocks in common languages




{…}
begin … end
let … in … end
Two forms of blocks



C
Algol
ML
In-line blocks
Blocks associated with functions or procedures
Topic:


block-based memory management,
access to local variables, parameters, global vars
Simplified Machine Model
Registers
Code
Data
Stack
Program
Counter
Environment
Pointer
Heap
Memory Mgmt Only

Registers, Code segment, Program counter



Ignore registers
Details of instruction set will not matter
Data Segment



Stack contains data related to block entry/exit
Heap contains data of varying lifetime
Environment pointer points to current stack position


Block entry: add new activation record to stack
Block exit: remove most recent activation record
Some basic concepts

Scope


Region of program text where declaration is visible
Lifetime

Period of time when location is allocated to program
{ int x = … ;
{ int y = … ;
{ int x = … ;
….
};
};
};





Inner declaration of x hides outer one.
Called “hole in scope”
Lifetime of outer x includes time when
inner block is executed
Lifetime  scope
Lines indicate “contour model” of
scope.
In-line Blocks

Activation record



Data structure stored on run-time stack
Contains space for local variables
Example
{ int x=0;
int y=x+1;
{ int z=(x+y)*(x-y);
};
};
Push record with space for x, y
Set values of x, y
Push record for inner block
Set value of z
Pop record for inner block
Pop record for outer block
May need space for variables and intermediate results like (x+y), (x-y)
Activation record for in-line block
Control link

Local variables
Intermediate results


Local variables


Set new control link to point to old
env ptr
Set env ptr to new record
Pop record off stack

Environment
Pointer
pointer to previous record on stack
Push record on stack:

Control link
Intermediate results
Control link
Follow control link of current
record to reset environment pointer
Example
{ int x=0;
int y=x+1;
{ int z=(x+y)*(x-y);
};
Control link
x
0
y
1
};
Control link
Push record with space for x, y
Set values of x, y
Push record for inner block
Set value of z
Pop record for inner block
Pop record for outer block
z
-1
x+y
1
x-y
-1
Environment
Pointer
8.4 프로시저 구현
프로시저 호출에 필요한 사항은?

매개변수 전달 메커니즘

지역 변수 메모리 할당

호출자로의 반환에 필요한 정보 저장

피호출자(callee)에 제어 이전

비지역 변수 접근 메커니즘
프로시저 반환에 필요한 사항

매개변수 전달 메커니즘(copy-out)

지역 변수를 위한 메모리 해제

반환 값 저장

호출자로의 반환
활성 레코드(Activation record)

활성 레코드 역할



프로시저 호출/반환에 필요한
정보를 저장하는 자료 구조
스택 프레임(frame)
활성 레코드 내용






매개변수를 위한 기억공간
지역변수를 위한 기억공간
호출자의 실행 상태 정보
반환 주소
반환 값
동적 링크(제어 링크)

호출자의 활성 레코드
Control link
Return address
Return-result addr
Parameters
Local variables
Intermediate results
Environment
Pointer
활성 레코드 언제 할당하는가?

정적 활성 레코드 할당



자기호출이 없는 초기 FORTRAN
한 프로시저마다 하나씩
동적 활성 레코드 할당


자기호출이 가능한 대부분의 현대 프로그래밍 언어
한 프로시저마다 몇 개가 필요할까?
블록 구조 언어의 특성

리커전 가능


지역변수


한 프로시저가 동시에 여러 번 활성화(호출)될 수 있다.
프로시저가 호출될 때마다 동적으로 할당된다.
비지역 변수

접근을 위해 정적 스코프를 사용한다.
어떤 실행 환경이 필요할까?

실행시간 스택(Runtime stack)


스택-기반 실행 환경
프로시저 호출될 때마다


프로시저가 끝날(반환될) 때마다


새로운 활성 레코드가 생성된다.
그 활성 레코드를 없앤다.
이유는



프로시저의 활성 레코드를 정적으로 할당할 수 없다
프로시저는 자기호출이 가능함으로 끝나기 전에 다시 호출
될 수 있다.
새로운 활성 레코드는 프로시저 시작마다 생성되어야 한다.
활성 레코드 확장

기존의 활성 레코드 내용






매개변수를 위한 기억공간
지역변수를 위한 기억공간
호출자의 실행 상태 정보
반환 주소
반환 값
블록 구조 언어를 위한 확장

동적 링크(제어 링크)


호출자의 활성 레코드
정적 링크(접근 링크)

비지역 변수 접근
Example
Control link

fact(n) = if n<= 1 then 1
else n * fact(n-1)
Return address
Return result address
Parameters
Local variables

Return result address


Intermediate results
location to put fact(n)
Parameter


Environment
Pointer
Function
set to value of n by calling
sequence
Intermediate result

locations to contain value of
fact(n-1)
Function call
fact(k)
Control link
Return-result addr
n
k
fact(n-1)
Environment
Pointer
fact(n) = if n<= 1 then 1
else n * fact(n-1)
Return address omitted; would
be ptr into code segment
fact(3)
Control link
Return-result addr
n
3
fact(n-1)
fact(2)
Control link
Return-result addr
n
2
fact(n-1)
fact(1)
Control link
Return-result addr
n
1
fact(n-1)
Function return
fact(3)
Control link
Return result addr
n
3
fact(n-1)
fact(3)
Control link
Return result addr
n
3
fact(n-1)
2
fact(2)
Control link
Return result addr
n
2
fact(n-1)
1
fact(2)
Control link
Return result addr
n
2
fact(n-1)
1
fact(1)
Control link
Return result addr
n
1
fact(n-1)
fact(n) = if n<= 1 then 1
else n * fact(n-1)
동적 링크와 정적 링크

제어 링크(Control link)



접근 링크(Access link)




동적 링크(Dynamic link)
호출자의 활성레코드(바로 전 활성
레코드)에 대한 포인터
정적 링크(Static link)
비지역변수 접근을 위한 포인터
호출된 프로시저의 바깥 프로시저의
활성 레코드에 대한 포인터
차이점


Control link depends on dynamic
behavior of prog
Access link depends on static
form of program text
Control link
Access link
Return address
Return result addr
Parameters
Local variables
Intermediate results
Environment
Pointer
접근 링크를 이용한 정적 스코프
{ int x=1;
function g(z)
{ return x+z; }
function n( ) {
function f(y)
{ int x = y+1;
return g(y*x)
};
f(3);
}
n();
}
x
n( )
1
control link
access link
f
…
f(3)
control link
access link
y
3
x
4
g(12)
control link
access link
z
12
지역 변수 접근

지역 변수 접근




지역 변수가 사용된다는 것은
이를 선언한 프로시저가 현재 호출 되어 있음을 의미한다.
따라서 ep가 해당 프로시저의 활성 레코드를 가리키고 있다.
지역 변수의 주소


(ep) + offset
프레임 포인터가 가리키는 주소 + 상대위치
비지역 변수 접근

기본 아이디어




접근 체인(access chaining)


비지역 변수를 찾기 위해 접근 링크를 따라간다.
비지역 변수 x의 주소 addr(x)


정적 링크(접근 링크)를 사용한다.
호출된 프로시저의 바로 바깥 프로시저 즉
호출된 프로시저를 선언한 프로시저를 가리킨다.
접근 체인에 의해 도달한 활성 레코드 주소 + 변수 x의 상대 위치
몇 번 접근 링크를 따라 가야 하는가 ?

변수 x를 사용하는 프로시저의 중첩 레벨 – 변수 x를 선언한 프로시
저의 중첩 레벨