IT공부/IT서적

[윤성우 열혈 C프로그래밍] 디버깅 빌드, 어셈블리 코드 - Chapter9

shine94 2025. 1. 18. 23:14
#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 이용