티스토리 뷰
우선 WINDEF.H를 보면 다음을 알 수 있다.
CALLBACK = WINAPI = PASCAL = __stdcall
WINAPIV = __cdecl
즉 window에서의 calling convention은 크게 __stdcall과 __cdecl로 생각할 수 있다.
그럼 __stdcall과 __cdecl의 공통점과 차이점을 살펴보자.
공통점은 함수의 인자를 스택에 쌓을 때 오른쪽에서부터 왼쪽으로 쌓기 때문에 가장
첫번째 인자가 스택의 맨 위로 올라온다.
차이점은 __stdcall은 호출된 함수, 즉 __stdcall로 정의된 함수 내부에서 스택이
청소되고 __cdecl은 호출한 함수에서 스택을 정리하여 준다. __cdecl의 이러한 특징
때문에 __cdecl로 정의된 함수는 가변 인자를 지원할 수 있게 된다. 왜냐하면 호출한
함수에서는 가변 인자의 스택의 크기를 알지만 호출된 함수에서는 가변 인자의 스택의
크기를 알 수 없기 때문이다.
그리고 흔히들 OS에서 사용되는 함수나 다른 프로그래밍 언어에서 사용할 수 있게
DLL로 만들 때 함수를 __stdcall로 선언해야 한다고 말한다.
왜 그럴까?
그것은 __stdcall이 서로 다른 프로그래밍언어 사이에서 통일된 표준이기 때문이다.
OS는 특정 언어만을 지원할 수 없고 또한 서로 다른 프로그래밍 언어들이 서로 다른
함수의 인자 처리 방식을 사용한다면 한 프로그래밍 언어로 쓰여진 함수가 다른
프로그래밍 언어에서 사용되는 것이 불가능하다. 그래서 표준이 필요하였고
그것이 __stdcall인 것이다.
사실 이 부분은 내 주관적인 판단일 뿐이다.
또한 __stdcall이 __cdecl로 선언되는 것보다 프로그램의 크기가 작아지고 빠르다고
한다. 그 이유는 무엇일까?
이 부분은 데브피아에 '''고임''' 님이 어셈블리 코드까지 제시하면서 자세히 말씀해
주셨다. 아래는 고임님의 글에 본인이 약간의 수정을 가한 것이다.
cdecl 방식에서는 다음과 같습니다.
함수의 형태가 다음과 같다고 칩시다.
MyFunc Proto :DWORD,:DWORD,:DWORD,:DWORD
Invoke MyFunc, 1, 2, 3, 4
위의 코드는 다음과 같습니다.
Push 4
Push 3
Push 2
Push 1
Call MyFunc
Add sp, 16 ;; -->> 스택 정리 코드..
자 이것은 MyFunc의 인자를 오른쪽에서 왼쪽으로 스택에 집어 넣습니다.
그리고 보다시피 스택 정리 코드가 MyFunc이 리턴된 다음에 있습니다. 이는 함수를
호출한 쪽에서 호출된 함수가 리턴된 다음에 스택을 정리한다는 뜻입니다.
stdcall 방식은 다음과 같습니다.
Invoke WinMain, hInstance, NULL, NULL, SW_SHOWDEFAULT
call 명령으로 풀어쓰면 다음과 같이 됩니다.
Push SW_SHOWDEFAULT
Push NULL
Push NULL
Push hInstance
Call WinMain
여기서 보면 스택을 정리하는 코드가 빠져 있습니다. 따라서 스택 정리 코드가 없어진
stdcall 방식이 실행크기가 작아지고 속도도 명령어 하나 만큼이나 빨리지게 된 것입니다.
하지만 한가지 의구심이 듭니다.
어차피 호출당한 함수에서 해제를 하나 아니면 호출한 함수에서 해제를 하나
똑같이 해제를 하는데 호출당한 함수에서 해제를 하는 것이 속도나 크기가 더 줄어드는
것일까요?
엎어치나 되치나.. 스택을 어디선가 정리는 해야할텐데 도대체 ? 어떤 꽁수로? 이걸 해결했단말가?
여기에는 8086 아키텍쳐에 관련된 명령어가 그 원인으로 등장합니다.
그리고 스택을 정리한다는 것 자체가 그 함수를 호출한 뒤에
Add sp, 16으로 스택포인터를 인자의 크기만큼 변경을 시킨다는 이야기입니다.
근데 여기서 프로시저 즉 함수를 다 수행했을때 원래 상태로 돌아가게 될 때 쓰이는 명령어는 ret입니다.
(프로시저와 함수라는 용어를 병행하고 있는데.. ㅡㅡ;; 그냥 하나의 분리된 코드 덩어리다 라고
이해해주시기 바랍니다. 정확히 보면 서로 의미가 틀리지만.. ㅡㅡ; )
함수 시작하고, 함수가 끝났을때 ret 명령어로 호출한 부분으로 넘어가게 됩니다.
다시 말하면 이 명령어는 실행되던 함수를 바로 빠져나가게 됩니다. 따라서..
스택을 정리할 시간이 전혀 없었습니다. 이에 8086설계자들은 함수에서 리턴이 될때
스택포인터(SP)를 적절한 위치로 리셋을 시킬 수 있는 ret명령어를 새로 제공을 하여
이 문제를 아주 손쉽게 해결해 버렸습니다.
즉 ret, n 이라는 명령어를 제공했다는 셈이지요..
멋진 속담으로는 도랑치고 가재잡고 또는 멋진 고사성어로는 일석이조 라는 말로 표현된다
하겠습니다.
어차피 리턴할 걸 스택 포인터가 정리되는 부분으로 아예 리턴을 해버리란 이야기이지요..
이것은 가만히 앉아서 프로그램의 속도와 크기를 이점을 살리는 일이었습니다.
Add sp, 16 ;; -->> 추가된 코드..
호출하는 부분에서 이렇게 코딩하는 대신
호출 받는부분에서 리턴할때 ret, 16으로 해결했다는 이야기지요..
이래서 속도가 더빨라집니다. 크기도 줄어들구요..
생각을 한번 해보자구요... 이런식의 함수가 굉장히 많이 호출된다면..
크기나 실행 시간이 증가되는건 당연하겠지요..
마지막으로 정리를 하자면..
첫째, stdcall 방식은 cdecl 방식보다 빠르지만 가변 인자를 지원하지 못한다.
둘째, OS가 호출하는 함수나 DLL에 들어가는 함수는 가능하면 stdcall을 쓴다.
갑자기 __stdcall 이 궁금해졌어. | C / C++ 자료 | 2006.06.26 00:53 | ||
| |||
|
호출 규약(calling convention)을 지정합니다. 다음은 MSDN에서 발췌한 호출규약 요약입니다. [호출규약 : __cdecl]
[호출규약 : __stdcall]
|
'IT > 프로그래밍' 카테고리의 다른 글
How To sscanf() Example Using a Comma (,) as Delimiter (0) | 2008.01.18 |
---|---|
MSDN CFileDialog - 한글 (1) | 2008.01.18 |
reentrant ; 재진입성 (0) | 2007.12.28 |
삼성 코딩스타일(CodingStyle) (0) | 2007.12.22 |
Volatile [펌 www.debuglab.com] (0) | 2007.12.18 |
- Total
- Today
- Yesterday
- 지루박멸연구센타
- 열정의 힘을 믿는다
- Le4rN TO Cr4cK
- 디버깅에관한모든것(DebugLab)
- sysinternals
- FoundStone
- hashtab
- 보안-coderant
- 디바이스드라이버 개발자 포럼
- dualpage.muz.ro
- osronline.com - 드라이버 관련 정보 사이트
- NtInternals - NativeAPI Refere…
- pcthreat - spyware 정보 제공
- rootkit.com - 루트킷 관련 정보
- www.ntinternals.net
- WINE CrossRef. - source.winehq…
- tuts4you
- hex-rays
- idapalace
- idefense
- immunityinc
- threatexpert
- hdp.null2root.org
- www.crackstore.com
- crackmes.de
- www.who.is
- www.cracklab.ru
- community.reverse-engineering.…
- video.reverse-engineering.net
- SnD
- 클레이 키위
- reversengineering.wordpress.co…
- www.openrce.org
- www.woodmann.com
- PEID.Plusins.BobSoft
- roxik.com/pictaps/
- regexlib.com
- spyware-browser.com
- www.usboffice.kr
- regulator
- www.txt2re.com
- ietab.mozdev.org
- zesrever.xstone.org
- www.heaventools.com/PE-file-he…
- www.heaventools.com
- www.innomp3.com
- 울지않는벌새
- exetools.com-forum
- exetools.com
- utf8 conv
- robtex - IP trace
- onsamehost - same IP sites
- JpopSuki
- jsunpack.jeek.org
- wepawet.iseclab.org
- www.jswiff.com
- www.hackeroo.com
- winesearcher.co.kr
- khpga.org
- malwareurl.com
- anubis.iseclab.org
- www.crummy.com-eautifulSoup
- malwarebytes.org/forums
- bbs.janmeng.com
- blackip.ustc.edu.cn
- eureka.cyber-ta.org
- exploit-db.com
- 주식
- CriticalSection
- 실시간트래이딩
- 매매가격지수
- PIR
- 주식트래이딩
- hai
- INVOICE
- ChatGPT
- 사회간접자본
- 전세매매지수
- 피봇
- 신한저축은행
- ubuntu
- 자동트래이딩
- 군함도
- 공공인프라
- Pivot
- 다올저축은행
- 주택구매력지수
- 레고랜드
- SBI저축은행
- O365
- ElasticSearch
- logrotate
- 맥쿼리인프라
- ROA
- 미국주식
- systemd
- 시스템트래이딩
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |