IT공부/IT서적

[윤성우 열혈 C++프로그래밍] 어셈블리 코드 - Chapter3, Chapter4

shine94 2025. 3. 29. 21:52

* 구조체

   연관된 데이터를 묶을 수 있는 문법적 장치

 

int main(void)
{
00007FF61C911160  push        rsi  
00007FF61C911162  push        rdi  
00007FF61C911163  sub         rsp,78h  
00007FF61C911167  mov         rax,qword ptr [__security_cookie (07FF61C915000h)]  
00007FF61C91116E  xor         rax,rsp  
00007FF61C911171  mov         qword ptr [rsp+60h],rax  
	Car run99 = { "run99", 100, 0 };
00007FF61C911176  lea         rax,[run99]  
00007FF61C91117B  lea         rcx,[std::_Fake_alloc+20h (07FF61C9132ECh)]  
00007FF61C911182  mov         rdi,rax  
00007FF61C911185  mov         rsi,rcx  
00007FF61C911188  mov         ecx,6  
00007FF61C91118D  rep movs    byte ptr [rdi],byte ptr [rsi]  
00007FF61C91118F  lea         rax,[rsp+26h]  
00007FF61C911194  mov         rdi,rax  
00007FF61C911197  xor         eax,eax  
00007FF61C911199  mov         ecx,0Eh  
00007FF61C91119E  rep stos    byte ptr [rdi]  
00007FF61C9111A0  mov         dword ptr [rsp+34h],64h  
00007FF61C9111A8  mov         dword ptr [rsp+38h],0  
	Accel(run99);
00007FF61C9111B0  lea         rcx,[run99]  
00007FF61C9111B5  call        Accel (07FF61C9110C0h)  
	Accel(run99);
00007FF61C9111BA  lea         rcx,[run99]  
00007FF61C9111BF  call        Accel (07FF61C9110C0h)  
	ShowCarState(run99);
00007FF61C9111C4  lea         rcx,[run99]  
00007FF61C9111C9  call        ShowCarState (07FF61C911000h)  
	Break(run99);
00007FF61C9111CE  lea         rcx,[run99]  
00007FF61C9111D3  call        Break (07FF61C911120h)  
	ShowCarState(run99);
00007FF61C9111D8  lea         rcx,[run99]  
00007FF61C9111DD  call        ShowCarState (07FF61C911000h)  

	Car run77 = { "run77", 100, 0 };
00007FF61C9111E2  lea         rax,[run77]  
00007FF61C9111E7  lea         rcx,[std::_Fake_alloc+28h (07FF61C9132F4h)]  
00007FF61C9111EE  mov         rdi,rax  
00007FF61C9111F1  mov         rsi,rcx  
00007FF61C9111F4  mov         ecx,6  
00007FF61C9111F9  rep movs    byte ptr [rdi],byte ptr [rsi]  
00007FF61C9111FB  lea         rax,[rsp+46h]  
00007FF61C911200  mov         rdi,rax  
00007FF61C911203  xor         eax,eax  
00007FF61C911205  mov         ecx,0Eh  
00007FF61C91120A  rep stos    byte ptr [rdi]  
00007FF61C91120C  mov         dword ptr [rsp+54h],64h  
00007FF61C911214  mov         dword ptr [rsp+58h],0  
	Accel(run77);
00007FF61C91121C  lea         rcx,[run77]  
00007FF61C911221  call        Accel (07FF61C9110C0h)  
	Break(run77);
00007FF61C911226  lea         rcx,[run77]  
00007FF61C91122B  call        Break (07FF61C911120h)  
	ShowCarState(run77);
00007FF61C911230  lea         rcx,[run77]  
00007FF61C911235  call        ShowCarState (07FF61C911000h)  

	return 0;
00007FF61C91123A  xor         eax,eax  
}
00007FF61C91123C  mov         rcx,qword ptr [rsp+60h]  
00007FF61C911241  xor         rcx,rsp  
00007FF61C911244  call        __security_check_cookie (07FF61C911A10h)  
00007FF61C911249  add         rsp,78h  
00007FF61C91124D  pop         rdi  
00007FF61C91124E  pop         rsi  
00007FF61C91124F  ret

 

 

* 00007FF61C91117B  lea         rcx,[std::_Fake_alloc+20h (07FF61C9132ECh)] 

   ㄴ _Fake_alloc

       문자열이 들어 있는 메모리 블럭의 이름일 뿐

 

* 구조체 안에 함수 삽입 가능

   모든 구조체 변수 내에 함수는 별도로 존재하는 것이 아니라 하나의 함수를 공유한다

 

int main(void)
{
00007FF7B06C1120  push        rsi  
00007FF7B06C1122  push        rdi  
00007FF7B06C1123  sub         rsp,78h  
00007FF7B06C1127  mov         rax,qword ptr [__security_cookie (07FF7B06C5000h)]  
00007FF7B06C112E  xor         rax,rsp  
00007FF7B06C1131  mov         qword ptr [rsp+60h],rax  
	Car run99 = { "run99", 100, 0 };
00007FF7B06C1136  lea         rax,[run99]  
00007FF7B06C113B  lea         rcx,[string "\xc7\xf6\xc0\xe7\xbc\xd3\xb5\xb5: "+0Ch (07FF7B06C32ECh)]  
00007FF7B06C1142  mov         rdi,rax  
00007FF7B06C1145  mov         rsi,rcx  
00007FF7B06C1148  mov         ecx,6  
00007FF7B06C114D  rep movs    byte ptr [rdi],byte ptr [rsi]  
00007FF7B06C114F  lea         rax,[rsp+26h]  
00007FF7B06C1154  mov         rdi,rax  
00007FF7B06C1157  xor         eax,eax  
00007FF7B06C1159  mov         ecx,0Eh  
00007FF7B06C115E  rep stos    byte ptr [rdi]  
00007FF7B06C1160  mov         dword ptr [rsp+34h],64h  
00007FF7B06C1168  mov         dword ptr [rsp+38h],0  
	run99.Accel();
00007FF7B06C1170  lea         rcx,[run99]  
00007FF7B06C1175  call        Car::Accel (07FF7B06C10C0h)  
	run99.Accel();
00007FF7B06C117A  lea         rcx,[run99]  
00007FF7B06C117F  call        Car::Accel (07FF7B06C10C0h)  
	run99.ShowCarState();
00007FF7B06C1184  lea         rcx,[run99]  
00007FF7B06C1189  call        Car::ShowCarState (07FF7B06C1000h)  
	run99.Break();
00007FF7B06C118E  cmp         dword ptr [rsp+38h],0Ah  
00007FF7B06C1193  jge         main+7Fh (07FF7B06C119Fh)  
00007FF7B06C1195  mov         dword ptr [rsp+38h],0  
00007FF7B06C119D  jmp         main+8Ah (07FF7B06C11AAh)  
00007FF7B06C119F  mov         eax,dword ptr [rsp+38h]  
00007FF7B06C11A3  sub         eax,0Ah  
00007FF7B06C11A6  mov         dword ptr [rsp+38h],eax  
	run99.ShowCarState();
00007FF7B06C11AA  lea         rcx,[run99]  
00007FF7B06C11AF  call        Car::ShowCarState (07FF7B06C1000h)  

	cout << sizeof(run99) << endl;
00007FF7B06C11B4  mov         edx,1Ch  
00007FF7B06C11B9  mov         rcx,qword ptr [__imp_std::cout (07FF7B06C3090h)]  
00007FF7B06C11C0  call        qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7B06C3080h)]  
00007FF7B06C11C6  lea         rdx,[std::endl<char,std::char_traits<char> > (07FF7B06C19C0h)]  
00007FF7B06C11CD  mov         rcx,rax  
00007FF7B06C11D0  call        qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF7B06C3098h)]  

	Car run77 = { "run77", 100, 0 };
00007FF7B06C11D6  lea         rax,[run77]  
00007FF7B06C11DB  lea         rcx,[std::_Fake_alloc+2h (07FF7B06C32F4h)]  
00007FF7B06C11E2  mov         rdi,rax  
00007FF7B06C11E5  mov         rsi,rcx  
00007FF7B06C11E8  mov         ecx,6  
00007FF7B06C11ED  rep movs    byte ptr [rdi],byte ptr [rsi]  
00007FF7B06C11EF  lea         rax,[rsp+46h]  
00007FF7B06C11F4  mov         rdi,rax  
00007FF7B06C11F7  xor         eax,eax  
00007FF7B06C11F9  mov         ecx,0Eh  
00007FF7B06C11FE  rep stos    byte ptr [rdi]  
00007FF7B06C1200  mov         dword ptr [rsp+54h],64h  
00007FF7B06C1208  mov         dword ptr [rsp+58h],0  
	run77.Accel();
00007FF7B06C1210  lea         rcx,[run77]  
00007FF7B06C1215  call        Car::Accel (07FF7B06C10C0h)  
	run77.Break();
00007FF7B06C121A  cmp         dword ptr [rsp+58h],0Ah  
00007FF7B06C121F  jge         main+10Bh (07FF7B06C122Bh)  
00007FF7B06C1221  mov         dword ptr [rsp+58h],0  
00007FF7B06C1229  jmp         main+116h (07FF7B06C1236h)  
00007FF7B06C122B  mov         eax,dword ptr [rsp+58h]  
00007FF7B06C122F  sub         eax,0Ah  
00007FF7B06C1232  mov         dword ptr [rsp+58h],eax  
	run77.ShowCarState();
00007FF7B06C1236  lea         rcx,[run77]  
00007FF7B06C123B  call        Car::ShowCarState (07FF7B06C1000h)  

	return 0;
00007FF7B06C1240  xor         eax,eax  
}
00007FF7B06C1242  mov         rcx,qword ptr [rsp+60h]  
00007FF7B06C1247  xor         rcx,rsp  
00007FF7B06C124A  call        __security_check_cookie (07FF7B06C1A20h)  
00007FF7B06C124F  add         rsp,78h  
00007FF7B06C1253  pop         rdi  
00007FF7B06C1254  pop         rsi  
00007FF7B06C1255  ret

 

* 구조체 안에 enum 상수 선언 가능

   ㄴ enum은 컴파일러가 읽기 좋게 만든 이름 붙은 정수 상수

   ㄴ 컴파일 되면 전부 정수 숫자(기본적으로 int)로 바꿈

   ㄴ 그래서 enum 자체는 메모리에 올라가지도 않고, 실행 중에 존재하지도 않음

 

	void Accel()
	{
00007FF7372810C0  mov         qword ptr [this],rcx  
		if (fuelGauge <= 0)
00007FF7372810C5  mov         rax,qword ptr [this]  
00007FF7372810CA  cmp         dword ptr [rax+14h],0  
00007FF7372810CE  jg          Car::Accel+14h (07FF7372810D4h)  
			return;
00007FF7372810D0  jmp         Car::Accel+5Ah (07FF73728111Ah)  
00007FF7372810D2  jmp         Car::Accel+27h (07FF7372810E7h)  
		else
			fuelGauge -= FUEL_STEP;
00007FF7372810D4  mov         rax,qword ptr [this]  
00007FF7372810D9  mov         eax,dword ptr [rax+14h]  
00007FF7372810DC  sub         eax,2  
00007FF7372810DF  mov         rcx,qword ptr [this]  
00007FF7372810E4  mov         dword ptr [rcx+14h],eax  

		if (curSpeed + ACC_STEP >= MAX_SPD)
00007FF7372810E7  mov         rax,qword ptr [this]  
00007FF7372810EC  mov         eax,dword ptr [rax+18h]  
00007FF7372810EF  add         eax,0Ah  
00007FF7372810F2  cmp         eax,0C8h  
00007FF7372810F7  jl          Car::Accel+47h (07FF737281107h)  
		{
			curSpeed = MAX_SPD;
00007FF7372810F9  mov         rax,qword ptr [this]  
00007FF7372810FE  mov         dword ptr [rax+18h],0C8h  
			return;
00007FF737281105  jmp         Car::Accel+5Ah (07FF73728111Ah)  
		}

		curSpeed += ACC_STEP;
00007FF737281107  mov         rax,qword ptr [this]  
00007FF73728110C  mov         eax,dword ptr [rax+18h]  
00007FF73728110F  add         eax,0Ah  
00007FF737281112  mov         rcx,qword ptr [this]  
00007FF737281117  mov         dword ptr [rcx+18h],eax  
	}
00007FF73728111A  ret

 

* 구조체 안에 함수가 정의되어 있으면 함수를 인라인 처리하라는 의미가 내포됨

   ㄴ 함수를 구조체 밖으로 빼내면, 그러한 의미가 사라짐

   [중요한 사실] 인라인은 강제 아님

                          inline 키워드를 붙이든

                          구조체 안에 함수를 정의하든

                          컴파일러가 판단해서 인라인 할지 말지 결정함

 

* 인라인 함수

   함수를 호출하지 말고, 함수 몸체를 그 자리에 복사해서 붙이는 것

 

* register 변수(C언어)

   자주 쓰는 변수 레지스터 넣기 요청(강제는 아님)

 

* 접근제어 지시자(접근제어 레이블)

   public           어디서든 접근 허용

   protected     상속관계에 놓여있을 때, 유도 클래스에서 접근 허용

   private         클래스 내에서만 접근 허용

 

int main(void)
{
00007FF633861000  sub         rsp,78h  
00007FF633861004  mov         rax,qword ptr [__security_cookie (07FF633865000h)]  
00007FF63386100B  xor         rax,rsp  
00007FF63386100E  mov         qword ptr [rsp+60h],rax  
	Car run99;
	run99.InitMembers((char*)"run99", 100);
00007FF633861013  mov         r8d,64h  
00007FF633861019  lea         rdx,[__xmm@ffffffffffffffffffffffffffffffff+10h (07FF6338632D0h)]  
00007FF633861020  lea         rcx,[run99]  
00007FF633861025  call        Car::InitMembers (07FF6338610D0h)  
	run99.Accel();
00007FF63386102A  lea         rcx,[run99]  
00007FF63386102F  call        Car::Accel (07FF6338611E0h)  
	run99.Accel();
00007FF633861034  lea         rcx,[run99]  
00007FF633861039  call        Car::Accel (07FF6338611E0h)  
	run99.ShowCarState();
00007FF63386103E  lea         rcx,[run99]  
00007FF633861043  call        Car::ShowCarState (07FF633861120h)  
	run99.Break();
00007FF633861048  lea         rcx,[run99]  
00007FF63386104D  call        Car::Break (07FF633861240h)  
	run99.ShowCarState();
00007FF633861052  lea         rcx,[run99]  
00007FF633861057  call        Car::ShowCarState (07FF633861120h)  

	cout << sizeof(run99) << endl;
00007FF63386105C  mov         edx,1Ch  
00007FF633861061  mov         rcx,qword ptr [__imp_std::cout (07FF633863090h)]  
00007FF633861068  call        qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF633863080h)]  
00007FF63386106E  lea         rdx,[std::endl<char,std::char_traits<char> > (07FF6338614C0h)]  
00007FF633861075  mov         rcx,rax  
00007FF633861078  call        qword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07FF633863098h)]  

	Car run77;
	run77.InitMembers((char*)"run77", 100);
00007FF63386107E  mov         r8d,64h  
00007FF633861084  lea         rdx,[std::_Fake_alloc+2h (07FF6338632D8h)]  
00007FF63386108B  lea         rcx,[run77]  
00007FF633861090  call        Car::InitMembers (07FF6338610D0h)  
	run77.Accel();
00007FF633861095  lea         rcx,[run77]  
00007FF63386109A  call        Car::Accel (07FF6338611E0h)  
	run77.Break();
00007FF63386109F  lea         rcx,[run77]  
00007FF6338610A4  call        Car::Break (07FF633861240h)  
	run77.ShowCarState();
00007FF6338610A9  lea         rcx,[run77]  
00007FF6338610AE  call        Car::ShowCarState (07FF633861120h)  

	return 0;
00007FF6338610B3  xor         eax,eax  
}
00007FF6338610B5  mov         rcx,qword ptr [rsp+60h]  
00007FF6338610BA  xor         rcx,rsp  
00007FF6338610BD  call        __security_check_cookie (07FF633861A40h)  
00007FF6338610C2  add         rsp,78h  
00007FF6338610C6  ret

 

* 레이블

   특정 위치 정보를 알리는 레이블(라벨)

 

* 인라인 함수는 헤더파일에 함께 넣어야 함

   ㄴ 컴파일 과정에서 함수의 호출문이 있는 곳에 몸체 부분이 삽입되어야 하므로!

 

* 객체

   현실에 존재하는 사물과 대상, 그리고 그에 따른 행동을 있는 그대로 실사화시키는 형태의 프로그래밍

   하나 이상의 상태 정보와 하나 이상의 행동으로 구성

 

객체 지향의 중요한 요소

   정보은닉, 캡슐화

 

int main(void)
{
00007FF7E84B1080  sub         rsp,38h  
00007FF7E84B1084  mov         rax,qword ptr [__security_cookie (07FF7E84B5000h)]  
00007FF7E84B108B  xor         rax,rsp  
00007FF7E84B108E  mov         qword ptr [rsp+28h],rax  
	CONTAC600 cap;
	ColdPatient sufferer;
	sufferer.TakeCONTAC600(cap);
00007FF7E84B1093  lea         rcx,[cap]  
00007FF7E84B1098  call        CONTAC600::Take (07FF7E84B1000h)  
00007FF7E84B109D  nop  

	return 0;
00007FF7E84B109E  xor         eax,eax  
}
00007FF7E84B10A0  mov         rcx,qword ptr [rsp+28h]  
00007FF7E84B10A5  xor         rcx,rsp  
00007FF7E84B10A8  call        __security_check_cookie (07FF7E84B1880h)  
00007FF7E84B10AD  add         rsp,38h  
00007FF7E84B10B1  ret

 

* 생성자

   함수의 일종이니 오버로딩이 가능

   함수의 일종이니 매개변수에 디폴트 값을 설정 가능

 

int main(void)
{
00007FF6A8A91050  sub         rsp,48h  
00007FF6A8A91054  mov         rax,qword ptr [__security_cookie (07FF6A8A95000h)]  
00007FF6A8A9105B  xor         rax,rsp  
00007FF6A8A9105E  mov         qword ptr [rsp+38h],rax  
	SimpleClass sc1;
00007FF6A8A91063  mov         dword ptr [sc1],0  
00007FF6A8A9106B  mov         dword ptr [rsp+24h],0  
	sc1.ShowData();
00007FF6A8A91073  lea         rcx,[sc1]  
00007FF6A8A91078  call        SimpleClass::ShowData (07FF6A8A91000h)  

	SimpleClass sc2(100);
00007FF6A8A9107D  mov         dword ptr [sc2],64h  
00007FF6A8A91085  mov         dword ptr [rsp+2Ch],0  
	sc2.ShowData();
00007FF6A8A9108D  lea         rcx,[sc2]  
00007FF6A8A91092  call        SimpleClass::ShowData (07FF6A8A91000h)  

	SimpleClass sc3(100, 200);
00007FF6A8A91097  mov         dword ptr [sc3],64h  
00007FF6A8A9109F  mov         dword ptr [rsp+34h],0C8h  
	sc3.ShowData();
00007FF6A8A910A7  lea         rcx,[sc3]  
00007FF6A8A910AC  call        SimpleClass::ShowData (07FF6A8A91000h)  

	return 0;
00007FF6A8A910B1  xor         eax,eax  
}
00007FF6A8A910B3  mov         rcx,qword ptr [rsp+38h]  
00007FF6A8A910B8  xor         rcx,rsp  
00007FF6A8A910BB  call        __security_check_cookie (07FF6A8A91830h)  
00007FF6A8A910C0  add         rsp,48h  
00007FF6A8A910C4  ret

   

int main(void)
{
006510E0  push        ebp  
006510E1  mov         ebp,esp  
006510E3  sub         esp,1Ch  
006510E6  mov         eax,dword ptr [__security_cookie (0655000h)]  
006510EB  xor         eax,ebp  
006510ED  mov         dword ptr [ebp-4],eax  
	SimpleClass sc1;
006510F0  lea         ecx,[sc1]  
006510F3  call        SimpleClass::SimpleClass (0651000h)  
	sc1.ShowData();
006510F8  lea         ecx,[sc1]  
006510FB  call        SimpleClass::ShowData (0651090h)  

	SimpleClass sc2(100);
00651100  push        64h  
00651102  lea         ecx,[sc2]  
00651105  call        SimpleClass::SimpleClass (0651030h)  
	sc2.ShowData();
0065110A  lea         ecx,[sc2]  
0065110D  call        SimpleClass::ShowData (0651090h)  

	SimpleClass sc3(100, 200);
00651112  push        0C8h  
00651117  push        64h  
00651119  lea         ecx,[sc3]  
0065111C  call        SimpleClass::SimpleClass (0651060h)  
	sc3.ShowData();
00651121  lea         ecx,[sc3]  
00651124  call        SimpleClass::ShowData (0651090h)  

	return 0;
00651129  xor         eax,eax  
}
0065112B  mov         ecx,dword ptr [ebp-4]  
0065112E  xor         ecx,ebp  
00651130  call        __security_check_cookie (0651663h)  
00651135  mov         esp,ebp  
00651137  pop         ebp  
00651138  ret

 

* SimpleClass sc5();

   인자를 받지 않는 생성자의 호출문으로 인정해버리면

   컴파일러는 이러한 문장을 만났을 때, 객체 생성문인지 함수의 선언인지 구분할 수 없게 된다

   그래서 이러한 유형의 문장은 객체 생성이 아닌, 함수의 원형 선언에만 사용

 

int main(void)
{
00C41080  push        ebp  
00C41081  mov         ebp,esp  
00C41083  sub         esp,2Ch  
00C41086  mov         eax,dword ptr [__security_cookie (0C45000h)]  
00C4108B  xor         eax,ebp  
00C4108D  mov         dword ptr [ebp-4],eax  
	// 1. 매개변수 없는 생성자 호출
	SimpleClass sc1;
00C41090  push        0  
00C41092  push        0  
00C41094  lea         ecx,[sc1]  
00C41097  call        SimpleClass::SimpleClass (0C41000h)  
	SimpleClass sc2{};
00C4109C  push        0  
00C4109E  push        0  
00C410A0  lea         ecx,[sc2]  
00C410A3  call        SimpleClass::SimpleClass (0C41000h)  

	sc1.ShowData();
00C410A8  lea         ecx,[sc1]  
00C410AB  call        SimpleClass::ShowData (0C41030h)  
	sc2.ShowData();
00C410B0  lea         ecx,[sc2]  
00C410B3  call        SimpleClass::ShowData (0C41030h)  

	// 2. 매개변수 있는 생성자 호출
	SimpleClass sc3(30);
00C410B8  push        0  
00C410BA  push        1Eh  
00C410BC  lea         ecx,[sc3]  
00C410BF  call        SimpleClass::SimpleClass (0C41000h)  
	SimpleClass sc4{10, 20};
00C410C4  push        14h  
00C410C6  push        0Ah  
00C410C8  lea         ecx,[sc4]  
00C410CB  call        SimpleClass::SimpleClass (0C41000h)  

	sc3.ShowData();
00C410D0  lea         ecx,[sc3]  
00C410D3  call        SimpleClass::ShowData (0C41030h)  
	sc4.ShowData();
00C410D8  lea         ecx,[sc4]  
00C410DB  call        SimpleClass::ShowData (0C41030h)  

	// 책 예제
	// 보통 함수의 원형은 전역적으로(함수 밖에) 선언하지만,
	// 아래의 예제처럼 함수 내에 지역적으로 선언 가능
	SimpleClass sc5();			// 함수의 원형 선언
	SimpleClass mysc = sc5();
00C410E0  lea         eax,[mysc]  
00C410E3  push        eax  
00C410E4  call        sc5 (0C41110h)  
00C410E9  add         esp,4  
	mysc.ShowData();
00C410EC  lea         ecx,[mysc]  
00C410EF  call        SimpleClass::ShowData (0C41030h)  
	return 0;
00C410F4  xor         eax,eax  
}
00C410F6  mov         ecx,dword ptr [ebp-4]  
00C410F9  xor         ecx,ebp  
00C410FB  call        __security_check_cookie (0C41653h)  
00C41100  mov         esp,ebp  
00C41102  pop         ebp  
00C41103  ret

 

* 객체의 생성 과정

   1. 메모리 공간의 할당

   2. 이니셜라이저를 이용한 멤버 변수(객체)의 초기화

   3. 생성자의 몸체 부분

 

int main(void)
{
007719F0  push        ebp  
007719F1  mov         ebp,esp  
007719F3  sub         esp,24h  
007719F6  mov         eax,dword ptr [__security_cookie (0775000h)]  
007719FB  xor         eax,ebp  
007719FD  mov         dword ptr [ebp-4],eax  
	Rectangle rec(1, 1, 5, 5);
00771A00  mov         dword ptr [ebp-18h],5  
00771A07  mov         dword ptr [ebp-1Ch],5  
00771A0E  mov         dword ptr [ebp-20h],1  
00771A15  mov         dword ptr [ebp-24h],1  
00771A1C  lea         eax,[ebp-18h]  
00771A1F  push        eax  
00771A20  lea         ecx,[ebp-1Ch]  
00771A23  push        ecx  
00771A24  lea         edx,[ebp-20h]  
00771A27  push        edx  
00771A28  lea         eax,[ebp-24h]  
00771A2B  push        eax  
00771A2C  lea         ecx,[rec]  
00771A2F  call        Rectangle::Rectangle (0771610h)  
00771A34  nop  
	rec.ShowRecInfo();
00771A35  lea         ecx,[rec]  
00771A38  call        Rectangle::ShowRecInfo (0771650h)  
	return 0;
00771A3D  xor         eax,eax  
}
00771A3F  mov         ecx,dword ptr [ebp-4]  
00771A42  xor         ecx,ebp  
00771A44  call        __security_check_cookie (0771A4Dh)  
00771A49  mov         esp,ebp  
00771A4B  pop         ebp  
00771A4C  ret

 

이니셜라이저를 이용하면 선언과 동시에 초기화가 이뤄지는 형태로 바이너리 코드가 생성된다

   반면, 생성자의 몸체부분에서 대입연산을 통한 초기화를 진행하면,

   선언과 초기화를 각각 별도의 문장에서 진행하는 형태로 바이너리 코드가 생성된다

 

   [const 멤버변수]

   이니셜라이저를 이용하면 초기화 가능

   C++11 이후부터는 직접 선언한 것도 일종의 이니셜라이저로 간주되어 초기화가 가능하며,

   이러한 방식을 inline 초기화 또는 in-class initializer라고 부름

 

   근데, 어셈블리 코드상 확인해보면 차이가 없음. 코드상 차이 같음

 

class FruitSeller
{
private:
	int APPLE_PRICE;
	int numOfApples;
	int myMoney;

public:
	FruitSeller(int price, int num, int money)
003B1000  push        ebp  
003B1001  mov         ebp,esp  
003B1003  push        ecx  
003B1004  mov         dword ptr [this],ecx  
	{
		APPLE_PRICE = price;
003B1007  mov         eax,dword ptr [this]  
003B100A  mov         ecx,dword ptr [price]  
003B100D  mov         dword ptr [eax],ecx  
		numOfApples = num;
003B100F  mov         edx,dword ptr [this]  
003B1012  mov         eax,dword ptr [num]  
003B1015  mov         dword ptr [edx+4],eax  
		myMoney = money;
003B1018  mov         ecx,dword ptr [this]  
003B101B  mov         edx,dword ptr [money]  
003B101E  mov         dword ptr [ecx+8],edx  
	}
003B1021  mov         eax,dword ptr [this]  
003B1024  mov         esp,ebp  
003B1026  pop         ebp  
003B1027  ret         0Ch
class FruitSeller
{
private:
	int APPLE_PRICE;
	int numOfApples;
	int myMoney;

public:
	FruitSeller(int price, int num, int money)
		:APPLE_PRICE(price), numOfApples(num), myMoney(money)
002315B7  mov         eax,dword ptr [this]  
002315BA  mov         ecx,dword ptr [price]  
002315BD  mov         dword ptr [eax],ecx  
002315BF  mov         edx,dword ptr [this]  
002315C2  mov         eax,dword ptr [num]  
002315C5  mov         dword ptr [edx+4],eax  
002315C8  mov         ecx,dword ptr [this]  
002315CB  mov         edx,dword ptr [money]  
002315CE  mov         dword ptr [ecx+8],edx  
	{	}
002315D1  mov         eax,dword ptr [this]  
002315D4  mov         esp,ebp  
002315D6  pop         ebp  
002315D7  ret         0Ch

 

* const

   변수를 상수화시키는 키워드

   const 선언에 의해서 상수화된 변수를 가리켜 const 변수라고도 하고 const 상수라고도 한다

 

* 참조자도 선언과 동시에 초기화가 필요 → 이니셜라이저를 이용하면 참조자도 멤버변수로 선언 가능

 

* new, delete는 동적할당이고 사용자가 직접 메모리 해제해줘야 함

   반면, 정적할당(ex. 스택에 있는 지역변수)은

             함수 스코프가 끝나면 자동으로 메모리가 해제되기 때문에 delete가 필요 없음

 

int main(void)
{
00F51420  push        ebp  
00F51421  mov         ebp,esp  
00F51423  push        0FFFFFFFFh  
00F51425  push        0F53476h  
00F5142A  mov         eax,dword ptr fs:[00000000h]  
00F51430  push        eax  
00F51431  sub         esp,0C0h  
00F51437  mov         eax,dword ptr [__security_cookie (0F56000h)]  
00F5143C  xor         eax,ebp  
00F5143E  mov         dword ptr [ebp-10h],eax  
00F51441  push        eax  
00F51442  lea         eax,[ebp-0Ch]  
00F51445  mov         dword ptr fs:[00000000h],eax  
	Person parr[3];
00F5144B  push        offset Person::~Person (0F513A0h)  
00F51450  push        offset Person::Person (0F512C0h)  
00F51455  push        3  
00F51457  push        8  
00F51459  lea         eax,[parr]  
00F5145F  push        eax  
00F51460  call        `eh vector constructor iterator' (0F5242Ch)  
00F51465  mov         dword ptr [ebp-4],0  
	char namestr[100];
	char* strptr;
	int age;
	int len;

	for (int i = 0; i < 3; i++)
00F5146C  mov         dword ptr [ebp-0B0h],0  
00F51476  jmp         main+67h (0F51487h)  
00F51478  mov         ecx,dword ptr [ebp-0B0h]  
00F5147E  add         ecx,1  
00F51481  mov         dword ptr [ebp-0B0h],ecx  
00F51487  cmp         dword ptr [ebp-0B0h],3  
00F5148E  jge         main+17Bh (0F5159Bh)  
	{
		cout << "이름 : ";
00F51494  push        0F54254h  
00F51499  mov         edx,dword ptr [__imp_std::cout (0F540A4h)]  
00F5149F  push        edx  
00F514A0  call        std::operator<<<std::char_traits<char> > (0F51B70h)  
00F514A5  add         esp,8  
		cin >> namestr;
00F514A8  lea         eax,[namestr]  
00F514AB  push        eax  
00F514AC  mov         ecx,dword ptr [__imp_std::cin (0F54098h)]  
00F514B2  push        ecx  
00F514B3  call        std::operator>><char,std::char_traits<char> > (0F51EA0h)  
00F514B8  add         esp,8  

		cout << "나이 : ";
00F514BB  push        0F5425Ch  
00F514C0  mov         edx,dword ptr [__imp_std::cout (0F540A4h)]  
00F514C6  push        edx  
00F514C7  call        std::operator<<<std::char_traits<char> > (0F51B70h)  
00F514CC  add         esp,8  
		cin >> age;
00F514CF  lea         eax,[age]  
00F514D5  push        eax  
00F514D6  mov         ecx,dword ptr [__imp_std::cin (0F54098h)]  
00F514DC  call        dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (0F54058h)]  

		len = strlen(namestr) + 1;
00F514E2  lea         ecx,[namestr]  
00F514E5  mov         dword ptr [ebp-0A0h],ecx  
00F514EB  mov         edx,dword ptr [ebp-0A0h]  
00F514F1  add         edx,1  
00F514F4  mov         dword ptr [ebp-0B4h],edx  
00F514FA  mov         eax,dword ptr [ebp-0A0h]  
00F51500  mov         cl,byte ptr [eax]  
00F51502  mov         byte ptr [ebp-99h],cl  
00F51508  add         dword ptr [ebp-0A0h],1  
00F5150F  cmp         byte ptr [ebp-99h],0  
00F51516  jne         main+0DAh (0F514FAh)  
00F51518  mov         edx,dword ptr [ebp-0A0h]  
00F5151E  sub         edx,dword ptr [ebp-0B4h]  
00F51524  mov         dword ptr [ebp-0B8h],edx  
00F5152A  mov         eax,dword ptr [ebp-0B8h]  
00F51530  add         eax,1  
00F51533  mov         dword ptr [len],eax  
		strptr = new char[len];
00F51539  mov         ecx,dword ptr [len]  
00F5153F  push        ecx  
00F51540  call        operator new[] (0F52400h)  
00F51545  add         esp,4  
00F51548  mov         dword ptr [ebp-0BCh],eax  
00F5154E  mov         edx,dword ptr [ebp-0BCh]  
00F51554  mov         dword ptr [strptr],edx  
		strcpy_s(strptr, len, namestr);
00F5155A  lea         eax,[namestr]  
00F5155D  push        eax  
00F5155E  mov         ecx,dword ptr [len]  
00F51564  push        ecx  
00F51565  mov         edx,dword ptr [strptr]  
00F5156B  push        edx  
00F5156C  call        dword ptr [__imp__strcpy_s (0F5415Ch)]  
00F51572  add         esp,0Ch  
		parr[i].SetPersonInfo(strptr, age);
00F51575  mov         eax,dword ptr [age]  
00F5157B  push        eax  
00F5157C  mov         ecx,dword ptr [strptr]  
00F51582  push        ecx  
00F51583  mov         edx,dword ptr [ebp-0B0h]  
00F51589  lea         ecx,parr[edx*8]  
00F51590  call        Person::SetPersonInfo (0F51310h)  
00F51595  nop  
	}
00F51596  jmp         main+58h (0F51478h)  

	parr[0].ShowPersonInfo();
00F5159B  mov         eax,8  
00F515A0  imul        ecx,eax,0  
00F515A3  lea         ecx,parr[ecx]  
00F515AA  call        Person::ShowPersonInfo (0F51330h)  
	parr[1].ShowPersonInfo();
00F515AF  mov         edx,8  
00F515B4  shl         edx,0  
00F515B7  lea         ecx,parr[edx]  
00F515BE  call        Person::ShowPersonInfo (0F51330h)  
	parr[2].ShowPersonInfo();
00F515C3  mov         eax,8  
00F515C8  shl         eax,1  
00F515CA  lea         ecx,parr[eax]  
00F515D1  call        Person::ShowPersonInfo (0F51330h)  

	cout << sizeof(parr) << endl;
00F515D6  push        offset std::endl<char,std::char_traits<char> > (0F51E60h)  
00F515DB  push        18h  
00F515DD  mov         ecx,dword ptr [__imp_std::cout (0F540A4h)]  
00F515E3  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0F540ACh)]  
00F515E9  mov         ecx,eax  
00F515EB  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0F5404Ch)]  

	Person p;
00F515F1  push        8  
00F515F3  lea         ecx,[p]  
00F515F9  call        std::unique_ptr<std::_Facet_base,std::default_delete<std::_Facet_base> >::__autoclassinit2 (0F51790h)  
00F515FE  lea         ecx,[p]  
00F51604  call        Person::Person (0F512C0h)  
00F51609  mov         byte ptr [ebp-4],1  

	cout << "이름 : ";
00F5160D  push        0F54264h  
00F51612  mov         ecx,dword ptr [__imp_std::cout (0F540A4h)]  
00F51618  push        ecx  
00F51619  call        std::operator<<<std::char_traits<char> > (0F51B70h)  
00F5161E  add         esp,8  
	cin >> namestr;
00F51621  lea         edx,[namestr]  
00F51624  push        edx  
00F51625  mov         eax,dword ptr [__imp_std::cin (0F54098h)]  
00F5162A  push        eax  
00F5162B  call        std::operator>><char,std::char_traits<char> > (0F51EA0h)  
00F51630  add         esp,8  

	cout << "나이 : ";
00F51633  push        0F5426Ch  
00F51638  mov         ecx,dword ptr [__imp_std::cout (0F540A4h)]  
00F5163E  push        ecx  
00F5163F  call        std::operator<<<std::char_traits<char> > (0F51B70h)  
00F51644  add         esp,8  
	cin >> age;
00F51647  lea         edx,[age]  
00F5164D  push        edx  
00F5164E  mov         ecx,dword ptr [__imp_std::cin (0F54098h)]  
00F51654  call        dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (0F54058h)]  

	len = strlen(namestr) + 1;
00F5165A  lea         eax,[namestr]  
00F5165D  mov         dword ptr [ebp-0A4h],eax  
00F51663  mov         ecx,dword ptr [ebp-0A4h]  
00F51669  add         ecx,1  
00F5166C  mov         dword ptr [ebp-0C0h],ecx  
00F51672  mov         edx,dword ptr [ebp-0A4h]  
00F51678  movzx       eax,byte ptr [edx]  
00F5167B  mov         byte ptr [ebp-9Ah],al  
00F51681  add         dword ptr [ebp-0A4h],1  
00F51688  cmp         byte ptr [ebp-9Ah],0  
00F5168F  jne         main+252h (0F51672h)  
00F51691  mov         ecx,dword ptr [ebp-0A4h]  
00F51697  sub         ecx,dword ptr [ebp-0C0h]  
00F5169D  mov         dword ptr [ebp-0C4h],ecx  
00F516A3  mov         edx,dword ptr [ebp-0C4h]  
00F516A9  add         edx,1  
00F516AC  mov         dword ptr [len],edx  
	strptr = new char[len];
00F516B2  mov         eax,dword ptr [len]  
00F516B8  push        eax  
00F516B9  call        operator new[] (0F52400h)  
00F516BE  add         esp,4  
00F516C1  mov         dword ptr [ebp-0C8h],eax  
00F516C7  mov         ecx,dword ptr [ebp-0C8h]  
00F516CD  mov         dword ptr [strptr],ecx  
	strcpy_s(strptr, len, namestr);
00F516D3  lea         edx,[namestr]  
00F516D6  push        edx  
00F516D7  mov         eax,dword ptr [len]  
00F516DD  push        eax  
00F516DE  mov         ecx,dword ptr [strptr]  
00F516E4  push        ecx  
00F516E5  call        dword ptr [__imp__strcpy_s (0F5415Ch)]  
00F516EB  add         esp,0Ch  
	p.SetPersonInfo(strptr, age);
00F516EE  mov         edx,dword ptr [age]  
00F516F4  push        edx  
00F516F5  mov         eax,dword ptr [strptr]  
00F516FB  push        eax  
00F516FC  lea         ecx,[p]  
00F51702  call        Person::SetPersonInfo (0F51310h)  

	p.ShowPersonInfo();
00F51707  lea         ecx,[p]  
00F5170D  call        Person::ShowPersonInfo (0F51330h)  

	cout << sizeof(p) << endl;
00F51712  push        offset std::endl<char,std::char_traits<char> > (0F51E60h)  
00F51717  push        8  
00F51719  mov         ecx,dword ptr [__imp_std::cout (0F540A4h)]  
00F5171F  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0F540ACh)]  
00F51725  mov         ecx,eax  
00F51727  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0F5404Ch)]  
00F5172D  nop  

	return 0;
00F5172E  mov         dword ptr [ebp-0CCh],0  
00F51738  mov         byte ptr [ebp-4],0  
00F5173C  lea         ecx,[p]  
00F51742  call        Person::~Person (0F513A0h)  
00F51747  mov         dword ptr [ebp-4],0FFFFFFFFh  
00F5174E  push        offset Person::~Person (0F513A0h)  
00F51753  push        3  
00F51755  push        8  
00F51757  lea         ecx,[parr]  
00F5175D  push        ecx  
00F5175E  call        `eh vector destructor iterator' (0F522DDh)  
00F51763  mov         eax,dword ptr [ebp-0CCh]  
}
00F51769  mov         ecx,dword ptr [ebp-0Ch]  
00F5176C  mov         dword ptr fs:[0],ecx  
00F51773  pop         ecx  
00F51774  mov         ecx,dword ptr [ebp-10h]  
00F51777  xor         ecx,ebp  
00F51779  call        __security_check_cookie (0F522CAh)  
00F5177E  mov         esp,ebp  
00F51780  pop         ebp  
00F51781  ret

 

* 생성자

 

* 소멸자

 

int main(void)
{
000713B0  push        ebp  
000713B1  mov         ebp,esp  
000713B3  push        0FFFFFFFFh  
000713B5  push        73156h  
000713BA  mov         eax,dword ptr fs:[00000000h]  
000713C0  push        eax  
000713C1  sub         esp,98h  
000713C7  mov         eax,dword ptr [__security_cookie (076040h)]  
000713CC  xor         eax,ebp  
000713CE  mov         dword ptr [ebp-10h],eax  
000713D1  push        eax  
000713D2  lea         eax,[ebp-0Ch]  
000713D5  mov         dword ptr fs:[00000000h],eax  
	Person* parr[3];
	char namestr[100];
	int age;

	for (int i = 0; i < 3; i++)
000713DB  mov         dword ptr [ebp-7Ch],0  
000713E2  jmp         main+3Dh (0713EDh)  
000713E4  mov         eax,dword ptr [ebp-7Ch]  
000713E7  add         eax,1  
000713EA  mov         dword ptr [ebp-7Ch],eax  
000713ED  cmp         dword ptr [ebp-7Ch],3  
000713F1  jge         main+100h (0714B0h)  
	{
		cout << "이름 : ";
000713F7  push        74230h  
000713FC  mov         ecx,dword ptr [__imp_std::cout (0740A4h)]  
00071402  push        ecx  
00071403  call        std::operator<<<std::char_traits<char> > (0719F0h)  
00071408  add         esp,8  
		cin >> namestr;
0007140B  lea         edx,[namestr]  
0007140E  push        edx  
0007140F  mov         eax,dword ptr [__imp_std::cin (074098h)]  
00071414  push        eax  
00071415  call        std::operator>><char,std::char_traits<char> > (071D20h)  
0007141A  add         esp,8  

		cout << "나이 : ";
0007141D  push        74238h  
00071422  mov         ecx,dword ptr [__imp_std::cout (0740A4h)]  
00071428  push        ecx  
00071429  call        std::operator<<<std::char_traits<char> > (0719F0h)  
0007142E  add         esp,8  
		cin >> age;
00071431  lea         edx,[age]  
00071434  push        edx  
00071435  mov         ecx,dword ptr [__imp_std::cin (074098h)]  
0007143B  call        dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (074058h)]  
00071441  nop  

		parr[i] = new Person(namestr, age);
00071442  push        8  
00071444  call        operator new (0721DCh)  
00071449  add         esp,4  
0007144C  mov         dword ptr [ebp-80h],eax  
0007144F  mov         dword ptr [ebp-4],0  
00071456  cmp         dword ptr [ebp-80h],0  
0007145A  je          main+0CEh (07147Eh)  
0007145C  push        8  
0007145E  mov         ecx,dword ptr [ebp-80h]  
00071461  call        std::unique_ptr<std::_Facet_base,std::default_delete<std::_Facet_base> >::__autoclassinit2 (071610h)  
00071466  mov         eax,dword ptr [age]  
00071469  push        eax  
0007146A  lea         ecx,[namestr]  
0007146D  push        ecx  
0007146E  mov         ecx,dword ptr [ebp-80h]  
00071471  call        Person::Person (0712C0h)  
00071476  mov         dword ptr [ebp-88h],eax  
0007147C  jmp         main+0D8h (071488h)  
0007147E  mov         dword ptr [ebp-88h],0  
00071488  mov         edx,dword ptr [ebp-88h]  
0007148E  mov         dword ptr [ebp-90h],edx  
00071494  mov         dword ptr [ebp-4],0FFFFFFFFh  
0007149B  mov         eax,dword ptr [ebp-7Ch]  
0007149E  mov         ecx,dword ptr [ebp-90h]  
000714A4  mov         dword ptr parr[eax*4],ecx  
	}
000714AB  jmp         main+34h (0713E4h)  

	parr[0]->ShowPersonInfo();
000714B0  mov         edx,4  
000714B5  imul        eax,edx,0  
000714B8  mov         ecx,dword ptr parr[eax]  
000714BF  call        Person::ShowPersonInfo (071340h)  
	parr[1]->ShowPersonInfo();
000714C4  mov         ecx,4  
000714C9  shl         ecx,0  
000714CC  mov         ecx,dword ptr parr[ecx]  
000714D3  call        Person::ShowPersonInfo (071340h)  
	parr[2]->ShowPersonInfo();
000714D8  mov         edx,4  
000714DD  shl         edx,1  
000714DF  mov         ecx,dword ptr parr[edx]  
000714E6  call        Person::ShowPersonInfo (071340h)  

	cout << sizeof(parr) << endl;
000714EB  push        offset std::endl<char,std::char_traits<char> > (071CE0h)  
000714F0  push        0Ch  
000714F2  mov         ecx,dword ptr [__imp_std::cout (0740A4h)]  
000714F8  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0740ACh)]  
000714FE  mov         ecx,eax  
00071500  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07404Ch)]  

	Person* p;

	cout << "이름 : ";
00071506  push        74240h  
0007150B  mov         eax,dword ptr [__imp_std::cout (0740A4h)]  
00071510  push        eax  
00071511  call        std::operator<<<std::char_traits<char> > (0719F0h)  
00071516  add         esp,8  
	cin >> namestr;
00071519  lea         ecx,[namestr]  
0007151C  push        ecx  
0007151D  mov         edx,dword ptr [__imp_std::cin (074098h)]  
00071523  push        edx  
00071524  call        std::operator>><char,std::char_traits<char> > (071D20h)  
00071529  add         esp,8  

	cout << "나이 : ";
0007152C  push        74248h  
00071531  mov         eax,dword ptr [__imp_std::cout (0740A4h)]  
00071536  push        eax  
00071537  call        std::operator<<<std::char_traits<char> > (0719F0h)  
0007153C  add         esp,8  
	cin >> age;
0007153F  lea         ecx,[age]  
00071542  push        ecx  
00071543  mov         ecx,dword ptr [__imp_std::cin (074098h)]  
00071549  call        dword ptr [__imp_std::basic_istream<char,std::char_traits<char> >::operator>> (074058h)]  
0007154F  nop  

	p = new Person(namestr, age);
00071550  push        8  
00071552  call        operator new (0721DCh)  
00071557  add         esp,4  
0007155A  mov         dword ptr [ebp-84h],eax  
00071560  mov         dword ptr [ebp-4],1  
00071567  cmp         dword ptr [ebp-84h],0  
0007156E  je          main+1E8h (071598h)  
00071570  push        8  
00071572  mov         ecx,dword ptr [ebp-84h]  
00071578  call        std::unique_ptr<std::_Facet_base,std::default_delete<std::_Facet_base> >::__autoclassinit2 (071610h)  
0007157D  mov         edx,dword ptr [age]  
00071580  push        edx  
00071581  lea         eax,[namestr]  
00071584  push        eax  
00071585  mov         ecx,dword ptr [ebp-84h]  
0007158B  call        Person::Person (0712C0h)  
00071590  mov         dword ptr [ebp-8Ch],eax  
00071596  jmp         main+1F2h (0715A2h)  
00071598  mov         dword ptr [ebp-8Ch],0  
000715A2  mov         ecx,dword ptr [ebp-8Ch]  
000715A8  mov         dword ptr [ebp-94h],ecx  
000715AE  mov         dword ptr [ebp-4],0FFFFFFFFh  
000715B5  mov         edx,dword ptr [ebp-94h]  
000715BB  mov         dword ptr [p],edx  

	p->ShowPersonInfo();
000715C1  mov         ecx,dword ptr [p]  
000715C7  call        Person::ShowPersonInfo (071340h)  

	cout << sizeof(p) << endl;
000715CC  push        offset std::endl<char,std::char_traits<char> > (071CE0h)  
000715D1  push        4  
000715D3  mov         ecx,dword ptr [__imp_std::cout (0740A4h)]  
000715D9  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0740ACh)]  
000715DF  mov         ecx,eax  
000715E1  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (07404Ch)]  

	return 0;
000715E7  xor         eax,eax  
}
000715E9  mov         ecx,dword ptr [ebp-0Ch]  
000715EC  mov         dword ptr fs:[0],ecx  
000715F3  pop         ecx  
000715F4  mov         ecx,dword ptr [ebp-10h]  
000715F7  xor         ecx,ebp  
000715F9  call        __security_check_cookie (0721CEh)  
000715FE  mov         esp,ebp  
00071600  pop         ebp  
00071601  ret

 

int main(void)
{
006210C0  push        ebp  
006210C1  mov         ebp,esp  
006210C3  sub         esp,14h  
006210C6  mov         eax,dword ptr [__security_cookie (0625000h)]  
006210CB  xor         eax,ebp  
006210CD  mov         dword ptr [ebp-4],eax  
	SoSimple sim1(100);
006210D0  push        64h  
006210D2  lea         ecx,[sim1]  
006210D5  call        SoSimple::SoSimple (0621000h)  
	SoSimple* ptr1 = sim1.GetThisPointer();
006210DA  lea         ecx,[sim1]  
006210DD  call        SoSimple::GetThisPointer (06210B0h)  
006210E2  mov         dword ptr [ptr1],eax  

	cout << ptr1 << ", ";
006210E5  push        623168h  
006210EA  mov         eax,dword ptr [ptr1]  
006210ED  push        eax  
006210EE  mov         ecx,dword ptr [__imp_std::cout (0623080h)]  
006210F4  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0623038h)]  
006210FA  push        eax  
006210FB  call        std::operator<<<std::char_traits<char> > (0621410h)  
00621100  add         esp,8  
	ptr1->ShowSimpleData();
00621103  mov         ecx,dword ptr [ptr1]  
00621106  call        SoSimple::ShowSimpleData (0621080h)  

	SoSimple sim2(200);
0062110B  push        0C8h  
00621110  lea         ecx,[sim2]  
00621113  call        SoSimple::SoSimple (0621000h)  
	SoSimple* ptr2 = sim2.GetThisPointer();
00621118  lea         ecx,[sim2]  
0062111B  call        SoSimple::GetThisPointer (06210B0h)  
00621120  mov         dword ptr [ptr2],eax  
	cout << ptr2 << ", ";
00621123  push        62316Ch  
00621128  mov         ecx,dword ptr [ptr2]  
0062112B  push        ecx  
0062112C  mov         ecx,dword ptr [__imp_std::cout (0623080h)]  
00621132  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0623038h)]  
00621138  push        eax  
00621139  call        std::operator<<<std::char_traits<char> > (0621410h)  
0062113E  add         esp,8  
	ptr2->ShowSimpleData();
00621141  mov         ecx,dword ptr [ptr2]  
00621144  call        SoSimple::ShowSimpleData (0621080h)  

	cout << endl << sizeof(sim2) << endl;
00621149  push        offset std::endl<char,std::char_traits<char> > (0621700h)  
0062114E  push        4  
00621150  push        offset std::endl<char,std::char_traits<char> > (0621700h)  
00621155  mov         ecx,dword ptr [__imp_std::cout (0623080h)]  
0062115B  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (062304Ch)]  
00621161  mov         ecx,eax  
00621163  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0623034h)]  
00621169  mov         ecx,eax  
0062116B  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (062304Ch)]  

	return 0;
00621171  xor         eax,eax  
}
00621173  mov         ecx,dword ptr [ebp-4]  
00621176  xor         ecx,ebp  
00621178  call        __security_check_cookie (0621733h)  
0062117D  mov         esp,ebp  
0062117F  pop         ebp  
00621180  ret

 

* MSVC 컴파일러에서만 명시적으로 __thiscall 존재, 표준 아님

 

* 속성 > C/C++ > 고급 > 호출규칙 

 

class TwoNumber
{
private:
	int num1;
	int num2;
public:
	TwoNumber(int num1, int num2)
00C21000  push        ebp  
00C21001  mov         ebp,esp  
00C21003  push        ecx  
00C21004  mov         dword ptr [this],ecx  
	{
		this->num1 = num1;
00C21007  mov         eax,dword ptr [this]  
00C2100A  mov         ecx,dword ptr [num1]  
00C2100D  mov         dword ptr [eax],ecx  
		this->num2 = num2;
00C2100F  mov         edx,dword ptr [this]  
00C21012  mov         eax,dword ptr [num2]  
00C21015  mov         dword ptr [edx+4],eax  
	}
00C21018  mov         eax,dword ptr [this]  
00C2101B  mov         esp,ebp  
00C2101D  pop         ebp  
00C2101E  ret         8

/////////////////////////////////////////////////////////////////////////////////////

	void ShowTwoNumber()
	{
00C21030  push        ebp  
00C21031  mov         ebp,esp  
00C21033  push        ecx  
00C21034  mov         dword ptr [this],ecx  
		cout << this->num1 << endl;
00C21037  push        offset std::endl<char,std::char_traits<char> > (0C210C0h)  
00C2103C  mov         eax,dword ptr [this]  
00C2103F  mov         ecx,dword ptr [eax]  
00C21041  push        ecx  
00C21042  mov         ecx,dword ptr [__imp_std::cout (0C22048h)]  
00C21048  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0C22044h)]  
00C2104E  mov         ecx,eax  
00C21050  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0C22040h)]  
		cout << this->num2 << endl;
00C21056  push        offset std::endl<char,std::char_traits<char> > (0C210C0h)  
00C2105B  mov         edx,dword ptr [this]  
00C2105E  mov         eax,dword ptr [edx+4]  
00C21061  push        eax  
00C21062  mov         ecx,dword ptr [__imp_std::cout (0C22048h)]  
00C21068  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0C22044h)]  
00C2106E  mov         ecx,eax  
00C21070  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0C22040h)]  
00C21076  nop  
	}
00C21077  mov         esp,ebp  
00C21079  pop         ebp  
00C2107A  ret