함수 호출 약속

최근 에 어 셈 블 리 와 관련 된 것 을 연구 하 다가 어 셈 블 리 에서 함수 호출 약속 을 보고 기록 했다.
cdecl x86 시스템 구조의 많은 C 컴 파일 러 가 사용 하 는 기본 호출 약속 은 C 호출 약속 (c declaration) 이 라 고 합 니 다.cdecl 호출 약정 규정: 호출 자가 오른쪽 에서 왼쪽 순서 로 함수 파 라미 터 를 창고 에 넣 고 호출 된 함수 가 작업 을 완성 할 때 호출 자가 창고 에서 파 라미 터 를 제거 하 는 것 을 책임 집 니 다.오른쪽 에서 왼쪽으로 스 택 에 파 라 메 터 를 넣 은 결 과 는 함수 가 호출 되면 가장 왼쪽 (첫 번 째) 파 라 메 터 는 항상 스 택 꼭대기 에 있 습 니 다.이렇게 하면 이 함수 가 몇 개의 매개 변 수 를 필요 로 하 든 우 리 는 첫 번 째 매개 변 수 를 쉽게 찾 을 수 있다.따라서 cdecl 호출 약속 은 인자 의 수량 이 변 하 는 함수 (예 를 들 어 printf) 에 매우 적합 합 니 다.호출 함수 가 스 택 에서 파 라 메 터 를 삭제 하 라 고 요구 하 는 것 은 자주 볼 수 있 음 을 의미 합 니 다. 명령 은 호출 된 함수 에서 돌아 온 후에 바로 프로그램 스 택 지침 을 조정 합 니 다.만약 함수 가 수량 가 변 적 인 파 라 메 터 를 받 아들 일 수 있다 면 호출 자 는 이러한 조정 에 매우 적합 합 니 다. 함수 에 몇 개의 파 라 메 터 를 전달 하 는 지 잘 알 기 때문에 정확 한 조정 을 쉽게 할 수 있 습 니 다.호출 된 함 수 는 자신 이 몇 개의 인 자 를 받 을 지 미리 알 수 없 기 때문에 스 택 에 필요 한 조정 을 하기 어렵다.예 를 들 어 우 리 는 다음 과 같은 원형 을 가 진 함 수 를 호출 합 니 다.
void demo_cdecl(int w, int x, int y, int z);

기본 적 인 상황 에서 이 함 수 는 cdecl 호출 약속 을 사용 하고 오른쪽 에서 왼쪽 순서 로 4 개의 인 자 를 누 르 고 호출 자 에 게 스 택 의 인 자 를 제거 하 라 고 요구 합 니 다.컴 파 일 러 는 이 함수 의 호출 을 위해 다음 코드 를 생 성 할 수 있 습 니 다.
; demo_cdecl(1, 2, 3, 4);
push     4                    ;  push parameter z
push     3                    ;  push parameter y
push     2                    ;  push parameter x
push     1                    ;  push parameter w
call     demo_cdecl           ;  call the function
add      esp, 16              ;     esp,               

함 수 를 호출 할 때 스 택 포인터 가 가장 왼쪽 에 있 는 인 자 를 가리 킵 니 다.
stdcall 이라는 약속 은 함수 성명 에 수식 자 를 사 용 했 습 니 다stdcall, 다음 과 같 습 니 다.
void _stdcall demo_stdcall(int w, int x, int y);

cdecl 호출 약속 과 마찬가지 로 stdcall 호출 약속 은 오른쪽 에서 왼쪽 순서 로 함수 파 라 메 터 를 프로그램 스 택 에 놓 습 니 다.stdcall 호출 약속 을 사용 하 는 차이 점 은 함수 가 실 행 될 때 호출 된 함수 가 스 택 의 함수 인 자 를 삭제 해 야 한 다 는 것 입 니 다.호출 된 함수 에 있어 서 이 작업 을 완성 하려 면 스 택 에 몇 개의 인자 가 있 는 지 알 아야 합 니 다. 이것 은 함수 가 받 아들 인 매개 변수 수량 이 고정 되 어 있 을 때 만 가능 합 니 다.따라서 printf 와 같은 수량 가 변 적 인 매개 변 수 를 받 아들 이 는 함 수 는 stdcall 호출 약속 을 사용 할 수 없습니다.예 를 들 어 demostdcall 함 수 는 3 개의 정수 매개 변수 가 필요 합 니 다. 스 택 에서 모두 12 개의 바이트 (32 비트 시스템 구조 상 3 * sizeof (int) 의 공간 을 차지 합 니 다.x86 컴 파 일 러 는 RET 명령 의 특수 한 형식 을 사용 할 수 있 으 며, 동시에 창고 꼭대기 에서 주 소 를 추출 하고, 창고 지침 에 12 를 더 해서 함수 파 라미 터 를 제거 할 수 있다.demo_stdcall 은 다음 명령 을 사용 하여 호출 자 에 게 돌아 갈 수 있 습 니 다.
ret 12  ;  return and clear 12 bytes from the stack

stdcall 을 사용 하 는 주요 장점 은 매번 함수 가 호출 된 후에 코드 를 통 해 스 택 에서 파 라 메 터 를 제거 하지 않 아 도 되 기 때문에 부피 가 작고 속도 가 빠 른 프로그램 을 생 성 할 수 있다 는 것 이다.
fastcall fastcall 약속 은 stdcall 이 약속 한 변형 입 니 다. CPU 레지스터 (프로그램 스 택 이 아 닌) 에 최대 두 개의 인 자 를 전달 합 니 다.Microsoft Visual C / C + + 와 GNU gcc / g + (3.4 및 더 낮은 버 전) 컴 파일 러 는 함수 성명 의 fastcall 수식 자 를 식별 할 수 있 습 니 다.fastcall 약속 을 사용 하면 함수 에 전달 되 는 앞의 두 매개 변 수 는 각각 ECX 와 EDX 레지스터 에 있 습 니 다.나머지 인 자 는 stdcall 약속 과 유사 한 방식 으로 오른쪽 에서 왼쪽으로 스 택 에 넣 습 니 다.마찬가지 로 stdcall 약속 과 유사 한 것 은 호출 자 에 게 돌아 갈 때 fastcall 함수 가 스 택 에서 파 라 메 터 를 삭제 하 는 것 입 니 다.다음 성명 에 서 는 fastcall 수식 자 를 사 용 했 습 니 다:
void fastcall demo_fastcall(int w, int x, int y, int z);

demo 호출 을 위 한fastcall, 컴 파일 러 는 다음 코드 를 생 성 할 수 있 습 니 다.
; demo_fastcall(1, 2, 3, 4);
push     4                    ;  move parameter z to the second position on stack
push     3                    ;  move parameter y to the top position on stack
mov      edx, 2               ;  move parameter x to edx
mov      ecx, 1               ;  move parameter w to ecx
call     demo_fastcall        ;  call the function

주의, demo 호출fastcall 이 돌아 온 후, 스 택 을 조정 할 필요 가 없습니다. demo 때 문 입 니 다.fastcall 은 호출 자 에 게 돌아 갈 때 스 택 에서 인자 y 와 z 를 제거 하 는 것 을 책임 집 니 다.두 개의 매개 변수 가 레지스터 에 전달 되 기 때문에 호출 된 함 수 는 스 택 에서 8 바이트 만 제거 해 야 합 니 다. 이 함수 가 4 개의 매개 변 수 를 가지 고 있 더 라 도 이 점 을 이해 하 는 것 이 중요 합 니 다.

좋은 웹페이지 즐겨찾기