C코드를 어셈블리 코드로 보는 법


디버깅 중에, VS2010에서 Debug -> Window -> Disassembly를 실행해 C코드를 어셈블리 코드로 치환한 것을 볼 수 있다.



분석해 보기

1. int a = 100;

0041348E  mov         dword ptr [a],64h

- 0041348E : 어셈블리 명령어가 있는 주소. 바로 다음에 나오는 주소에서 빼면 몇 바이트 명령어인지 알 수 있다.

- mov : 명령어. 대입연산자에 해당한다.

- dword : Double Word, 4Byte 자료형(int)

- ptr [a] : 변수 a의 주소를 나타냄. ptr = pointer, *( &a )에 해당. 결국 a를 의미

- 64h : h는 Hexadecimal을 의미(16진수), 16진수 64는 100이다.

-> o는 Octal(8진수), b는 Binary(2진수)를 의미한다.


=> 결국 a의 메모리 주소에 100의 값을 넣는다고 할 수 있다.


2. a = a + 1;, a++;, ++a;

이 세 코드는 기본적으로 같은 역할을 하지만 코드는 다르다.

그럼 실제로 속도나 코드에서 차이가 있을까?


a = a + 1;

0041349C  mov         eax,dword ptr [a]  

0041349F  add         eax,1  

004134A2  mov         dword ptr [a],eax  

++a;

004134A5  mov         eax,dword ptr [a]  

004134A8  add         eax,1  

004134AB  mov         dword ptr [a],eax  

a++;

004134AE  mov         eax,dword ptr [a]  

004134B1  add         eax,1  

004134B4  mov         dword ptr [a],eax  


자세히 보면 알 수 있지만, 다 같은 코드이다.

속도, 용량, 모든게 다 똑같음을 알 수 있다.(컴파일러마다 다를 수도 있다)

참고로 ++와 --에 해당하는 전용 어셈블리 명령어도 존재한다.

inc(increase)와 dec(decrease)로, add나 sub보다 용량이 적다.(속도면에서는 아마 느린 모양 byte수가 다르므로)


3. a = b + a;

004134B7  mov         eax,dword ptr [b]  

004134BA  add         eax,dword ptr [a]  

004134BD  mov         dword ptr [a],eax  

- eax : 메모리의 값은 메모리가 직접 연산할 수 없으므로, ALU가 사용할 수 있게 임시 레지스터에 전송해야 한다. 그 중 제일 만만한 녀석이 eax이다.


1. 메모리에 있는 4바이트 b값을 연산하기 위해 eax레지스터에 저장한다.

2. eax 레지스터에 있는 값과 메모리에 있는 4바이트인 a의 값을 더한다.

3. 메모리에 있는 4바이트 a 주소에 eax값을 집어넣는다.


4. b = a;

004134C0  mov         eax,dword ptr [a]  

004134C3  mov         dword ptr [b],eax

1. 4바이트 a의 값을 eax 레지스터에 넣는다.

2. eax레지스터에 있는 값을 4바이트 b주소에 넣는다.


=> 즉, a=b;같이 메모리에 있는 값끼리 바꾼다 하더라도 CPU를 무조건 거쳐야 한다.

- 이를 생략하는 것이 DMA(Direct Memory Acces)

+ Recent posts