윈도우즈 시스템 프로그래밍

윈도우즈 시스템 프로그래밍 10장 - 함수 호출(Procedure Call)에 의한 실행의 이동 / 함수 호출 규약(Calling Convention)

111-000-111 2021. 7. 31. 19:43

 

 

 

 

윈도우즈 시스템 프로그래밍이라는 책과 해당 책의 저자이신 윤성우님의 강의를 통해 공부한 내용을 정리하는 글입니다.

 

 

 

 


 

 

 

 

메모리 구조와 PC(Program Counter)

 

프로세스 메모리 구조

 

Code 영역은 프로그램이 동작하기 위한 코드(컴파일된 명령어의 집합)가 올라가는 공간이다.

Fetch 단계에서 명령어를 코드영역에서 CPU로 가져온다.

CPU로 다음 번에 가져올 명령어의 위치를 pc를 통해 알 수있다.

 

 

 

 

함수 호출과 함수 종료

 

프로그램의 흐름은 pc를 통해서 조정할 수 있다.

pc에 이동해야 할 주소값을 저장하기 전에 반드시 현재 pc 값을 스택에 백업해야 한다.

 

 

 

 

 


 

 

 

함수 호출 규약

 

함수 호출 시 인자를 전달하는 방식과 스택 프레임을 반환하는 방식을 약속해 놓은 것

 

 

 

 

__cdecl, __stdcall + α

 

Windows 시스템 함수 선언에서는 __stdcall을 직접 사용하지 않고, CALLBACK이나 WINAPI라는 이름을 부여해서 함수 특성 파악에 도움을 준다.

프로젝트 속성 창에서 디폴트 함수호출 규약을 지정할 수 있고, 해당 프로젝트에선 이 디폴트 선언을 따른다.

 

디폴트 함수 호출규약 지정

 

 

 

 

 

호출규약의 종류와 의미

 

Segment
word size
Calling
Convention
Parameters
In registers
Parameter order
on stack
Stack
cleanup by
32 bit __cdecl
C Caller
__stdcall
C Function
__fastcall eax, edx C Function
__thiscall ecx C Function
64 bit Windows
(MS, Intel)
rcx/xmm0, C Caller
rcx/xmm1,
r8/xmm3
r9/xmm3,
Linux, BSD
(GNU, Intel)
rdi, rsi, C Caller
rdx, rcx, r8
r9, xmm0-7

 

 

 

__cdecl : C/C++ 디폴트 호출 규약이고 인자 전달 방식은 C 언어 스타일을 따른다. 즉, 오른쪽에 전달되는 인자가 먼저 스택에 쌓이는 방식이다. 반환 시에는 함수를 호출하는 호출자가 스택 프레임을 반환하도록 되어 있다.

 

__stdcall과 __cdecl의 차이점은 스택 프레임을 반환하는 주체이다. __stdcall은 호출된 함수 내에서 스택 프레임을 반환한다.

 

__fastcall은 함수 호출을 빠르게 처리하기 위한 호출규약이다. 위 표에서 Parameters in registers에 해당하는 부분은 전달되는 인자를 저장할 떄 레지스터의 사용 유무를 설명한다. 첫 번째 전달 인자와 두 번째 전달 인자는 ecx, edx를 통해 저장된다. 레지스터를 사용하므로 함수 호출이 빨라진다.

 

64비트 Windows 기반에서는 총 8개의 레지스터를 활용해서 인자를 저장한다. 실제로 레지스터에 저장되는 전달인자의 개수는 4개이다. rcx/xmm0은 첫 번째 전달 인자가 rcx 혹은 xmm0 레지스터에 저장된다는 뜻이다.

 

64비트 기반의 Linux, BSD 계열의 시스템에서는 최대 14개의 인자까지 레지스터를 통해 처리한다.