PROGRAMMING/MFC(C++)

[0414수업] CallConvention(__cdecl, __stdcall, __fastcall)

마마필로 2011. 4. 14. 01:02

1.대화상자기반 프로젝트 CallConvention 만들기

 

2. 도구상자이용 버튼 3개 추가한 후, 세 개 버튼 각각 속성에서 캡션 수정

Button1 →  __cdecl 방식 호출규약

Button2 → __stdcall 방식의 호출규약

Button3 → __fastcall방식의 호출규약

 

3. 각 버튼을 더블클릭하여 CallConventionDlg.cpp에 메시지 처리 함수 3개를 만들어 준다.

더블클릭하면 자동으로 아래와 같이 코드가 추가됨.

void CCallConventionDlg::OnBnClickedButton1()
{
 // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
}

 

void CCallConventionDlg::OnBnClickedButton2()
{
 // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
}

 

void CCallConventionDlg::OnBnClickedButton3()
{
 // TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
}

 

4. 함수 만들고(세 개의 이벤트 처리기 위에 각각 만들어 준다) 호출하기

CallConventionDlg.cpp에 AddValue(), AddValue2(), AddValue3() 세 개의 함수를 만들었음

이벤트 처리기 안에서 각 함수를 호출해 준다.

함수이름 앞에서 호출방식을 결정해 준다.

AddValue는 __cdecl Addvalue, Addvalue2는 __stdcall AddValue2, Addvalue3는 __fastcall AddValue3와 같이.

 

<작성코드>

void __cdecl AddValue(int nA, int nB, int* pnResult)
{
     *pnResult = nA + nB;
}
void CCallConventionDlg::OnBnClickedButton1()
{
     int nResult=0;
     AddValue(10, 20, &nResult);
     // 호출하는 측에서, 메모리 스택에 있는 값 해제를 담당한다
}


int __stdcall AddValue2(int nA, int nB)
{
     // 실제 함수에서 메모리 스택을 해제한 뒤 반환한다
     return nA+nB;
}
void CCallConventionDlg::OnBnClickedButton2()
{
     int nResult=0;
     nResult=AddValue2(10,20);
}

 

int __fastcall AddValue3(int nA, int nB, int nC, int nD, int nE)
{
     return nA+nB+nC+nD+nE;
}
void CCallConventionDlg::OnBnClickedButton3()
{
     int nResult=0;
     nResult=AddValue3(1,2,3,4,5);
}

 

*함수 호출 규약을 붙이지 않고 쓰는 경우는 실제 __cdecl이 생략되어 있는 것이다.

굳이 호출규약을 붙여 주는 이유??

 

호출규약은 호출부가 아닌 실제 구현부에서 결정해 줌.

인자가 2개(3개?)일때 가장 빠름. 기본적으로 2개(3개?)까지 레지스터에 들어가고 나머지는 레지스터 공간에서 대기함

(디버깅하여 디스어셈블리에서 확인 가능. edx, ecx등은 레지스터 공간의 이름)

이와같이 함수의 호출규약을 결정하는 행위를 CallConvention이라 함