C Calling Convention

C 2019. 12. 23. 01:03 Posted by Vispera

함수 호출 규약(Calling Convention)

쓰레드마다 스택 생성

함수마다 스택 프레임 생성

모든 함수는 main 함수에서 호출됨

 

4가지 기준

1) 매개변수 전달 방법: 스택 프레임 or 레지스터

2) 매개변수 전달 순서: 오른쪽 -> 왼쪽 or 왼쪽 -> 오른쪽

3) 함수 리턴값 전달 방법: 어떤 레지스터에 저장

4) 함수 호출 간 사용했던 스택 프레임 정리하는 방법: caller가 정리 or callee가 정리

 

1. __cdecl

C언어에서 만든 함수 호출 규약

1) 스택 프레임

2) 오른쪽 -> 왼쪽

3)

- 리턴값이 4 바이트 이하: eax

- 리턴값이 8 바이트 이하: 상위 4 바이트는 edx & 하위 4 바이트는 eax

- 리턴값이 8 바이트 초과: 저장안함

4) caller & 정리 코드: add esp, (전체 매개변수 크기)

c언어는 매개변수가 가변적일 수 있다.

그래서 callee에서 일정한 정리 방식을 정하기 어렵다.

caller에서 callee의 매개변수에 대한 정보를 얻은 상태이므로

caller가 정리하게 한다. callee가 정리하는 것보다 느리지만 가변인자 함수이므로 caller가 스택 프레임을 정리한다.

5) Name decoration: _(함수 이름)

 

2. __stdcall

윈도우에서 사용하는 표준 호출 규약, Windows API

1) 스택 프레임

2) 오른쪽 -> 왼쪽

3)

- 리턴값이 4 바이트 이하: eax

- 리턴값이 8 바이트 이하: 상위 4 바이트는 edx & 하위 4 바이트는 eax

- 리턴값이 8 바이트 초과: 저장안함

4) callee & 정리 코드: ret

윈도우 표준 함수는 매개변수가 고정

5) Name decoration: _(함수 이름)@(전체 매개변수 크기)

 

3. __fastcall

윈도우 커널 일부 함수에서 사용

성능의 극대화를 필요로 할 때 사용

1) 레지스터 + 스택 프레임: ecx + edx + stack frame

2) 오른쪽 -> 왼쪽

3)

- 리턴값이 4 바이트 이하: eax

- 리턴값이 8 바이트 이하: 상위 4 바이트는 edx & 하위 4 바이트는 eax

- 리턴값이 8 바이트 초과: 저장안함

4) callee & 정리 코드: ret

윈도우 표준 함수는 매개변수가 고정

5) Name decoration: @(함수 이름)@(전체 매개변수 크기)

 

(+)

메인 함수와 개발자가 만든 함수들은 callee saved register를 백업 (ebx, esi, edi, ebp)

시스템 함수는 caller saved register를 백업 (eax, ecx, edx)

함수들간의 레지스터 사용의 충돌을 피하기 위함 > 데이터 무결성 유지

'C' 카테고리의 다른 글

(C언어로 C++ 흉내내기 2) OOP-2  (0) 2020.01.28
(C언어로 C++ 흉내내기 1) OOP-1  (0) 2020.01.28
CentOS7 게스트 확장 설정  (0) 2020.01.28
(Vim) vimrc 설정  (0) 2020.01.28
C 혈압 측정기  (0) 2019.11.26