Category Archives: C / C++

Calling Conventions (콜링 컨벤션)에 대한 정리

Calling Conventions (콜링 컨벤션) 콜링 컨벤션 호출 규약

콜링 컨벤션(Calling Conventions)란?
Microsoft의 Calling Conventions은 모두 5가지 종류의 Calling Conventions가 존재 한다.
각각의 차이점은 스택을 어떤 식으로 관리하고 또한 어떤 방법을로 인자를 전달하느냐의 차이가 있다.

1)__cdecl        (asm 에서는 C 만 써주면된다)
. 인자 전달순서는 RIGHT -> LEFT 순서
. 스택관리를호출한곳에서 관리한다.
. 함수의 이름에 _ 가 붙는다. ex) _Test
. 기본 호출 규약이므로 /Gz (stdcall) 또는 /Gr (fastcall) 옵션이 켜졌을 때, 필요한 변수나 함수 이름 앞에 __cdecl을 놓으면 된다.
/Gd 옵션은 강제로 __cdecl 규약으로 호출한다.

ex) _CRTIMP int __cdecl system(const char *);

2)__stdcall          (asm 에서는 stdcall 만 써주면된다)
. 인자 전달순서는 RIGHT -> LEFT 순서
. 스택관리를호출 받은곳에서 관리한다.
. 함수의 이름에 _ 가 붙으며 뒤에 @가 붙은후 인자목록의 바이트수(10진수)가 붙는다. ex) int Test(int a, double b)는 _Test@12
. /Gz 옵션은 호출규약이 명시적으로 선언되지 않은 모든 함수를 __stdcall로 만든다. __stdcall 형식으로 선언된 함수는 __cdecl 형식으로 값을 리턴한다

ex) #define WINAPI __stdcall

3)__fastcall
. 처음 2개의 DWORD 또는 더 작은 인자들이 ECX와 EDX 레지스터로 전달. 나머지 인자들은 오른쪽 –> 왼쪽으로 스택에 저장.
. 스택관리를 호출 받은곳에서 관리한다.
. 함수의 이름에 @가 붙은후 인자목록의 바이트수(10진수)가 붙는다. ex) int Test(int a, double b)는 Test@12
. /Gr 옵션은 선언된 함수가 충돌하지 않고 이름이 main이 아니라면, 모듈 내 각 함수를 fastcall로 컴파일한다.

ex) void __fastcall Test(void);

4) thiscall
가변인자를 사용하지 않는 C++ 멤버함수의 기본 호출 규약. 호출한곳에서 스택을 관리하고 스택 끝에 this 포인터를 넣으며,
컴파일시 컴파일러에 의해 가변인자(vararg) 함수는 __cdecl로 변경된다.
thiscall은 키워드가 아니므로 thiscall 호출 규약은 명시적으로 사용될 수 없다.
모든 함수인자들은 스택 상에 놓여지며, 이 호출규약은 C++에만 적용되므로, C 이름 장식 스키마는 없다.

5)naked
. 인자 전달순서는 RIGHT -> LEFT 순서
. 스택관리를 호출한곳에서 관리한다.
. VxDs에서만 사용한다.

< SAMPLE CODE >
http://www.cs.cornell.edu/courses/cs412/2001sp/resources/microsoft-calling-conventions.html

// The strings passed to each function.
static char * g_szStdCall = “__stdcall” ;
static char * g_szCdeclCall = “__cdecl” ;
static char * g_szFastCall = “__fastcall” ;
static char * g_szNakedCall = “__naked” ;

// The extern “C” turns off all C++ name decoration.
extern “C”
{
// The __cdecl function.
void CDeclFunction ( char * szString , unsigned long ulLong , char chChar ) ;
// The __stdcall function.
void __stdcall StdCallFunction ( char * szString , unsigned long ulLong , char chChar ) ;
// The __fastcall function.
void __fastcall FastCallFunction ( char * szString , unsigned long ulLong , char chChar ) ;
// The naked function. The declspec goes on the definition, not the
// declaration.
int NakedCallFunction ( char * szString ,  unsigned long ulLong , char chChar ) ;
}
void main ( void )
{
00401000 55 push ebp
00401001 8B EC mov ebp,esp
00401003 53 push ebx
00401004 56 push esi
00401005 57 push edi
// Call each function to generate the code.

CDeclFunction ( g_szCdeclCall , 1 , ‘a’ ) ;
00401008 6A 61 push 61h                              // ‘a’
0040100A 6A 01 push 1                                 //  1
0040100C A1 14 30 40 00 mov eax,[00403014]
00401011 50 push eax                                   //  g_szCdeclCall
00401012 E8 45 00 00 00 call 0040105C
00401017 83 C4 0C add esp,0Ch                     // 호출한곳에서 스택 정리
StdCallFunction ( g_szStdCall , 2 , ‘b’ ) ;
0040101C 6A 62 push 62h
0040101E 6A 02 push 2
00401020 8B 0D 10 30 40 00 mov ecx,dword ptr ds:[00403010h]
00401026 51 push ecx
00401027 E8 3D 00 00 00 call 00401069         // 콜하면 끝  함수 내부에서 스택관리

FastCallFunction ( g_szFastCall , 3 , ‘c’ ) ;
0040102E 6A 63 push 63h                               // ‘c’ 만 푸시
00401030 BA 03 00 00 00 mov edx,3                //  3은 edx에 저장
00401035 8B 0D 18 30 40 00 mov ecx,dword ptr ds:[00403018h]        // g_szFastCall 은 ecx에 저장
0040103B E8 38 00 00 00 call 00401078          // 함수 내부에서 스택관리

NakedCallFunction ( g_szNakedCall , 4 , ‘d’ ) ;             // 기본값은 cdecl
00401042 6A 64 push 64h
00401044 6A 04 push 4
00401046 8B 15 1C 30 40 00 mov edx,dword ptr ds:[0040301Ch]
0040104C 52 push edx
0040104D E8 40 00 00 00 call 00401092
00401052 83 C4 0C add esp,0Ch
}
00401057 5F pop edi
00401058 5E pop esi
00401059 5B pop ebx
0040105A 5D pop ebp
0040105B C3 ret
void CDeclFunction ( char * szString , unsigned long ulLong , char chChar )
{
0040105C 55 push ebp
0040105D 8B EC mov ebp,esp
0040105F 53 push ebx
00401060 56 push esi
00401061 57 push edi
__asm NOP __asm NOP // NOPs stand for the function body here
00401062 90 nop
00401063 90 nop
}
00401064 5F pop edi
00401065 5E pop esi
00401066 5B pop ebx
00401067 5D pop ebp
00401068 C3 ret
void __stdcall StdCallFunction ( char * szString , unsigned long ulLong , char chChar )
{
00401069 55 push ebp
0040106A 8B EC mov ebp,esp
0040106C 53 push ebx
0040106D 56 push esi
0040106E 57 push edi
__asm NOP __asm NOP
0040106F 90 nop
00401070 90 nop
}
00401071 5F pop edi
00401072 5E pop esi
00401073 5B pop ebx
00401074 5D pop ebp
00401075 C2 0C 00 ret 0Ch    // 스택정리
void __fastcall FastCallFunction ( char * szString , unsigned long ulLong , char chChar )
{
00401078 55 push ebp
00401079 8B EC mov ebp,esp
0040107B 83 EC 08 sub esp,8
0040107E 53 push ebx
0040107F 56 push esi
00401080 57 push edi
00401081 89 55 F8 mov dword ptr [ebp-8],edx
00401084 89 4D FC mov dword ptr [ebp-4],ecx
__asm NOP __asm NOP
00401087 90 nop
00401088 90 nop
}
00401089 5F pop edi
0040108A 5E pop esi
0040108B 5B pop ebx
0040108C 8B E5 mov esp,ebp
0040108E 5D pop ebp
0040108F C2 04 00 ret 4    // 스택정리
78:
__declspec(naked) int NakedCallFunction ( char * szString , unsigned long ulLong , char chChar )
{
__asm NOP __asm NOP
00401092 90 nop
00401093 90 nop
// Naked functions must EXPLICITLY do a return.
__asm RET
00401094 C3 ret

< 참고자료 >
꼭 한번 보시길.
http://www.unixwiz.net/techtips/win32-callconv.html

출처 – http://www.crazysoul.org/tt/94?TSSESSION=510470321220837f75085d433fcbe5eb

현재 시스템 시간 얻어오는 소스

#include <stdio.h>
#include <time.h>

void main()
{

 tm *t;
 long tim=time(NULL);

 t=localtime(&tim);
 printf("유닉스 타임 (Unix Time): %d 초\n\n", tim); // 1970년 1월 1일 0시 0분 0초부터 시작하여 현재까지의 초
 printf("현재 년: %d\n",   t->tm_year + 1900);
 printf("현재 월: %d\n",   t->tm_mon + 1);
 printf("현재 일: %d\n\n", t->tm_mday);
 printf("현재 시: %d\n",   t->tm_hour);
 printf("현재 분: %d\n",   t->tm_min);
 printf("현재 초: %d\n\n", t->tm_sec);
 printf("현재 요일: %d\n", t->tm_wday); // 일요일 0 ~
 printf("올해 몇 번째 날: %d\n", t->tm_yday); // 1월 1일은 0, 1월 2일은 1
 printf("서머타임 적용 여부: %d\n", t->tm_isdst); // 0 이면 서머타임 없음

}

 

 

struct tm {
  int tm_sec;   /* 초Seconds */
  int tm_min;   /* 분Minutes */
  int tm_hour;  /* 시Hour (0–23) */
  int tm_mday;  /* 일Day of month (1–31) */
  int tm_mon;   /* 월Month (0–11) */
  int tm_year;  /* 년Year (calendar year minus 1900) */
  int tm_wday;  /* 요일Weekday (0–6; Sunday = 0) */
  int tm_yday;  /* 1년의 몇번째Day of year (0–365) */
  int tm_isdst; /* 서머타임 적용여부 0 if daylight savings time is not in effect) */

};

가상 키값

가상 키 코드(Virtual Key Code)테이블

가상키                       코드                            값 키
VK_LBUTTON                01  
VK_RBUTTON                02  
VK_CANCEL                 03                           Ctrl-Break
VK_MBUTTON                04  
VK_BACK                   08                           Backspace
VK_TAB                    09                              Tab
VK_CLEAR                  0C                 NumLock이 꺼져 있을 때의 5
VK_RETURN                 0D                             Enter
VK_SHIFT                  10                                Shift
VK_CONTROL                11                                Ctrl  
VK_MENU                   12                                Alt  
VK_PAUSE                  13                              Pause
VK_CAPITAL                14                            Caps Lock  
VK_ESCAPE                 1B                               Esc  
VK_SPACE                  20                            스페이스  
VK_PRIOR                  21                              PgUp
VK_NEXT                   22                              PgDn  
VK_END                    23                              End  
VK_HOME                   24                              Home  
VK_LEFT                   25                         왼측 커서 이동키  
VK_UP                     26                         위쪽 커서 이동키  
VK_RIGHT                  27                         오른쪽 커서 이동키  
VK_DOWN                   28                         아래쪽 커서 이동키  
VK_SELECT                 29  
VK_PRINT                  2A  
VK_EXECUTE                2B  
VK_SNAPSHOT               2C                             Print Screen
VK_INSERT                 2D                               Insert
VK_DELETE                 2E                               Delete
VK_HELP                   2F  
                               30~39                           숫자키 0~9
                               41~5A                           영문자 A~Z
VK_LWIN                   5B                             왼쪽 윈도우 키
VK_RWIN                   5C                            오른쪽 윈도우 키
VK_APP                    5D                            Application 키
VK_NUMPAD0~VK_NUMPAD9     60~69            숫자 패드의 0~9
VK_MULTIPLY               6A                             숫자 패드의 *  
VK_ADD                    6B                             숫자 패드의 +  
VK_SEPARATOR              6C  
VK_SUBTRACT               6D                             숫자 패드의 –  
VK_DECIMAL                6E                             숫자 패드의 .  
VK_DIVIDE                 6F                              숫자 패드의 /  
VK_F1~VKF24               70~87                           평션키 F1~F24
VK_NUMLOCK                90                               Num Lock
VK_SCROLL                 91                               Scroll Lock  

 

 

 

Virtual key codes

Symbolic constantHexadecimal valueMouse or keyboard equivalent
VK_LBUTTON01Left mouse button
VK_RBUTTON02Right mouse button
VK_CANCEL03Control-break processing
VK_MBUTTON04Middle mouse button on a three-button mouse
0507Undefined
VK_BACK08BACKSPACE key
VK_TAB09TAB key
0A0BUndefined
VK_CLEAR0CCLEAR key
VK_RETURN0DENTER key
0E0FUndefined
VK_SHIFT10SHIFT key
VK_CONTROL11CTRL key
VK_MENU12ALT key
VK_PAUSE13PAUSE key
VK_CAPITAL14CAPS LOCK key
1519Reserved for Kanji systems
1AUndefined
VK_ESCAPE1BESC key
1C1FReserved for Kanji systems
VK_SPACE20SPACEBAR
VK_PRIOR21PAGE UP key
VK_NEXT22PAGE DOWN key
VK_END23END key
VK_HOME24HOME key
VK_LEFT25LEFT ARROW key
VK_UP26UP ARROW key
VK_RIGHT27RIGHT ARROW key
VK_DOWN28DOWN ARROW key
VK_SELECT29SELECT key
 2ASpecific to original equipment manufacturer
VK_EXECUTE2BEXECUTE key
VK_SNAPSHOT2CPRINT SCREEN key
VK_INSERT2DINS key
VK_DELETE2EDEL key
VK_HELP2FHELP key
 3A40Undefined
VK_LWIN5BLeft Windows key on a Microsoft Natural Keyboard
VK_RWIN5CRight Windows key on a Microsoft Natural Keyboard
VK_APPS5DApplications key on a Microsoft Natural Keyboard
 5E5FUndefined
VK_NUMPAD060Numeric keypad 0 key
VK_NUMPAD161Numeric keypad 1 key
VK_NUMPAD262Numeric keypad 2 key
VK_NUMPAD363Numeric keypad 3 key
VK_NUMPAD464Numeric keypad 4 key
VK_NUMPAD565Numeric keypad 5 key
VK_NUMPAD666Numeric keypad 6 key
VK_NUMPAD767Numeric keypad 7 key
VK_NUMPAD868Numeric keypad 8 key
VK_NUMPAD969Numeric keypad 9 key
VK_MULTIPLY6AMultiply key
VK_ADD6BAdd key
VK_SEPARATOR6CSeparator key
VK_SUBTRACT6DSubtract key
VK_DECIMAL6EDecimal key
VK_DIVIDE6FDivide key
VK_F170F1 key
VK_F271F2 key
VK_F372F3 key
VK_F473F4 key
VK_F574F5 key
VK_F675F6 key
VK_F776F7 key
VK_F877F8 key
VK_F978F9 key
VK_F1079F10 key
VK_F117AF11 key
VK_F127BF12 key
VK_F137CF13 key
VK_F147DF14 key
VK_F157EF15 key
VK_F167FF16 key
VK_F1780HF17 key
VK_F1881HF18 key
VK_F1982HF19 key
VK_F2083HF20 key
VK_F2184HF21 key
VK_F2285HF22 key

(PPC only) Key used to lock device.

VK_F2386HF23 key
VK_F2487HF24 key
 888FUnassigned
VK_NUMLOCK90NUM LOCK key
VK_SCROLL91SCROLL LOCK key
VK_LSHIFT0xA0Left SHIFT
VK_RSHIFT0xA1Right SHIFT
VK_LCONTROL0xA2Left CTRL
VK_RCONTROL0xA3Right CTRL
VK_LMENU0xA4Left ALT
VK_RMENU0xA5Right ALT
 BA-C0Specific to original equipment manufacturer; reserved. See following tables.
 C1-DAUnassigned
 DB-E2Specific to original equipment manufacturer; reserved. See following tables.
 E3 – E4Specific to original equipment manufacturer
 E5Unassigned
 E6Specific to original equipment manufacturer
VK_PACKETE7Used to pass Unicode characters as if they were keystrokes. If VK_PACKET is used with SendInput, then the Unicode character to be delivered should be placed into the lower 16 bits of the scan code. If a keyboard message is removed from the message queue and the virtual key is VK_PACKET, then the Unicode character will be the upper 16 bits of the lparam.
 E8Unassigned
 E9-F5Specific to original equipment manufacturer
VK_ATTNF6ATTN key
VK_CRSELF7CRSEL key
VK_EXSELF8EXSEL key
VK_EREOFF9Erase EOF key
VK_PLAYFAPLAY key
VK_ZOOMFBZOOM key
VK_NONAMEFCReserved for future use
VK_PA1FDPA1 key
VK_OEM_CLEARFECLEAR key
VK_KEYLOCKF22Key used to lock device

Original equipment manufacturers should make special note of the VK key ranges reserved for specific original equipment manufacturer use: 2A, DBE4, E6, and E9F5.

In addition to the VK key assignments in the previous table, Microsoft has assigned the following specific original equipment manufacturer VK keys.

Symbolic constantHexadecimal valueMouse or keyboard equivalent
VK_OEM_SCROLL0x91None
VK_OEM_10xBA";:" for US
VK_OEM_PLUS0xBB"+" any country/region
VK_OEM_COMMA0xBC"," any country/region
VK_OEM_MINUS0xBD"-" any country/region
VK_OEM_PERIOD0xBE"." any country/region
VK_OEM_20xBF"/?" for US
VK_OEM_30xC0"`~" for US
VK_OEM_40xDB"[{" for US
VK_OEM_50xDC"\|" for US
VK_OEM_60xDD"]}" for US
VK_OEM_70xDE"’"" for US
VK_OEM_80xDFNone
VK_OEM_AX0xE1AX key on Japanese AX keyboard
VK_OEM_1020xE2"<>" or "\|" on RT 102-key keyboard

For East Asian Input Method Editors (IMEs) the following additional virtual keyboard definitions must be observed.

Symbolic constantHexadecimal valueDescription
VK_DBE_ALPHANUMERIC0x0f0Changes the mode to alphanumeric.
VK_DBE_KATAKANA0x0f1Changes the mode to Katakana.
VK_DBE_HIRAGANA0x0f2Changes the mode to Hiragana.
VK_DBE_SBCSCHAR0x0f3Changes the mode to single-byte characters.
VK_DBE_DBCSCHAR0x0f4Changes the mode to double-byte characters.
VK_DBE_ROMAN0x0f5Changes the mode to Roman characters.
VK_DBE_NOROMAN0x0f6Changes the mode to non-Roman characters.
VK_DBE_ENTERWORDREGISTERMODE0x0f7Activates the word registration dialog box.
VK_DBE_ENTERIMECONFIGMODE0x0f8Activates a dialog box for setting up an IME environment.
VK_DBE_FLUSHSTRING0x0f9Deletes the undetermined string without determining it.
VK_DBE_CODEINPUT0x0faChanges the mode to code input.
VK_DBE_NOCODEINPUT0x0fbChanges the mode to no-code input.

변환지정자

변환문자>$2

의미>$2

%c

문자1개 출력

%d

10진수로 출력

%e

부호있는 소수 출력(지수표시e)

%E

부호있는 소수출력(지수표시E)

%f

부호있는 소수 출력

%g

주어진 부호값에 따라f또는e를 자동으로 선택하여 출력

%G

주어진 부호값에 따라f또는E를 자동으로 선택하여 출력

%ld

long10진수로 출력

%lo

long8진수로 출력

%lx

long16진수로 출력

%o

8진수로 출력

%s

문자열 출력

%u

부호없는10진수로 출력

%x

16진수로 출력(0~9,a,b,c,d,e,f)

%X

16진수로 출력(0~9,A,B,C,D,E,F)