질문과 답변

soen님의 답변에 대한 질문 날짜:2020-3-5 11:15:13 조회수:161
작성자 : Air
포인트 : 88
가입일 : 2020-02-15 17:44:18
방문횟수 : 22
글 14개, 댓글 9개
소개 :
작성글 보기
쪽지 보내기
소엔 3월4일 9:31:14  답글 
함수 호출 관련 규칙을 호출 규약(Calling Convention)이라고 합니다. 관련 내용은 어셈블리 수준까지 메모리를 들여다 봐야 해서 좀 어렵습니다만 이 사이트 C/C++ 강좌의 16-1절에 자세하게 설명되어 있으니 다음에 차근히 읽어 보십시오.
함수의 호출 기록은 스택 프레임이라는 곳이 차곡 차곡 저장됩니다. 예를 드신 코드에서 a 함수에 인수와 지역 변수가 없는데 설명의 편의상 a가 int c를 인수로 받고 int d 지역 변수를 선언했다고 합시다. 이런 모습이겠죠.

int a(int c)
{
 int d;
 count << "함수 호출입니다";
}

main이 처음 호출되면 스택 프레임에는 지역 변수 b만 생성되어 있습니다.

main의 지역 변수 b

이 상태에서 main은 지역 변수 b를 자유롭게 액세스할 수 있습니다. 이 상태에서 a 함수를 호출하면 main의 스택 프레임은 그대로 유지한 채로 그 위에 a 함수의 스택 프레임이 생성됩니다. 먼저 인수가 들어가고 이어서 main으로의 복귀 번지, main의 기준 번지, 그리고 자신의 지역 변수 영역이 생성됩니다.

a의 지역 변수 d
main의 기준 번지(ebp)
main으로 복귀할 번지
a로 전달할 인수 c
main의 지역 변수 b

이 상태에서 a 함수는 자신의 인수와 지역 변수를 자유롭게 액세스합니다. main의 지역 변수 b는 a에서 읽을 수 없으며 그 값을 그대로 유지만 합니다. 만약  a가 또 다른 함수를 호출한다면 그 위에 스택 프레임이 또 생성됩니다. 이런 식으로 스택 영역을 다 쓸 때까지 함수를 호출할 수 있어 호출 횟수의 제약은 거의 없습니다.
a가 실행을 마치고 main으로 복귀하면 지역와 인수는 모두 정리되고 복귀 번지를 찾아 리턴하며 main의 기준 번지를 복구해 줍니다. 그러면 스택 프레임은 다음과 같이 되겠죠.

main의 지역 변수 b

a를 호출하기 전의 상태 그대로 돌아갑니다. 이때 a의 모든 지역 변수는 사라지고 없습니다. 그래서 지역 변수는 함수 내부에서만 유효하며 함수 호출이 끝나면 같이 사라지는 것입니다. main의 지역 변수 b는 그대로 남아 있으며 main은 이 변수를 계속 사용할 수 있습니다.
main에서 Dog(int v) { int n, m; ....} 을 호출하고 Dog에서 Add(int a, int b) { int c, d, e; ....)을 호출하면 스택 프레임은 다음과 같이 변합니다. 호출을 마치고 돌아오면 원래대로 깜쪽같이 복구되고요.



이런 식으로 동작하는 호출 규약을 _cdecl이라고 하며 C언어의 기본 호출 규약입니다. 즉 별다른 지정이 없으면 함수는 위와 같은 절차대로 호출 및 정리됩니다. 그 외에도 다른 방식으로 동작하는 호출 규약이 많이 있는데 인수를 전달하는 순서, 스택을 정리할 주체, 함수에 이름을 붙이는 방법이 각각 다릅니다.
함수를 단순히 정의하고 사용만 하겠다면 굳이 몰라도 되는 내용이니다. 그러나 가변 인수 같은 고급 기법을 쓴다거나 다른 호출 규약을 사용하는 언어와 링크하려면 이런 내용도 알아야 합니다.
soen님의 답변입니다.

단순히 정의하고 사용만 한다면 어떻게 함수 호출을 생각하면 되나요?
제 질문입니다.
 

목록보기 삭제 수정 신고 스크랩

Program 3월5일 12:38:59  

함수호출 규약부분에서 호출하면 변수가 스택프레임에 저장되고 어쩌고 ...
예전에 읽어 보았는데 좀 신기하고 정교하다는 느낌을 받았습니다.
당시는 어느정도 이해했지만 나로써는 깊이 들어가기 보다는 그냥 필요하면 함수를 호출하고
사용후 결과를 얻고 반환하고 이정도로 이해하고 넘어감니다.

또한 스택프레임뿐만 아니라 많은 경우에 있어서 한정된 메모리(램?)를 여러가지 요청에 의해
사용되어지기 위해서 운영체제가 알아서 적당히 메모리내용을 잠시 옮겨놓고 우선순위 앞부터
처리하고 다시 옮겨놓은 부분을 가져오고 하므로
나는 이렇게 이해하고 내가 프로그래밍할 부분만 관심을 가집니다 

단순희 정의하고 사용만 한다면 어떻게 함수호출을 생각하면 되나요?
이 질문의 답은 나로서는 쉽게 생각하면 된다고 생각하는데
글쎄요 어떨지 또는 무슨 말인지 그렇습니다.

Air 3월5일 6:00:28  

저도 그렇게 이해하고 싶기는 한데 그런 설명에서 함수를 호출한 함수의 변수는 어떻게 되는지가 궁금합니다.

코딩페인트 3월5일 12:58:50  

미리 만들어놓은걸 제목만 써서 사용한다고 생각하세요


로그인하셔야 댓글을 달 수 있습니다.