기본 콘텐츠로 건너뛰기

[C/C++] 함수 호출 규약 ( Calling Conventions)

본 페이지에서는 함수 호출 규약에 대하여 정리하고자 한다. 

먼저 윈도우 프로그램의 정석 마이크로 소프트 문서 페이지의 개요를 이해하기 위해 번역하고,

좀더 구체적인 개념에 대해 정리한다.


마이크로 소프트 문서 번역



출처 https://docs.microsoft.com/en-us/cpp/cpp/calling-conventions?view=vs-2019


Calling Conventions

Visual C/C++ 컴파일러는 내부와 외부 함수을 호출하기 위한 여러가지 다른 규약을 제공한다. 이 차이점을 이해하는 것은 구독자의 프로그램을 디버깅 할 수 있도록 도와주거나 어셈블리 언어 루틴을 포함하는 구독자의 코드를 링크할 수 있도록 도와준다.


이 주제에서 토픽들은 함수 호출 규약의 차이점을 설명한다, 아규먼트들이 어떻게 입력되고 반환값들은 함수에 의해 어떻게 반환되는지 등에 대한 것들. 토픽은 구독자가 자신의 프롤로그 코드와 에필로그 코드를 작성할 수 있게 하는 좀더 향상된 특성인 naked 함수 호출에 대해 설명한다.


x64 프로세서를 위한 함수 호출 규약에 대한 정보는 여기를 참조하라.

# 이 세션의 토픽들

1) 아규먼트 입력과 네이밍 규약 ( __cdecl, __stdcall, __fastcall, and others )

2) 함수 호출 예제: Function  Prototype and Call

3) 커스터머 프롤로그/에필로그 코드를 호출하는 naked 함수 사용하기

4) 플로팅 포인트 코플세서와 함수 호출 규약

5) 예전 함수 호출 규약


아규먼트 입력과 네이밍 규약

MS C++ 컴파일러는 구독자가 함수와 호출자 간의 아규먼트 입력과 반환값을 위한 규약을 정하도록 한다.  - 생략( -  구독자는 ESI, EDI, EBX 레지스터에 저장하고 복구하기 위한 프롤로그와 에필로그 코드를 생성한다. 

구독자 함수의 프롤로크와 에필로그 코드를 정의하는 방법은 Naked Function Calls을 참조하라. x64 플랫폼을 대상으로 하는 기본 함수 호출 규약에 대한 정보는 x64 Calling Convntions를 참고하라. ARM 플랫폼을 대상으로 하는 함수 호출 규약 이슈에 대한 정보는 Common Visual C++ ARM Migration Issues를 참고하라. 

Visual c/C++ 컴파일러가 제공하는 함수 호출 규약은 다음과 같다.


* __cdecl

- C/C++의 기본 호출 규약

- 스택을 정리하는 주체는 Caller

- 가변 인수 함수를 지원한다. ( ex) printf() )

* __sdtcall

- Win32 API에서 사용

- 스택을 정리하는 주체는 Callee

- 가변 인수 함수를 지원하지 않는다.



Naked Function Calls

naked 속성으로 선언된 함수는 인라인 어셈블러를 사용한 구독자의 프롤로그/에필로그 시퀀스를 작성할 수 있는 프롤로그와 에필로그 코드 없이 발생된다. naked 함수는 향상된 특성으로 제공된다. naked 함수는 C/C++ 이외의 컨텍스트로부터 호출되는 함수를 선언할 수 있으므로 파라미터가 어디에 있는지 혹은 어떤 레지스터가 보존되는지에 대한 다양한 가정을 할 수 있다. 예를 들어, 인터럽트 핸들러와 같은 루틴을 포함한다. 이 특성은 가상 디바이스 드라이버의 작업자에게 유용한다. 

- naked 속성으로 선언된 함수에 대해 컴파일러는 프롤로그와 에필로그 코드 없이 코드를 생성한다. 구독자는 인라인 어셈블러 코드를 사용하여 자신의 프롤로그와 에필로그 시퀀스를 작성하기 위해 이 특성을 이용할 수 있다. naked 함수는 특히 가상 디바이스 드라이버를 작성하는데 유용하다. 이것은 x86와 ARM에서 가능하고 x64는 이용할 수 없다.


자료 정리

C는 그렇게 어렵지 않습니다.

에 달린 댓글들 중에서 흥미로운 몇 가지를 링크한다.

- 시계방향 / 나선 규칙, Clockwise/Spiral Rule

- 함수원형과 나선 규칙에 따른 설명 

Prolog / Epilog Code ? ( soen.kr ) 

- 함수가 호출될 때 스택에는 함수로 전달되는 인수, 복귀 번지, 지역 변수 등의 정보들이 저장된다. 스택에 저장되는 함수의 호출 정보를 스택 프레임이라고 한다.

- 함수가 호출되는 과정( 어셈블리어에서 실행되는 시퀀스 )에서 함수 실행전 실행 준비 단계를 프롤로그 코드, 실행 후 정리 단계를 에필로그 코드라고 한다.

※ Static Link, Dynamic Link 

댓글

이 블로그의 인기 게시물

[QT] 5.15.2 버전 다운로드와 설치하기

1. 버전 5.15.2를 설치하기 위해 QT 다운로드 사이트 에 접속하였으나 실행파일이 존재하지 않는다. 가장 최신의 실행파일은 ver5.14.2 이므로 일단 이것을 다운받아서 설치한다. ( 참고 사이트 - https://sloth-code.tistory.com/6#comment16833678 ) 다운 사이트  - https://bio.nic.funet.fi/pub/mirrors/download.qt-project.org/archive/qt/5.14/5.14.2/  ------------- 버전이 맞지 않으니 재 설치한다. 2.  5.15.2 버전에는 실행파일 exe가 없고 zip과 tar.gz 파일만 존재한다. ( https://bio.nic.funet.fi/pub/mirrors/download.qt-project.org/archive/qt/5.15/5.15.2/ ) OFFLINE_README.txt를 읽어보면 5.15 버전부터는 오픈 소스 오프라인 설치를 이용할 수 없다고 한다. 오프라인 설치를 원할 경우 다음 사이트 참조하라고 한다.  ( 원본:  The Qt Company offering changes, open source offline installers are not available any more since Qt 5.15. Read more about offering changes in the https://www.qt.io/blog/qt-offering-changes-2020 blog. If you need offline installers, please consider our new Qt for Small Business offering: https://www.qt.io/blog/available-now-qt-for-small-businesses ) - https://www.qt.io/blog/available-now-qt-for-small-businesses ...

Windows에서 MongoDB 사용하기 요약

NoSQL에 대한 이해 MongoDB에 대한 이해 MongoDB 메뉴얼 MongoDB 다운받기 - Community GUI를 설치하는 대신에 zip 파일선택하여 Shell Window에서 운영. ( mongdb.com ) MongoDB 서버 사용하기 - Command Interpreter Demon으로 실행하기 : 이 방법( --fork 옵션 )은 윈도우에서 실행되지 않고, 대신에 --install 옵션을 사용하여 윈도우 서비스에 등록하여 백그라운드로 사용한다. 관리자 모드 로 명령 프롬프트를 실행한다. demon을 실행시킨다. ( --install 옵션 추가 )   mongod --dbpath D:\Working\MongoDB\Server_JServer\mongodb_ver4.2.1\data --port 13100 --bind_ip_all --auth --logpath   D:\Working\MongoDB\Server_JServer\mongodb_ver4.2.1\log\mongod.log --install 명령 라인에 다음 명령을 입력한다. net start MongoDB 윈도우 서비스 창을 열어서 아래 내용을 확인한다. 배치 파일로 자동 실행하기 Demon으로 실행하는 방법의 2번과 3번을 한번에 처리하기 위해 생성한 mdbexe.bat 을 사용한다.  방법 mongodb demon을 실행하기 위한 mongod.cfg configuration 파일을 만든다. 배치 파일에 mongod 커멘드와 옵션을 다음과 같이 기술한다. mongod --config filename --install 배치 파일에 MongDB 서비스를 윈도우 서비스에 등록한다. net start MongoDB 만들어진 배치 파일을 관리자모드 로 실행시킨다. C#에서 구현할 때 관리자 모드로 실행하는 방법 조사할 것. ( TODO ) 종...

[ ChatGPT ] 임의의 프로세스에 접근하여 임의의 변수값을 바꾸기 위한 방법

 질문 사항 1번 프로세스와 2번 프로세스가 있어. 1번이 운영중인데, 2번 프로세스에서 1번 프로세스의 임의의 메모리에 접근하여 그 메모리의 값을 바꾸고 싶어. 어떤 절차를 이용해야 하지? 답변 내용 1번 프로세스의 메모리에 2번 프로세스에서 접근하여 값을 변경하는 것은 매우 민감한 작업이며, 운영 체제에서는 일반적으로 이러한 작업을 보안과 안정성 때문에 제한합니다. 그러나 특수한 경우, 특히 시스템 프로그래밍이나 디버깅 목적으로는 특정 API를 사용하여 이러한 작업을 수행할 수 있습니다. 아래는 이러한 작업을 수행하기 위한 일반적인 절차를 설명합니다. 1. 프로세스 권한 확인 및 확보 2번 프로세스가 1번 프로세스의 메모리에 접근하려면 충분한 권한이 있어야 합니다. 일반적으로 이는 관리자 권한이나 루트 권한이 필요합니다. Windows에서는 SeDebugPrivilege 를 활성화해야 할 수 있으며, Linux에서는 루트 권한이 필요할 수 있습니다. 2. 1번 프로세스의 핸들 획득 2번 프로세스가 1번 프로세스의 메모리에 접근하려면 먼저 1번 프로세스의 핸들을 얻어야 합니다. Windows : OpenProcess 함수를 사용하여 1번 프로세스의 핸들을 얻습니다. 이 함수는 1번 프로세스의 프로세스 ID를 기반으로 접근합니다.