#include <stdio.h>
int main(void)
{
004D1870 push ebp
004D1871 mov ebp,esp
004D1873 sub esp,0D8h
004D1879 push ebx
004D187A push esi
004D187B push edi
004D187C lea edi,[ebp-18h]
004D187F mov ecx,6
004D1884 mov eax,0CCCCCCCCh
004D1889 rep stos dword ptr es:[edi]
004D188B mov ecx,offset _14FBEC25_PrintfOutput@c (04DC008h)
004D1890 call @__CheckForDebuggerJustMyCode@4 (04D132Ah)
004D1895 nop
int num1, num2;
num1 = printf("12345\n");
004D1896 push offset string "12345\n" (04D7B30h)
004D189B call _printf (04D10D2h)
004D18A0 add esp,4
004D18A3 mov dword ptr [num1],eax
num2 = printf("I love my home\n");
004D18A6 push offset string "I love my home\n" (04D7B38h)
004D18AB call _printf (04D10D2h)
004D18B0 add esp,4
004D18B3 mov dword ptr [num2],eax
printf("%d %d\n", num1, num2);
004D18B6 mov eax,dword ptr [num2]
004D18B9 push eax
004D18BA mov ecx,dword ptr [num1]
004D18BD push ecx
004D18BE push offset string "%d %d\n" (04D7B4Ch)
004D18C3 call _printf (04D10D2h)
004D18C8 add esp,0Ch
return 0;
004D18CB xor eax,eax
}
004D18CD pop edi
004D18CE pop esi
004D18CF pop ebx
004D18D0 add esp,0D8h
004D18D6 cmp ebp,esp
004D18D8 call __RTC_CheckEsp (04D124Eh)
004D18DD mov esp,ebp
004D18DF pop ebp
004D18E0 ret
#include <stdio.h>
int main(void)
{
00007FF77E8F1890 push rbp
00007FF77E8F1892 push rdi
00007FF77E8F1893 sub rsp,128h
00007FF77E8F189A lea rbp,[rsp+20h]
00007FF77E8F189F lea rcx,[__14FBEC25_PrintfOutput@c (07FF77E902008h)]
00007FF77E8F18A6 call __CheckForDebuggerJustMyCode (07FF77E8F136Bh)
00007FF77E8F18AB nop
int num1, num2;
num1 = printf("12345\n");
00007FF77E8F18AC lea rcx,[string "12345\n" (07FF77E8FAC24h)]
00007FF77E8F18B3 call printf (07FF77E8F1195h)
00007FF77E8F18B8 mov dword ptr [num1],eax
num2 = printf("I love my home\n");
00007FF77E8F18BB lea rcx,[string "I love my home\n" (07FF77E8FAC30h)]
00007FF77E8F18C2 call printf (07FF77E8F1195h)
00007FF77E8F18C7 mov dword ptr [num2],eax
printf("%d %d\n", num1, num2);
00007FF77E8F18CA mov r8d,dword ptr [num2]
00007FF77E8F18CE mov edx,dword ptr [num1]
00007FF77E8F18D1 lea rcx,[string "%d %d\n" (07FF77E8FAC44h)]
00007FF77E8F18D8 call printf (07FF77E8F1195h)
00007FF77E8F18DD nop
return 0;
00007FF77E8F18DE xor eax,eax
}
00007FF77E8F18E0 lea rsp,[rbp+108h]
00007FF77E8F18E7 pop rdi
00007FF77E8F18E8 pop rbp
00007FF77E8F18E9 ret
int main(void)
{
001318C0 push ebp
001318C1 mov ebp,esp
001318C3 sub esp,0CCh
001318C9 push ebx
001318CA push esi
001318CB push edi
001318CC lea edi,[ebp-0Ch]
001318CF mov ecx,3
001318D4 mov eax,0CCCCCCCCh
001318D9 rep stos dword ptr es:[edi]
001318DB mov ecx,offset _B2D1B231_SimpleAddFunc@c (013C008h)
001318E0 call @__CheckForDebuggerJustMyCode@4 (013132Fh)
001318E5 nop
int result;
result = Add(3, 4);
001318E6 push 4
001318E8 push 3
001318EA call _Add (01310B9h)
001318EF add esp,8
001318F2 mov dword ptr [result],eax
printf("덧셈 결과1: %d\n", result);
001318F5 mov eax,dword ptr [result]
001318F8 push eax
001318F9 push offset string "\xb5\xa1\xbc\xc0 \xb0\xe1\xb0\xfa1: %d\n" (0137B30h)
001318FE call _printf (01310D7h)
00131903 add esp,8
result = Add(5, 8);
00131906 push 8
00131908 push 5
0013190A call _Add (01310B9h)
0013190F add esp,8
00131912 mov dword ptr [result],eax
printf("덧셈 결과2: %d\n", result);
00131915 mov eax,dword ptr [result]
00131918 push eax
00131919 push offset string "\xb5\xa1\xbc\xc0 \xb0\xe1\xb0\xfa2: %d\n" (0137B44h)
0013191E call _printf (01310D7h)
00131923 add esp,8
return 0;
00131926 xor eax,eax
}
00131928 pop edi
00131929 pop esi
0013192A pop ebx
0013192B add esp,0CCh
00131931 cmp ebp,esp
00131933 call __RTC_CheckEsp (0131253h)
00131938 mov esp,ebp
0013193A pop ebp
0013193B ret
#include <stdio.h>
int Add(int num1, int num2)
{
00131790 push ebp
00131791 mov ebp,esp
00131793 sub esp,0C0h
00131799 push ebx
0013179A push esi
0013179B push edi
0013179C mov edi,ebp
0013179E xor ecx,ecx
001317A0 mov eax,0CCCCCCCCh
001317A5 rep stos dword ptr es:[edi]
001317A7 mov ecx,offset _B2D1B231_SimpleAddFunc@c (013C008h)
001317AC call @__CheckForDebuggerJustMyCode@4 (013132Fh)
001317B1 nop
return num1 + num2;
001317B2 mov eax,dword ptr [num1]
001317B5 add eax,dword ptr [num2]
}
001317B8 pop edi
001317B9 pop esi
001317BA pop ebx
001317BB add esp,0C0h
001317C1 cmp ebp,esp
001317C3 call __RTC_CheckEsp (0131253h)
001317C8 mov esp,ebp
001317CA pop ebp
001317CB ret
* eax
32비트(4바이트) 정수 타입의 리턴값
* edx:eax
64비트(8바이트) 정수 타입의 리턴값
ㄴ edx는 리턴값을 상위 32비트 저장
ㄴ eax는 리턴값의 하위 32비트 저장
* 구조체 반환
작은 구조체(크기가 32비트 이하)는 eax에 반환
더 큰 구조체는 호출자가 메모리 주소를 전달하고, 함수는 해당 메모리에 값을 채워넣는다
* float, double
x87 FPU 환경
: 부동소수점 값은 항상 ST(0)에 반환
SSE 활성화 환경
: 부동소수점 값은 항상 xmm0에 반환
int main(void)
{
00C41B50 push ebp
00C41B51 mov ebp,esp
00C41B53 sub esp,0E4h
00C41B59 push ebx
00C41B5A push esi
00C41B5B push edi
00C41B5C lea edi,[ebp-24h]
00C41B5F mov ecx,9
00C41B64 mov eax,0CCCCCCCCh
00C41B69 rep stos dword ptr es:[edi]
00C41B6B mov ecx,offset _C50BD04E_SmartAddFunc@c (0C4C008h)
00C41B70 call @__CheckForDebuggerJustMyCode@4 (0C4134Dh)
00C41B75 nop
int result, num1, num2;
HowToUseThisProg();
00C41B76 call _HowToUseThisProg (0C4107Dh)
00C41B7B nop
num1 = ReadNum();
00C41B7C call _ReadNum (0C4133Eh)
00C41B81 mov dword ptr [num1],eax
num2 = ReadNum();
00C41B84 call _ReadNum (0C4133Eh)
00C41B89 mov dword ptr [num2],eax
result = Add(num1, num2);
00C41B8C mov eax,dword ptr [num2]
00C41B8F push eax
00C41B90 mov ecx,dword ptr [num1]
00C41B93 push ecx
00C41B94 call _Add (0C410CDh)
00C41B99 add esp,8
00C41B9C mov dword ptr [result],eax
ShowAddResult(result);
00C41B9F mov eax,dword ptr [result]
00C41BA2 push eax
00C41BA3 call _ShowAddResult (0C41064h)
00C41BA8 add esp,4
return 0;
00C41BAB xor eax,eax
}
00C41BAD pop edi
00C41BAE pop esi
00C41BAF pop ebx
00C41BB0 add esp,0E4h
00C41BB6 cmp ebp,esp
00C41BB8 call __RTC_CheckEsp (0C41267h)
00C41BBD mov esp,ebp
00C41BBF pop ebp
00C41BC0 ret
void HowToUseThisProg(void)
{
00C41820 push ebp
00C41821 mov ebp,esp
00C41823 sub esp,0C0h
00C41829 push ebx
00C4182A push esi
00C4182B push edi
00C4182C mov edi,ebp
00C4182E xor ecx,ecx
00C41830 mov eax,0CCCCCCCCh
00C41835 rep stos dword ptr es:[edi]
00C41837 mov ecx,offset _C50BD04E_SmartAddFunc@c (0C4C008h)
00C4183C call @__CheckForDebuggerJustMyCode@4 (0C4134Dh)
00C41841 nop
printf("두 개의 정수를 입력하시면 덧셈 결과가 출력됩니다\n");
00C41842 push offset string "\xb5\xce \xb0\xb3\xc0\xc7 \xc1\xa4\xbc\xf6\xb8\xa6 \xc0\xd4\xb7\xc2\xc7\xcf\xbd\xc3\xb8\xe9 \xb5\xa1\xbc\xc0 @"... (0C47B4Ch)
00C41847 call _printf (0C410EBh)
00C4184C add esp,4
printf("자! 그럼 두 개의 정수를 입력하세요\n");
00C4184F push offset string "\xc0\xda! \xb1\xd7\xb7\xb3 \xb5\xce \xb0\xb3\xc0\xc7 \xc1\xa4\xbc\xf6\xb8\xa6 \xc0\xd4\xb7\xc2\xc7\xcf\xbc@"... (0C47B88h)
00C41854 call _printf (0C410EBh)
00C41859 add esp,4
}
00C4185C pop edi
00C4185D pop esi
00C4185E pop ebx
00C4185F add esp,0C0h
00C41865 cmp ebp,esp
00C41867 call __RTC_CheckEsp (0C41267h)
00C4186C mov esp,ebp
00C4186E pop ebp
00C4186F ret
int ReadNum(void)
{
00C41890 push ebp
00C41891 mov ebp,esp
00C41893 sub esp,0D0h
00C41899 push ebx
00C4189A push esi
00C4189B push edi
00C4189C lea edi,[ebp-10h]
00C4189F mov ecx,4
00C418A4 mov eax,0CCCCCCCCh
00C418A9 rep stos dword ptr es:[edi]
00C418AB mov eax,dword ptr [__security_cookie (0C4A000h)]
00C418B0 xor eax,ebp
00C418B2 mov dword ptr [ebp-4],eax
00C418B5 mov ecx,offset _C50BD04E_SmartAddFunc@c (0C4C008h)
00C418BA call @__CheckForDebuggerJustMyCode@4 (0C4134Dh)
00C418BF nop
int num;
scanf_s("%d", &num);
00C418C0 lea eax,[num]
00C418C3 push eax
00C418C4 push offset string "%d" (0C47B48h)
00C418C9 call _scanf_s (0C412A3h)
00C418CE add esp,8
return num;
00C418D1 mov eax,dword ptr [num]
}
00C418D4 push edx
00C418D5 mov ecx,ebp
00C418D7 push eax
00C418D8 lea edx,ds:[0C41904h]
00C418DE call @_RTC_CheckStackVars@8 (0C41203h)
00C418E3 pop eax
00C418E4 pop edx
00C418E5 pop edi
00C418E6 pop esi
00C418E7 pop ebx
00C418E8 mov ecx,dword ptr [ebp-4]
00C418EB xor ecx,ebp
00C418ED call @__security_check_cookie@4 (0C41168h)
00C418F2 add esp,0D0h
00C418F8 cmp ebp,esp
00C418FA call __RTC_CheckEsp (0C41267h)
00C418FF mov esp,ebp
00C41901 pop ebp
00C41902 ret
#include <stdio.h>
int Add(int num1, int num2)
{
00C417D0 push ebp
00C417D1 mov ebp,esp
00C417D3 sub esp,0C0h
00C417D9 push ebx
00C417DA push esi
00C417DB push edi
00C417DC mov edi,ebp
00C417DE xor ecx,ecx
00C417E0 mov eax,0CCCCCCCCh
00C417E5 rep stos dword ptr es:[edi]
00C417E7 mov ecx,offset _C50BD04E_SmartAddFunc@c (0C4C008h)
00C417EC call @__CheckForDebuggerJustMyCode@4 (0C4134Dh)
00C417F1 nop
return num1 + num2;
00C417F2 mov eax,dword ptr [num1]
00C417F5 add eax,dword ptr [num2]
}
00C417F8 pop edi
00C417F9 pop esi
00C417FA pop ebx
00C417FB add esp,0C0h
00C41801 cmp ebp,esp
00C41803 call __RTC_CheckEsp (0C41267h)
00C41808 mov esp,ebp
00C4180A pop ebp
00C4180B ret
#include <stdio.h>
int main(void)
{
00831870 push ebp
00831871 mov ebp,esp
00831873 sub esp,0E4h
00831879 push ebx
0083187A push esi
0083187B push edi
0083187C lea edi,[ebp-24h]
0083187F mov ecx,9
00831884 mov eax,0CCCCCCCCh
00831889 rep stos dword ptr es:[edi]
0083188B mov ecx,offset _C443C804_AnotherLocalVar@c (083C008h)
00831890 call @__CheckForDebuggerJustMyCode@4 (083132Ah)
00831895 nop
int cnt;
for (cnt = 0; cnt < 3; cnt++)
00831896 mov dword ptr [cnt],0
0083189D jmp __$EncStackInitStart+2Ch (08318A8h)
0083189F mov eax,dword ptr [cnt]
008318A2 add eax,1
008318A5 mov dword ptr [cnt],eax
008318A8 cmp dword ptr [cnt],3
008318AC jge __$EncStackInitStart+5Ch (08318D8h)
{
int num = 0;
008318AE mov dword ptr [ebp-14h],0
num++;
008318B5 mov eax,dword ptr [ebp-14h]
008318B8 add eax,1
008318BB mov dword ptr [ebp-14h],eax
printf("%d번째 반복, 지역변수 num은 %d\n", cnt + 1, num);
008318BE mov eax,dword ptr [ebp-14h]
008318C1 push eax
008318C2 mov ecx,dword ptr [cnt]
008318C5 add ecx,1
008318C8 push ecx
008318C9 push offset string "%d\xb9\xf8\xc2\xb0 \xb9\xdd\xba\xb9, \xc1\xf6\xbf\xaa\xba\xaf\xbc\xf6 num\xc0\xba %d\n" (0837B30h)
008318CE call _printf (08310D2h)
008318D3 add esp,0Ch
}
008318D6 jmp __$EncStackInitStart+23h (083189Fh)
if (cnt == 3)
008318D8 cmp dword ptr [cnt],3
008318DC jne __$EncStackInitStart+83h (08318FFh)
{
int num = 7;
008318DE mov dword ptr [ebp-20h],7
num++;
008318E5 mov eax,dword ptr [ebp-20h]
008318E8 add eax,1
008318EB mov dword ptr [ebp-20h],eax
printf("if문 내에 존재하는 지역변수 num은 %d\n", num);
008318EE mov eax,dword ptr [ebp-20h]
008318F1 push eax
008318F2 push offset string "if\xb9\xae \xb3\xbb\xbf\xa1 \xc1\xb8\xc0\xe7\xc7\xcf\xb4\xc2 \xc1\xf6\xbf\xaa\xba\xaf\xbc\xf6 num@"... (0837B58h)
008318F7 call _printf (08310D2h)
008318FC add esp,8
}
return 0;
008318FF xor eax,eax
}
00831901 pop edi
00831902 pop esi
00831903 pop ebx
00831904 add esp,0E4h
0083190A cmp ebp,esp
0083190C call __RTC_CheckEsp (083124Eh)
00831911 mov esp,ebp
00831913 pop ebp
00831914 ret
* 같은 num 이름이지만 실질적으로 메모리상 따로 배분 받음
#include <stdio.h>
int main(void)
{
007E1870 push ebp
007E1871 mov ebp,esp
007E1873 sub esp,0CCh
007E1879 push ebx
007E187A push esi
007E187B push edi
007E187C lea edi,[ebp-0Ch]
007E187F mov ecx,3
007E1884 mov eax,0CCCCCCCCh
007E1889 rep stos dword ptr es:[edi]
007E188B mov ecx,offset _10E92DAD_LocalValHideVal@c (07EC008h)
007E1890 call @__CheckForDebuggerJustMyCode@4 (07E132Ah)
007E1895 nop
int num = 1;
007E1896 mov dword ptr [num],1
if (num == 1)
007E189D cmp dword ptr [num],1
007E18A1 jne __$EncStackInitStart+41h (07E18BDh)
{
//int num = 7;
num += 10;
007E18A3 mov eax,dword ptr [num]
007E18A6 add eax,0Ah
007E18A9 mov dword ptr [num],eax
printf("if문 내 지역변수 num: %d\n", num);
007E18AC mov eax,dword ptr [num]
007E18AF push eax
007E18B0 push offset string "if\xb9\xae \xb3\xbb \xc1\xf6\xbf\xaa\xba\xaf\xbc\xf6 num: %d\n" (07E7B30h)
007E18B5 call _printf (07E10D2h)
007E18BA add esp,8
}
printf("main 함수 내 지역변수 num: %d\n", num);
007E18BD mov eax,dword ptr [num]
007E18C0 push eax
007E18C1 push offset string "main \xc7\xd4\xbc\xf6 \xb3\xbb \xc1\xf6\xbf\xaa\xba\xaf\xbc\xf6 num: %d\n" (07E7B50h)
007E18C6 call _printf (07E10D2h)
007E18CB add esp,8
return 0;
007E18CE xor eax,eax
}
007E18D0 pop edi
007E18D1 pop esi
007E18D2 pop ebx
007E18D3 add esp,0CCh
007E18D9 cmp ebp,esp
007E18DB call __RTC_CheckEsp (07E124Eh)
007E18E0 mov esp,ebp
007E18E2 pop ebp
007E18E3 ret
#include <stdio.h>
int main(void)
{
00E51870 push ebp
00E51871 mov ebp,esp
00E51873 sub esp,0D8h
00E51879 push ebx
00E5187A push esi
00E5187B push edi
00E5187C lea edi,[ebp-18h]
00E5187F mov ecx,6
00E51884 mov eax,0CCCCCCCCh
00E51889 rep stos dword ptr es:[edi]
00E5188B mov ecx,offset _10E92DAD_LocalValHideVal@c (0E5C008h)
00E51890 call @__CheckForDebuggerJustMyCode@4 (0E5132Ah)
00E51895 nop
int num = 1;
00E51896 mov dword ptr [num],1
if (num == 1)
00E5189D cmp dword ptr [num],1
00E518A1 jne __$EncStackInitStart+48h (0E518C4h)
{
int num = 7;
00E518A3 mov dword ptr [ebp-14h],7
num += 10;
00E518AA mov eax,dword ptr [ebp-14h]
00E518AD add eax,0Ah
00E518B0 mov dword ptr [ebp-14h],eax
printf("if문 내 지역변수 num: %d\n", num);
00E518B3 mov eax,dword ptr [ebp-14h]
00E518B6 push eax
00E518B7 push offset string "if\xb9\xae \xb3\xbb \xc1\xf6\xbf\xaa\xba\xaf\xbc\xf6 num: %d\n" (0E57B30h)
00E518BC call _printf (0E510D2h)
00E518C1 add esp,8
}
printf("main 함수 내 지역변수 num: %d\n", num);
00E518C4 mov eax,dword ptr [num]
00E518C7 push eax
00E518C8 push offset string "main \xc7\xd4\xbc\xf6 \xb3\xbb \xc1\xf6\xbf\xaa\xba\xaf\xbc\xf6 num: %d\n" (0E57B50h)
00E518CD call _printf (0E510D2h)
00E518D2 add esp,8
return 0;
00E518D5 xor eax,eax
}
00E518D7 pop edi
00E518D8 pop esi
00E518D9 pop ebx
00E518DA add esp,0D8h
00E518E0 cmp ebp,esp
00E518E2 call __RTC_CheckEsp (0E5124Eh)
00E518E7 mov esp,ebp
00E518E9 pop ebp
00E518EA ret
* 지역 변수는 쓰레기 값을 가지고 있지만, 전역 변수는 기본 0으로 초기화 된다
#include <stdio.h>
void Add(int val);
int num; // 전역변수는 기본 0으로 초기화됨
int main(void)
{
009B18D0 push ebp
009B18D1 mov ebp,esp
009B18D3 sub esp,0C0h
009B18D9 push ebx
009B18DA push esi
009B18DB push edi
009B18DC mov edi,ebp
009B18DE xor ecx,ecx
009B18E0 mov eax,0CCCCCCCCh
009B18E5 rep stos dword ptr es:[edi]
009B18E7 mov ecx,offset _6499851B_GlobalVariable@c (09BC008h)
009B18EC call @__CheckForDebuggerJustMyCode@4 (09B132Fh)
009B18F1 nop
printf("num: %d\n", num);
009B18F2 mov eax,dword ptr [num (09BA61Ch)]
009B18F7 push eax
009B18F8 push offset string "num: %d\n" (09B7B30h)
009B18FD call _printf (09B10D7h)
009B1902 add esp,8
Add(3);
009B1905 push 3
009B1907 call _Add (09B10B9h)
009B190C add esp,4
printf("num: %d\n", num);
009B190F mov eax,dword ptr [num (09BA61Ch)]
009B1914 push eax
009B1915 push offset string "num: %d\n" (09B7B30h)
009B191A call _printf (09B10D7h)
009B191F add esp,8
num++; // 전역변수 num의 값 1 증가
009B1922 mov eax,dword ptr [num (09BA61Ch)]
009B1927 add eax,1
009B192A mov dword ptr [num (09BA61Ch)],eax
printf("num: %d\n", num);
009B192F mov eax,dword ptr [num (09BA61Ch)]
009B1934 push eax
009B1935 push offset string "num: %d\n" (09B7B30h)
009B193A call _printf (09B10D7h)
009B193F add esp,8
return 0;
009B1942 xor eax,eax
}
009B1944 pop edi
009B1945 pop esi
009B1946 pop ebx
009B1947 add esp,0C0h
009B194D cmp ebp,esp
009B194F call __RTC_CheckEsp (09B1253h)
009B1954 mov esp,ebp
009B1956 pop ebp
009B1957 ret
#include <stdio.h>
void Add(int val);
int num; // 전역변수는 기본 0으로 초기화됨
int main(void)
{
00007FF618BE18E0 push rbp
00007FF618BE18E2 push rdi
00007FF618BE18E3 sub rsp,0E8h
00007FF618BE18EA lea rbp,[rsp+20h]
00007FF618BE18EF lea rcx,[__6499851B_GlobalVariable@c (07FF618BF2008h)]
00007FF618BE18F6 call __CheckForDebuggerJustMyCode (07FF618BE1370h)
00007FF618BE18FB nop
printf("num: %d\n", num);
00007FF618BE18FC mov edx,dword ptr [num (07FF618BED924h)]
00007FF618BE1902 lea rcx,[string "num: %d\n" (07FF618BEAC28h)]
00007FF618BE1909 call printf (07FF618BE1195h)
00007FF618BE190E nop
Add(3);
00007FF618BE190F mov ecx,3
00007FF618BE1914 call Add (07FF618BE1348h)
00007FF618BE1919 nop
printf("num: %d\n", num);
00007FF618BE191A mov edx,dword ptr [num (07FF618BED924h)]
00007FF618BE1920 lea rcx,[string "num: %d\n" (07FF618BEAC28h)]
00007FF618BE1927 call printf (07FF618BE1195h)
00007FF618BE192C nop
num++; // 전역변수 num의 값 1 증가
00007FF618BE192D mov eax,dword ptr [num (07FF618BED924h)]
00007FF618BE1933 inc eax
00007FF618BE1935 mov dword ptr [num (07FF618BED924h)],eax
printf("num: %d\n", num);
00007FF618BE193B mov edx,dword ptr [num (07FF618BED924h)]
00007FF618BE1941 lea rcx,[string "num: %d\n" (07FF618BEAC28h)]
00007FF618BE1948 call printf (07FF618BE1195h)
00007FF618BE194D nop
return 0;
00007FF618BE194E xor eax,eax
}
00007FF618BE1950 lea rsp,[rbp+0C8h]
00007FF618BE1957 pop rdi
00007FF618BE1958 pop rbp
00007FF618BE1959 ret
* 지역 static 변수
지역변수에 static 선언이 붙게 되면, 이는 전역 변수의 성격을 지니는 변수가 된다
ㄴ 선언된 함수 내에서만 접근이 가능하다 (지역변수 특성)
ㄴ 딱 1회 초기화되고 프로그램 종료 시까지 메모리 공간에 존재한다 (전역변수 특성)
[정리하자면] 전역변수와 성격이 같다
초기화 하지 않으면 전역변수처럼 0으로 초기화되고,
프로그램 시작과 동시에 할당 및 초기화되어서 프로그램이 종료될 때까지 메모리 공간에 남아 있다
그럼에도 불구하고 존재하는 이유는 그건 접근의 범위를 함수로 제한하기 위함
int main(void)
{
00351900 push ebp
00351901 mov ebp,esp
00351903 sub esp,0CCh
00351909 push ebx
0035190A push esi
0035190B push edi
0035190C lea edi,[ebp-0Ch]
0035190F mov ecx,3
00351914 mov eax,0CCCCCCCCh
00351919 rep stos dword ptr es:[edi]
0035191B mov ecx,offset _A3ACC01E_StaticLocalVariable@c (035C008h)
00351920 call @__CheckForDebuggerJustMyCode@4 (035132Ah)
00351925 nop
int i;
for (i = 0; i < 3; i++)
00351926 mov dword ptr [i],0
0035192D jmp __$EncStackInitStart+2Ch (0351938h)
0035192F mov eax,dword ptr [i]
00351932 add eax,1
00351935 mov dword ptr [i],eax
00351938 cmp dword ptr [i],3
0035193C jge __$EncStackInitStart+3Ah (0351946h)
{
SimpleFunc();
0035193E call _SimpleFunc (03513B6h)
00351943 nop
}
00351944 jmp __$EncStackInitStart+23h (035192Fh)
return 0;
00351946 xor eax,eax
}
00351948 pop edi
00351949 pop esi
0035194A pop ebx
0035194B add esp,0CCh
00351951 cmp ebp,esp
00351953 call __RTC_CheckEsp (035124Eh)
00351958 mov esp,ebp
0035195A pop ebp
0035195B ret
#include <stdio.h>
void SimpleFunc(void)
{
00351790 push ebp
00351791 mov ebp,esp
00351793 sub esp,0CCh
00351799 push ebx
0035179A push esi
0035179B push edi
0035179C lea edi,[ebp-0Ch]
0035179F mov ecx,3
003517A4 mov eax,0CCCCCCCCh
003517A9 rep stos dword ptr es:[edi]
003517AB mov ecx,offset _A3ACC01E_StaticLocalVariable@c (035C008h)
003517B0 call @__CheckForDebuggerJustMyCode@4 (035132Ah)
003517B5 nop
static int num1 = 0;
int num2 = 0;
003517B6 mov dword ptr [num2],0
num1++, num2++;
003517BD mov eax,dword ptr [num1 (035A1B8h)]
003517C2 add eax,1
003517C5 mov dword ptr [num1 (035A1B8h)],eax
003517CA mov ecx,dword ptr [num2]
003517CD add ecx,1
003517D0 mov dword ptr [num2],ecx
printf("static: %d, local: %d\n", num1, num2);
003517D3 mov eax,dword ptr [num2]
003517D6 push eax
003517D7 mov ecx,dword ptr [num1 (035A1B8h)]
003517DD push ecx
003517DE push offset string "static: %d, local: %d\n" (0357B30h)
003517E3 call _printf (03510D2h)
003517E8 add esp,0Ch
}
003517EB pop edi
003517EC pop esi
003517ED pop ebx
003517EE add esp,0CCh
003517F4 cmp ebp,esp
003517F6 call __RTC_CheckEsp (035124Eh)
003517FB mov esp,ebp
003517FD pop ebp
003517FE ret
int main(void)
{
008818F0 push ebp
008818F1 mov ebp,esp
008818F3 sub esp,0C0h
008818F9 push ebx
008818FA push esi
008818FB push edi
008818FC mov edi,ebp
008818FE xor ecx,ecx
00881900 mov eax,0CCCCCCCCh
00881905 rep stos dword ptr es:[edi]
00881907 mov ecx,offset _346A806F_RecursiveFunc@c (088C008h)
0088190C call @__CheckForDebuggerJustMyCode@4 (088132Fh)
00881911 nop
Recursive(3);
00881912 push 3
00881914 call _Recursive (08811EAh)
00881919 add esp,4
return 0;
0088191C xor eax,eax
}
0088191E pop edi
0088191F pop esi
00881920 pop ebx
00881921 add esp,0C0h
00881927 cmp ebp,esp
00881929 call __RTC_CheckEsp (0881253h)
0088192E mov esp,ebp
00881930 pop ebp
00881931 ret
#include <stdio.h>
void Recursive(int num)
{
00881790 push ebp
00881791 mov ebp,esp
00881793 sub esp,0C0h
00881799 push ebx
0088179A push esi
0088179B push edi
0088179C mov edi,ebp
0088179E xor ecx,ecx
008817A0 mov eax,0CCCCCCCCh
008817A5 rep stos dword ptr es:[edi]
008817A7 mov ecx,offset _346A806F_RecursiveFunc@c (088C008h)
008817AC call @__CheckForDebuggerJustMyCode@4 (088132Fh)
008817B1 nop
if (num <= 0) // 재귀의 탈출 조건
008817B2 cmp dword ptr [num],0
008817B6 jg __$EncStackInitStart+1Eh (08817BAh)
return;
008817B8 jmp __$EncStackInitStart+3Eh (08817DAh)
printf("Recursive call! %d\n", num);
008817BA mov eax,dword ptr [num]
008817BD push eax
008817BE push offset string "Recursive call! %d\n" (0887B30h)
008817C3 call _printf (08810D2h)
008817C8 add esp,8
Recursive(num - 1);
008817CB mov eax,dword ptr [num]
008817CE sub eax,1
008817D1 push eax
008817D2 call _Recursive (08811EAh)
008817D7 add esp,4
}
008817DA pop edi
008817DB pop esi
008817DC pop ebx
008817DD add esp,0C0h
008817E3 cmp ebp,esp
008817E5 call __RTC_CheckEsp (0881253h)
008817EA mov esp,ebp
008817EC pop ebp
008817ED ret
* 실행 결과를 바탕으로 내린 결론
매개변수를 ecx, rcx로 담아서 넘겨주고 있음
[그래서] 스택 정리를 따로 하지 않았지만
[만약] 레지스터 다 쓰고 스택을 썼다면 호출자 쪽에서 정리를 해야 함
int main(void)
{
00007FF663EF1900 push rbp
00007FF663EF1902 push rdi
00007FF663EF1903 sub rsp,0E8h
00007FF663EF190A lea rbp,[rsp+20h]
00007FF663EF190F lea rcx,[__346A806F_RecursiveFunc@c (07FF663F02008h)]
00007FF663EF1916 call __CheckForDebuggerJustMyCode (07FF663EF1370h)
00007FF663EF191B nop
Recursive(3);
00007FF663EF191C mov ecx,3
00007FF663EF1921 call Recursive (07FF663EF1014h)
00007FF663EF1926 nop
return 0;
00007FF663EF1927 xor eax,eax
}
00007FF663EF1929 lea rsp,[rbp+0C8h]
00007FF663EF1930 pop rdi
00007FF663EF1931 pop rbp
00007FF663EF1932 ret
#include <stdio.h>
void Recursive(int num)
{
00007FF663EF17B0 mov dword ptr [rsp+8],ecx
00007FF663EF17B4 push rbp
00007FF663EF17B5 push rdi
00007FF663EF17B6 sub rsp,0E8h
00007FF663EF17BD lea rbp,[rsp+20h]
00007FF663EF17C2 lea rcx,[__346A806F_RecursiveFunc@c (07FF663F02008h)]
00007FF663EF17C9 call __CheckForDebuggerJustMyCode (07FF663EF1370h)
00007FF663EF17CE nop
if (num <= 0) // 재귀의 탈출 조건
00007FF663EF17CF cmp dword ptr [num],0
00007FF663EF17D6 jg Recursive+2Ah (07FF663EF17DAh)
return;
00007FF663EF17D8 jmp Recursive+4Dh (07FF663EF17FDh)
printf("Recursive call! %d\n", num);
00007FF663EF17DA mov edx,dword ptr [num]
00007FF663EF17E0 lea rcx,[string "Recursive call! %d\n" (07FF663EFAC28h)]
00007FF663EF17E7 call printf (07FF663EF119Ah)
00007FF663EF17EC nop
Recursive(num - 1);
00007FF663EF17ED mov eax,dword ptr [num]
00007FF663EF17F3 dec eax
00007FF663EF17F5 mov ecx,eax
00007FF663EF17F7 call Recursive (07FF663EF1014h)
00007FF663EF17FC nop
}
00007FF663EF17FD lea rsp,[rbp+0C8h]
00007FF663EF1804 pop rdi
00007FF663EF1805 pop rbp
00007FF663EF1806 ret
int main(void)
{
005C18E0 push ebp
005C18E1 mov ebp,esp
005C18E3 sub esp,0C0h
005C18E9 push ebx
005C18EA push esi
005C18EB push edi
005C18EC mov edi,ebp
005C18EE xor ecx,ecx
005C18F0 mov eax,0CCCCCCCCh
005C18F5 rep stos dword ptr es:[edi]
005C18F7 mov ecx,offset _021A3472_RecursiveFactorial@c (05CC008h)
005C18FC call @__CheckForDebuggerJustMyCode@4 (05C132Fh)
005C1901 nop
printf("!1 = %d\n", Factorial(1));
005C1902 push 1
005C1904 call _Factorial (05C11EAh)
005C1909 add esp,4
005C190C push eax
005C190D push offset string "!1 = %d\n" (05C7B30h)
005C1912 call _printf (05C10D2h)
005C1917 add esp,8
printf("!1 = %d\n", Factorial(2));
005C191A push 2
005C191C call _Factorial (05C11EAh)
005C1921 add esp,4
005C1924 push eax
005C1925 push offset string "!1 = %d\n" (05C7B30h)
005C192A call _printf (05C10D2h)
005C192F add esp,8
printf("!1 = %d\n", Factorial(3));
005C1932 push 3
005C1934 call _Factorial (05C11EAh)
005C1939 add esp,4
005C193C push eax
005C193D push offset string "!1 = %d\n" (05C7B30h)
005C1942 call _printf (05C10D2h)
005C1947 add esp,8
printf("!1 = %d\n", Factorial(4));
005C194A push 4
005C194C call _Factorial (05C11EAh)
005C1951 add esp,4
005C1954 push eax
005C1955 push offset string "!1 = %d\n" (05C7B30h)
005C195A call _printf (05C10D2h)
005C195F add esp,8
printf("!1 = %d\n", Factorial(9));
005C1962 push 9
005C1964 call _Factorial (05C11EAh)
005C1969 add esp,4
005C196C push eax
005C196D push offset string "!1 = %d\n" (05C7B30h)
005C1972 call _printf (05C10D2h)
005C1977 add esp,8
return 0;
005C197A xor eax,eax
}
005C197C pop edi
005C197D pop esi
005C197E pop ebx
005C197F add esp,0C0h
005C1985 cmp ebp,esp
005C1987 call __RTC_CheckEsp (05C1253h)
005C198C mov esp,ebp
005C198E pop ebp
005C198F ret
#include <stdio.h>
int Factorial(int n)
{
005C1790 push ebp
005C1791 mov ebp,esp
005C1793 sub esp,0C0h
005C1799 push ebx
005C179A push esi
005C179B push edi
005C179C mov edi,ebp
005C179E xor ecx,ecx
005C17A0 mov eax,0CCCCCCCCh
005C17A5 rep stos dword ptr es:[edi]
005C17A7 mov ecx,offset _021A3472_RecursiveFactorial@c (05CC008h)
005C17AC call @__CheckForDebuggerJustMyCode@4 (05C132Fh)
005C17B1 nop
if (n == 0)
005C17B2 cmp dword ptr [n],0
005C17B6 jne __$EncStackInitStart+25h (05C17C1h)
return 1;
005C17B8 mov eax,1
005C17BD jmp __$EncStackInitStart+38h (05C17D4h)
005C17BF jmp __$EncStackInitStart+38h (05C17D4h)
else
return n * Factorial(n - 1);
005C17C1 mov eax,dword ptr [n]
005C17C4 sub eax,1
005C17C7 push eax
005C17C8 call _Factorial (05C11EAh)
005C17CD add esp,4
005C17D0 imul eax,dword ptr [n]
}
005C17D4 pop edi
005C17D5 pop esi
005C17D6 pop ebx
005C17D7 add esp,0C0h
005C17DD cmp ebp,esp
005C17DF call __RTC_CheckEsp (05C1253h)
005C17E4 mov esp,ebp
005C17E6 pop ebp
005C17E7 ret
int main(void)
{
00007FF7540E1900 push rbp
00007FF7540E1902 push rdi
00007FF7540E1903 sub rsp,0E8h
00007FF7540E190A lea rbp,[rsp+20h]
00007FF7540E190F lea rcx,[__021A3472_RecursiveFactorial@c (07FF7540F2008h)]
00007FF7540E1916 call __CheckForDebuggerJustMyCode (07FF7540E1370h)
00007FF7540E191B nop
printf("!1 = %d\n", Factorial(1));
00007FF7540E191C mov ecx,1
00007FF7540E1921 call Factorial (07FF7540E1069h)
00007FF7540E1926 mov edx,eax
00007FF7540E1928 lea rcx,[string "!1 = %d\n" (07FF7540EAC28h)]
00007FF7540E192F call printf (07FF7540E119Ah)
00007FF7540E1934 nop
printf("!1 = %d\n", Factorial(2));
00007FF7540E1935 mov ecx,2
00007FF7540E193A call Factorial (07FF7540E1069h)
00007FF7540E193F mov edx,eax
00007FF7540E1941 lea rcx,[string "!1 = %d\n" (07FF7540EAC28h)]
00007FF7540E1948 call printf (07FF7540E119Ah)
00007FF7540E194D nop
printf("!1 = %d\n", Factorial(3));
00007FF7540E194E mov ecx,3
00007FF7540E1953 call Factorial (07FF7540E1069h)
00007FF7540E1958 mov edx,eax
00007FF7540E195A lea rcx,[string "!1 = %d\n" (07FF7540EAC28h)]
00007FF7540E1961 call printf (07FF7540E119Ah)
00007FF7540E1966 nop
printf("!1 = %d\n", Factorial(4));
00007FF7540E1967 mov ecx,4
00007FF7540E196C call Factorial (07FF7540E1069h)
00007FF7540E1971 mov edx,eax
00007FF7540E1973 lea rcx,[string "!1 = %d\n" (07FF7540EAC28h)]
00007FF7540E197A call printf (07FF7540E119Ah)
00007FF7540E197F nop
printf("!1 = %d\n", Factorial(9));
00007FF7540E1980 mov ecx,9
00007FF7540E1985 call Factorial (07FF7540E1069h)
00007FF7540E198A mov edx,eax
00007FF7540E198C lea rcx,[string "!1 = %d\n" (07FF7540EAC28h)]
00007FF7540E1993 call printf (07FF7540E119Ah)
00007FF7540E1998 nop
return 0;
00007FF7540E1999 xor eax,eax
}
00007FF7540E199B lea rsp,[rbp+0C8h]
00007FF7540E19A2 pop rdi
00007FF7540E19A3 pop rbp
00007FF7540E19A4 ret
#include <stdio.h>
int Factorial(int n)
{
00007FF7540E17B0 mov dword ptr [rsp+8],ecx
00007FF7540E17B4 push rbp
00007FF7540E17B5 push rdi
00007FF7540E17B6 sub rsp,0E8h
00007FF7540E17BD lea rbp,[rsp+20h]
00007FF7540E17C2 lea rcx,[__021A3472_RecursiveFactorial@c (07FF7540F2008h)]
00007FF7540E17C9 call __CheckForDebuggerJustMyCode (07FF7540E1370h)
00007FF7540E17CE nop
if (n == 0)
00007FF7540E17CF cmp dword ptr [n],0
00007FF7540E17D6 jne Factorial+31h (07FF7540E17E1h)
return 1;
00007FF7540E17D8 mov eax,1
00007FF7540E17DD jmp Factorial+4Bh (07FF7540E17FBh)
00007FF7540E17DF jmp Factorial+4Bh (07FF7540E17FBh)
else
return n * Factorial(n - 1);
00007FF7540E17E1 mov eax,dword ptr [n]
00007FF7540E17E7 dec eax
00007FF7540E17E9 mov ecx,eax
00007FF7540E17EB call Factorial (07FF7540E1069h)
00007FF7540E17F0 mov ecx,dword ptr [n]
00007FF7540E17F6 imul ecx,eax
00007FF7540E17F9 mov eax,ecx
}
00007FF7540E17FB lea rsp,[rbp+0C8h]
00007FF7540E1802 pop rdi
00007FF7540E1803 pop rbp
00007FF7540E1804 ret
* 매개변수
edx, rcx 이용
'IT공부 > IT서적' 카테고리의 다른 글
[윤성우 열혈 C프로그래밍] 디버깅 빌드, 어셈블리 코드 - Chapter11, Chapter12, Chapter13, Chapter14 (0) | 2025.01.27 |
---|---|
[뇌를 자극하는 윈도우즈 시스템 프로그래밍] 8장. 프로세스간 통신(IPC) - 2 (0) | 2025.01.21 |
[윤성우 열혈 C프로그래밍] 디버깅 빌드, 어셈블리 코드 - Chapter8 (0) | 2025.01.16 |
[윤성우 열혈 C프로그래밍] 디버깅 빌드, 어셈블리 코드 - Chapter6, Chapter7 (0) | 2025.01.15 |
[윤성우 열혈 C프로그래밍] 디버깅 빌드, 어셈블리 코드 - Chapter5 (0) | 2025.01.13 |