질문과 답변

그래서 자세히 적은 질문 날짜:2020-3-4 10:05:18 조회수:95
작성자 : Air
포인트 : 83
가입일 : 2020-02-15 17:44:18
방문횟수 : 21
글 13개, 댓글 9개
소개 :
작성글 보기
쪽지 보내기
만약
int a()
{
cout<<"함수 호출입니다;
}

int main()
{
int b=5;
a();
}
이런 코드가 실행되면 함수가 호출될 때 b는 어떻게 되며, 함수의 호출  과정을 스택 수준이 아닌 코드 수준에 쉽고 대략적인 과정으로 설명해 주십시오.
soen님이 만드신 이 그림
차럼요, 하지만 이 과정은 호출한 함수의 변수들이 어떻게 되는지 설명되자 않아 저에겐 설명이 부족합니다.

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

코딩페인트 3월4일 1:35:36  

https://dakuo.tistory.com/102
여기 한번 봐보시면 어떨까요?
함수 호출과정 내용인데

Air 3월4일 5:51:15  

저는 이 설명보다 쉽게, 코드 수준에서 답변해 달라고 질문해서 취지에 맞지 않습니다.

코딩페인트 3월4일 6:28:15  

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

int main()
{
int b=5;
a()
}
코드 수준에서 말씀해달라는 거면
a함수가 호출될때 b라는 변수는 메인함수에 계속 있겠죠
변수라는게 결국은 메모리를 할당해서 값을 넣어주는거니깐요
a라는 함수를 호출한다고 해서 b가 가지고 있는 값의 메모리 주소를 지우는건 아니잖아요

이것도 원하는 답이 아니시면 저도 모르겠습니다ㅎ...

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

Air 3월5일 11:05:43  

단순히 정의하고 사용만 한다면 어떻게 생각하면 되나요?


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