포스트

디스어셈블리 코드로 살펴보는 루프문 짧게 줄여 보기

디스어셈블리 코드를 통해 루프문을 짧게 줄여 보는 시도를 해본다

디스어셈블리 코드로 살펴보는 루프문 짧게 줄여 보기

1. 단축 이전

먼저, 예제로 쓰일 C/C++로 작성한 아주 간단한 for 루프문이다.

디스어셈블리 스크린샷 1

sub()의 첫번째 파라미터 값에 첨자가 들어가 있지만 이것은 실수이니 신경쓰지 않아도 된다.

다음은 이에 대한 디스어셈블리 코드이다.
디스어셈블리 스크린샷 2
디스어셈블리 스크린샷 3

그럼 이제 위 코드에서 for 루프 부분만 살짝 떼어내어 살펴 보도록 하자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    11:  for(int i = 0; i < n; i++)
00D219F8  mov         dword ptr [i],0
00D219FF  jmp         sub+3Ah (0D21A0Ah)
00D21A01  mov         eax,dword ptr [i]
00D21A04  add         eax,1
00D21A07  mov         dword ptr [i],eax
00D21A0A  mov         eax,dword ptr [i]
00D21A0D  cmp         eax,dword ptr [ebp+0Ch]
00D21A10  jge         sub+54h (0D21A24h)
    12:  {
    13:   data[i] = a[i]; 
00D21A12  mov         eax,dword ptr [i]
00D21A15  mov         ecx,dword ptr [i]
00D21A18  mov         edx,dword ptr [ebp+8]
00D21A1B  mov         ecx,dword ptr [edx+ecx*4]
00D21A1E  mov         dword ptr [ebp+eax*4-30h],ecx
    14:  }

위처럼 총 13개 라인으로 구성되어 있다.

2. 단축을 해보자

이미 알고 있는 것 처럼, 루프문을 짧게 줄이는 작업은 결국 코드의 길이를 줄이는 작업 이라고 할 수 있다.
물론 실질적인 성능을 높이기 위한 파이프라이닝이나 해저드 문제 해결 등을 우선적으로 고려 해야 한다.
명령어 당 tick 카운트가 얼마나 소요되는지도 계산해 봐야 할 것이다. 그러나 여기선 논외로 한다.

다음은 어셈블리 코드를 이용해 코딩하여 명령어의 라인 수를 줄여본 코드다.

디스어셈블리 스크린샷 4

위 코드를 보면 8줄에 불과하다.
짧게 줄이기 이전 코드와 비교해 보면 무려 5줄이나 더 짧은 것이다.
위의 원본 코드와 위의 코드를 컴파일하여 생성된 디스어셈블리 코드와 비교를 해봐도 다를것이 없다.
똑같이 8줄인 것이다.

디스어셈블리 스크린샷 4

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.