별빛의 낙하지 :: [C++] 어셈으로 보는 함수 호출(1)

[C++] 어셈으로 보는 함수 호출(1)

C++ 2012. 11. 6. 23:56 Posted by byulbit

어셈블러 입장에서 C++의 파라미터를 값으로 넘기는 함수(call by value), 레퍼런스로 넘기는 함수(call by reference), 포인터로 넘기는 함수(call by pointer) 의 구현체들은 어떠한 차이가 있을까?


void callByValue(int a )
{

}

void callByReference(int& a)
{

}

void callByPointer(int* a)
{

}

int main()
{
	int number = 1;
	int value = number;
	int* pointer = &value;
	int& reference = value;
	
	int depointer = *pointer;
	int dereference = value;

	callByPointer(pointer);
	callByValue(value);
	callByReference(reference);


}

함수의 구현체는 파라미터의 종류에 관계 없이 동일한 방식이었다.

void callByPointer(int* a)

{

01091060  push        ebp  

01091061  mov         ebp,esp  

01091063  sub         esp,0C0h  

01091069  push        ebx  

0109106A  push        esi  

0109106B  push        edi  

0109106C  lea         edi,[ebp-0C0h]  

01091072  mov         ecx,30h  

01091077  mov         eax,0CCCCCCCCh  

0109107C  rep stos    dword ptr es:[edi]  


}


함수 호출전 변수에 값을 대입하는 코드는 변수의 경우 dword ptr[변수이름]을 통해서 해당하는 변수의 값을 가져와서 mov(복사) 하는 코드임을 알 수 있으며, pointer와 reference의 경우 lea 명령(load effective address)을 이용한다.

Load Effective Address란 의미로 다음의 인자를 주소값으로 인식합니다.


int number = 1;

010910AE  mov         dword ptr [number],1          // 1을 number가 가리키는 곳에 대입한다.

int value = number;

010910B5  mov         eax,dword ptr [number]      // number가 가리키는 곳의 값을 eax에 대입한다.

010910B8  mov         dword ptr [value],eax          // eax 값을 value가 가리키는 곳에 대입한다.

int* pointer = &value;

010910BB  lea         eax,[value]                          // value 값을 eax에 대입한다.

010910BE  mov         dword ptr [pointer],eax         // pointer가 가리키는 곳에 eax를 대입한다.

int& reference = value;

010910C1  lea         eax,[value]                          // value 값을 eax에 대입한다.

010910C4  mov         dword ptr [reference],eax     // reference가 가리키는 곳에 eax를 대입한다.

int depointer = *pointer;

010910C7  mov         eax,dword ptr [pointer]  // pointer가 가리키는 값을 eax에 대입한다.

010910CA  mov         ecx,dword ptr [eax]  // eax가 가리키는 값을 ecx에 대입한다.

010910CC  mov         dword ptr [depointer],ecx  // ecx 값을 depointer가 가리키는 값에 대입한다.

int dereference = value;

010910CF  mov         eax,dword ptr [value]      // value가 가리키는 값을 eax에 대입한다.

010910D2  mov         dword ptr [dereference],eax    // eax 값을 dereference에 대입한다.