ÇÔ¼ö È£Ãâ ±Ô¾à

2006-09-01 ½Å¿µÁø

ÇÔ¼ö¸¦ È£ÃâÇÏ´Â ÇüÅ¿¡´Â ¿©·¯ °¡Áö ¹æ¹ýÀÌ ÀÖ´Ù. Visual C++¿¡¼­´Â ³× °¡Áö ÇüÅÂÀÇ È£Ãâ ±Ô¾àÀ» Áö¿øÇÑ´Ù. __cdecl, __fastcall, __stdcall, __thiscallÀÌ ±×°ÍÀÌ´Ù. °¢ È£Ãâ ±Ô¾àÀº ºñ½ÁÇÏÁö¸¸ ¾à°£ ¾¿ Â÷À̸¦ °¡Áö°í ÀÖ´Ù. °¢°¢ÀÇ È£Ã⠱Ծ࿡ ´ëÇÑ Æ¯Â¡À» »ìÆì º¸µµ·Ï ÇÏÀÚ.

__cdecl

C¾ð¾î Ç¥ÁØ È£Ãâ ±Ô¾àÀÌ´Ù. ÆÄ¶ó¹ÌÅÍ´Â ¿À¸¥ÂÊ¿¡¼­ ¿ÞÂÊÀ¸·Î ½ºÅÃÀ» ÅëÇØ Àü´ÞµÇ¸ç, È£ÃâÇÑ °÷¿¡¼­ ½ºÅÃÀ» Á¤¸®ÇÑ´Ù. Ư¡ÀûÀÎ°Ç È£ÃâÇÑ ÂÊ¿¡¼­ ½ºÅÃÀ» Á¤¸®Çϱ⠶§¹®¿¡ °¡º¯ ÀÎÀÚ¸¦ Áö¿øÇÑ´Ù´Â °ÍÀÌ´Ù. 

À§ ÇÔ¼ö¸¦ È£ÃâÇϱâ À§ÇÑ ¾î¼Àºí¸® ÄÚµå´Â ¾Æ·¡¿Í °°´Ù. add ¸í·É¾î¸¦ ÅëÇØ¼­ È£Ãâ ÇÑ ÈÄ¿¡ ½ºÅÃÀ» Á¤¸®ÇØ ÁÖ¾î¾ß ÇÑ´Ù.

push 3
push 2
push 1
call CdeclFunc
add esp, 12

__fastcall

¸» ±×´ë·Î ºü¸¥ È£ÃâÀÌ´Ù. ÆÄ¶ó¹ÌÅÍ Áß ÀϺθ¦ ·¹Áö½ºÅ͸¦ ÅëÇØ¼­ Àü´ÞÇÏ´Â ÇÔ¼ö´Ù. x86 °è¿­¿¡¼­´Â ÀϹÝÀûÀ¸·Î ecx, edx·Î ÆÄ¶ó¹ÌÅ͸¦ Àü´ÞÇÏ°í ³ª¸ÓÁö´Â ½ºÅÃÀ¸·Î Àü´ÞÇÑ´Ù. __cdecl°ú °°ÀÌ ¿À¸¥ÂÊ¿¡¼­ ¿ÞÂÊÀ¸·Î ÆÄ¶ó¹ÌÅ͸¦ Àü´ÞÇϸç, ½ºÅà Á¤¸®´Â È£ÃâÀ» ´çÇÑ °÷¿¡¼­ ¼öÇàÇÑ´Ù. µû¶ó¼­ °¡º¯ ÀÎÀÚ¸¦ Áö¿øÇÏÁö ¸øÇÑ´Ù. 

À§ ÇÔ¼ö¸¦ È£Ãâ ÇÏ´Â ÄÚµå´Â ¾Æ·¡¿Í °°´Ù. ¾Õ ÂÊ µÎ °³ÀÇ ÆÄ¶ó¹ÌÅͰ¡ ecx¿Í edx¸¦ ÅëÇØ¼­ Àü´ÞµÈ´Ù. ÆÄ¶ó¹ÌÅͰ¡ µÎ °³ ÀÌÇÏÀÎ ÇÔ¼ö¿¡ ´ëÇØ¼­´Â ½ºÅÃÀ» ÀüÇô »ç¿ëÇÏÁö ¾Ê±â ¶§¹®¿¡ ºü¸£°Ô µ¿ÀÛÇÑ´Ù.

push 3
mov edx, 2
mov ecx, 1
call @FastcallFunc@12

__stdcall

À©µµ¿ì APIÀÇ Ç¥ÁØ È£Ãâ ±Ô¾àÀÌ´Ù. ÆÄ¶ó¹ÌÅÍ´Â ¿À¸¥ÂÊ¿¡¼­ ¿ÞÂÊÀ¸·Î ½ºÅÃÀ» ÅëÇØ¼­ Àü´ÞµÇ¸ç, ½ºÅà Á¤¸®´Â È£Ãâ ´çÇÑ °÷¿¡¼­ ÀÌ·ç¾îÁø´Ù.

È£Ãâ ÄÚµå´Â ¾Æ·¡¿Í °°´Ù. __cdecl°ú À¯»çÇÏÁö¸¸ ½ºÅà Á¤¸® Äڵ尡 ¾ø´Â°Ô Ư¡ÀÌ´Ù.

push 3
push 2
push 1
call _StdcallFunc@12

__thiscall

Á÷Á¢ÀûÀ¸·Î ÇÔ¼ö È£Ãâ ±Ô¾àÀ¸·Î »ç¿ëÇÒ ¼ö´Â ¾ø´Ù. ÀÌ È£Ãâ ±Ô¾àÀº C++ÀÇ Å¬·¡½º ¸â¹ö ÇÔ¼ö È£Ãâ ±Ô¾àÀ¸·Î »ç¿ëµÈ´Ù. ÆÄ¶ó¹ÌÅÍ´Â ¿À¸¥ÂÊ¿¡¼­ ¿ÞÂÊÀ¸·Î ½ºÅÃÀ» ÅëÇØ¼­ Àü´ÞµÇ°í, È£Ãâ ´çÇÑ °÷¿¡¼­ ½ºÅÃÀ» Á¤¸®ÇÑ´Ù. Ư¡Àû À롂 ecx¸¦ ÅëÇØ¼­ Ŭ·¡½º Æ÷ÀÎÅ͸¦ Àü´ÞÇÏ´Â Á¡ÀÌ´Ù.

È£Ãâ ÇÏ´Â ÄÚµå´Â ¾Æ·¡¿Í °°´Ù. Ư¡Àº ecx·Î Ŭ·¡½ºÀÇ this Æ÷ÀÎÅ͸¦ Àü´ÞÇÑ´Ù´Â Á¡ÀÌ´Ù.

push 3
push 2
push 1
lea ecx, conv
call CCallConv::ThisCall

½ºÅà Á¤¸® ¹æ½ÄÀÇ Â÷ÀÌ

ÇÔ¼ö È£Ãâ ±Ô¾àÀÇ ÁÖµÈ Â÷ÀÌÁ¡Àº ½ºÅà Á¤¸® ¹æ½ÄÀÌ´Ù. È£ÃâÇÑ ÂÊ¿¡¼­ Á¤¸®ÇÏ´Â ¹æ½Ä°ú È£ÃâÀ» ´çÇÑ °÷¿¡¼­ Á¤¸®ÇÏ´Â ¹æ¹ýÀÌ ÀÖ´Ù. È£ÃâÇÑ ÂÊ¿¡¼­ Á¤¸®ÇÏ´Â ¹æ¹ýÀÇ ÀåÁ¡Àº ÀÚ½ÅÀÌ ÆÄ¶ó¹ÌÅÍ·Î Àü´ÞÇÑ ÀÎÀÚÀÇ °³¼ö¸¦ Á¤È®È÷ ¾Ë ¼ö Àֱ⠶§¹®¿¡ °¡º¯ ÀÎÀÚ¸¦ Áö¿øÇÒ ¼ö ÀÖ´Ù´Â °ÍÀÌ´Ù. ±×·¸´Ù¸é __cdeclÀ» Á¦¿ÜÇÑ ³ª¸ÓÁö ¹æ½ÄÀº ¿Ö ½ºÅÃÀ» È£ÃâÀ» ´çÇÑ °÷¿¡¼­ Á¤¸®ÇÏ´Â °ÍÀϱî?

±× ÀÌÀ¯´Â ¼Óµµ¿¡ ÀÖ´Ù. x86 CPUÀÇ °æ¿ì ret ¾î¼Àºí¸® ¸í·É¾î¸¦ µÎ °¡Áö ÇüÅ·ΠÁö¿øÇÑ´Ù. ret¸¦ ÇÏ¸é ´Ü¼øÈ÷ ½ºÅÿ¡ ÀúÀåµÈ º¹±Í ÁÖ¼Ò·Î ¸®ÅÏ ÇÑ´Ù. ÇÏÁö¸¸ ret imm16À» »ç¿ëÇϸé imm16¸¸Å­ ½ºÅÿ¡¼­ ÆË ÇÑ ´ÙÀ½ ²¨³»Áø º¹±Í ÁÖ¼Ò·Î ¸®ÅÏ ÇÑ´Ù. À§¿¡¼­ »ìÆì º¸¾ÒµíÀÌ __cdeclÀº ½ºÅà Á¤¸®¸¦ À§Çؼ­ add ¸í·É¾î°¡ Ãß°¡µÈ´Ù. ¹Ý¸é¿¡ È£ÃâÀ» ´çÇÑ °÷¿¡¼­ Á¤¸®ÇÏ´Â ¹æ½ÄÀº ¸®ÅÏÇÒ ¶§¿¡ ret imm16À» »ç¿ëÇÔÀ¸·Î½á add ¸í·É¾î°¡ Ãß°¡µÇÁö ¾Ê¾Æµµ µÈ´Ù. ¶ÇÇÑ 486À» ±âÁØÀ¸·Î ÇßÀ» ¶§ ret¿Í ret imm16Àº 5Ŭ·° »çÀÌŬÀ» ¼Ò¸ðÇÏ´Â µ¿ÀÏÇÑ ¸í·É¾î·Î 󸮵ȴÙ. µû¶ó¼­ __cdeclº¸´Ù´Â ´Ù¸¥ È£Ãâ ±Ô¾àÀÌ ±Ù¼ÒÇÏ°Ô ºü¸¦ ¼ö ÀÖ´Ù.

¸â¹ö ÇÔ¼ö´Â ¸ðµÎ __thiscall??

À§¿¡¼­ ¸â¹ö ÇÔ¼ö¿£ __thiscallÀ» »ç¿ëÇÑ´Ù°í Çß´Ù. ¹°·Ð ±âº»ÀûÀ¸·Î __thiscallÀÌ »ç¿ëµÇ³ª, Á÷Á¢ ÁöÁ¤ÇÒ °æ¿ì ´Ù¸¥ È£Ãâ ±Ô¾àÀ» »ç¿ëÇÒ ¼ö ÀÖ´Ù. ´Ù¸¥ È£Ãâ ±Ô¾àÀ» ÁöÁ¤ÇÏ°Ô µÇ¸é ù ¹øÂ° ÀÎÀÚ·Î this Æ÷ÀÎÅͰ¡ Àü´ÞµÈ´Ù.

Á¤¸®

È£Ãâ ±Ô¾à ÆÄ¶ó¹ÌÅÍ ½ºÅà Ư¡
__cdecl ¿À¸¥ÂÊ -> ¿ÞÂÊ È£ÃâÇÑ °÷ °¡º¯ ÀÎÀÚ Áö¿ø
__fastcall ¿À¸¥ÂÊ -> ¿ÞÂÊ È£Ãâ ´çÇÑ °÷ ÆÄ¶ó¹ÌÅÍ µÎ °³¸¦ ecx, edx¸¦ ÅëÇØ¼­ Àü´ÞÇϱ⠶§¹®¿¡ µÎ °³ ÀÌÇÏÀÇ ÀÎÀÚ¸¦ °¡Áø ÇÔ¼ö¿¡ ´ëÇØ¼­ ºü¸§
__stdcall ¿À¸¥ÂÊ -> ¿ÞÂÊ È£Ãâ ´çÇÑ °÷ Windows Ç¥ÁØ È£Ãâ ±Ô¾à
__thiscall ¿À¸¥ÂÊ -> ¿ÞÂÊ È£Ãâ ´çÇÑ °÷ ecx¸¦ ÅëÇØ¼­ this Æ÷ÀÎÅ͸¦ Àü´Þ ÇÔ

ÄÚµå

Å×½ºÆ®¿¡ »ç¿ëµÈ C¾ð¾î ÄÚµå´Ù.

CdeclFunc ÇÔ¼öÀÇ ¾î¼Àºí¸® ¸®½ºÆÃÀÌ´Ù.

PUBLIC  _CdeclFunc
EXTRN   _printf:NEAR
; Function compile flags: /Odt
_TEXT   SEGMENT
_a$ = 8                         ; size = 4
_b$ = 12                        ; size = 4
_c$ = 16                        ; size = 4
_CdeclFunc PROC NEAR
; File d:\test\realtest\callconv\callconv.cpp
; Line 7
    push    ebp
    mov ebp, esp
; Line 8
    mov eax, DWORD PTR _c$[ebp]
    push    eax
    mov ecx, DWORD PTR _b$[ebp]
    push    ecx
    mov edx, DWORD PTR _a$[ebp]
    push    edx
    push    OFFSET FLAT:$SG9623
    call    _printf
    add esp, 16                 ; 00000010H
; Line 9
    pop ebp
    ret 0
_CdeclFunc ENDP

FastcallFunc ÇÔ¼öÀÇ ¾î¼Àºí¸® ¸®½ºÆÃÀÌ´Ù.

_TEXT   ENDS
PUBLIC  @FastcallFunc@12
; Function compile flags: /Odt
_TEXT   SEGMENT
_b$ = -8                        ; size = 4
_a$ = -4                        ; size = 4
_c$ = 8                         ; size = 4
@FastcallFunc@12 PROC NEAR
; _a$ = ecx
; _b$ = edx
; Line 13
    push    ebp
    mov ebp, esp
    sub esp, 8
    mov DWORD PTR _b$[ebp], edx
    mov DWORD PTR _a$[ebp], ecx
; Line 14
    mov eax, DWORD PTR _c$[ebp]
    push    eax
    mov ecx, DWORD PTR _b$[ebp]
    push    ecx
    mov edx, DWORD PTR _a$[ebp]
    push    edx
    push    OFFSET FLAT:$SG9629
    call    _printf
    add esp, 16                 ; 00000010H
; Line 15
    mov esp, ebp
    pop ebp
    ret 4
@FastcallFunc@12 ENDP
_TEXT   ENDS

StdcallFunc ÇÔ¼öÀÇ ¾î¼Àºí¸® ¸®½ºÆÃÀÌ´Ù.

PUBLIC  _StdcallFunc@12
; Function compile flags: /Odt
_TEXT   SEGMENT
_a$ = 8                         ; size = 4
_b$ = 12                        ; size = 4
_c$ = 16                        ; size = 4
_StdcallFunc@12 PROC NEAR
; Line 19
    push    ebp
    mov ebp, esp
; Line 20
    mov eax, DWORD PTR _c$[ebp]
    push    eax
    mov ecx, DWORD PTR _b$[ebp]
    push    ecx
    mov edx, DWORD PTR _a$[ebp]
    push    edx
    push    OFFSET FLAT:$SG9635
    call    _printf
    add esp, 16                 ; 00000010H
; Line 21
    pop ebp
    ret 12                  ; 0000000cH
_StdcallFunc@12 ENDP
_TEXT   ENDS

ThisCall ÇÔ¼öÀÇ ¾î¼Àºí¸® ¸®½ºÆÃÀÌ´Ù.

PUBLIC  ?ThisCall@CCallConv@@QAEHHHH@Z          ; CCallConv::ThisCall
; Function compile flags: /Odt
_TEXT   SEGMENT
_this$ = -4                     ; size = 4
_a$ = 8                         ; size = 4
_b$ = 12                        ; size = 4
_c$ = 16                        ; size = 4
?ThisCall@CCallConv@@QAEHHHH@Z PROC NEAR        ; CCallConv::ThisCall
; _this$ = ecx
; Line 30
    push    ebp
    mov ebp, esp
    push    ecx
    mov DWORD PTR _this$[ebp], ecx
; Line 31
    mov eax, DWORD PTR _c$[ebp]
    push    eax
    mov ecx, DWORD PTR _b$[ebp]
    push    ecx
    mov edx, DWORD PTR _a$[ebp]
    push    edx
    push    OFFSET FLAT:$SG9653
    call    _printf
    add esp, 16                 ; 00000010H
; Line 32
    mov esp, ebp
    pop ebp
    ret 12                  ; 0000000cH
?ThisCall@CCallConv@@QAEHHHH@Z ENDP         ; CCallConv::ThisCall
_TEXT   ENDS

main ÇÔ¼öÀÇ ¾î¼Àºí¸® ¸®½ºÆÃÀÌ´Ù.

PUBLIC  _main
; Function compile flags: /Odt
_TEXT   SEGMENT
_conv$ = -1                     ; size = 1
_argc$ = 8                      ; size = 4
_argv$ = 12                     ; size = 4
_main   PROC NEAR
; Line 35
    push    ebp
    mov ebp, esp
    push    ecx
; Line 36
    push    3
    push    2
    push    1
    call    _CdeclFunc
    add esp, 12                 ; 0000000cH
; Line 37
    push    3
    mov edx, 2
    mov ecx, 1
    call    @FastcallFunc@12
; Line 38
    push    3
    push    2
    push    1
    call    _StdcallFunc@12
; Line 41
    push    3
    push    2
    push    1
    lea ecx, DWORD PTR _conv$[ebp]
    call    ?ThisCall@CCallConv@@QAEHHHH@Z      ; CCallConv::ThisCall
; Line 42
    xor eax, eax
; Line 43
    mov esp, ebp
    pop ebp
    ret 0
_main   ENDP

Âü°í ÀÚ·á

http://www.unixwiz.net/techtips/win32-callconv-asm.html
http://home.comcast.net/~fbui/intel.html#clock
http://www.hardwaresecrets.com/article/270/4
http://swox.com/doc/x86-timing.pdf
http://developer.intel.com/design/Pentium4/documentation.htm
¡¡