Notice
Recent Posts
05-05 17:46
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Today
Total
관리 메뉴

프로그래밍 잡화점

함수의 반환에 대한 고찰 본문

C, C++ 분석 보고서

함수의 반환에 대한 고찰

Luana7 2022. 12. 27. 21:24

오늘은 함수 반환에 대해 간단하게 알아보고자 한다.

 

* 컴파일 옵션은 다음과 같다

gcc -o Main Main.c -O0

 

보통 함수에서 값을 반환하게 되면, eax(32bits), rax(64bits) 레지스터를 사용하게 된다.

그리하여 main에서 int를 반환할때도 eax나 rax에 exit_code를 전달해서 main을 탈출하게 되는데.

 

여기서 한가지 의문이 생기게 된다.

 

그렇다면 구조체 같이 복잡한 구조의 타입을 반환하면 어떻게 될까?

 

 

다음과 같이 한 구조체를 만들고 컴파일을 한 뒤 어셈블리 코드로 뜯어보았다

typedef struct {
    int a, b, c;
} A;

A test() {
    A a = { 1, 2, 3 };
    return a;
}

int main() {
	A a = test();
    return a.a - 1;
}

생각보다 신기한 결과를 내놓았다.

 

 

main에서 먼저 구조체의 크기만큼 스택변수를 할당해준 뒤 해당 스택 변수의 위치를 rcx(ecx)에 담고 함수를 호출하였다.

 

그 뒤 test 함수에서는 받은 rcx의 주소 값을 바탕으로 해당 위치에 구조체의 값을 차례대로 넣었고 eax(rax)에 받았던 주솟값을 다시 돌려주었다.

 

그리하여 마지막 return a.a - 1에서는 main에서 할당해두었던 곳에서 읽어서 반환하는 것을 보였다.

 

우리가 주목해야할 것은 test라는 녀석이 반환한 것이 결국 포인터라는 것이다.

 

eax, rax의 크기에 맞지 않는 반환 타입을 갖는 함수는 그 이전 함수에서 미리 공간을 만들고 메모리 주소를 넘겨주어 값을 반환 받는 방식으로 돌아가는 것 같다.

 

 

이번에는 다음과 같이 main 함수를 고쳐서 뜯어보았다

int main() {
	return test().a - 1;
}

아마도 최적화 옵션을 -O0으로 주어서 그런지 위에와 같은 결과를 보였다.

 

 

정리하자면, 정수 타입의 경우에는 eax, rax에 값을 그대로 넣어서 반환하지만, 구조체와 같은 복합 데이터 형식은 미리 할당한 스택 변수를 통해 값을 주고 받는다고 할 수 있다.

'C, C++ 분석 보고서' 카테고리의 다른 글

struct 반환에 대한 고찰  (2) 2023.04.06
main의 반환형에 관한 고찰 (In C)  (2) 2022.05.04
if에 관한 고찰 (In C)  (0) 2022.03.13
bool과 int의 관계 (In C)  (0) 2022.03.12
for에 관한 작은 고찰 (In C)  (0) 2022.03.11
Comments