'서브루틴'에 해당되는 글 1건

  1. 2010.04.22 [System Programming] 서브루틴의 개념 (1)

1. 개 요
서브루틴(SubRoutine)의 개념에 대해서 알아보도록 한다.

2. 설 명
프로그래밍시 매크로(macro) 기능을 자주 사용한다.
매크로란 반복되어 자주 사용되는 명령어를 묶어서 하나의 이름으로 만드는 것을 말한다.
C언어 등의 프로그래밍 언어를 이용하여 프로그래밍시 매크로를 사용하게 되면 컴파일시에 해당 매크로를 사용하는 부분은 매크로의 원문으로 모두 교체되게 되므로, 소스 코드의 크기가 커지고 그만큼 메모리의 점유율이 높아지는 단점이 있다.

이런 매크로의 단점을 극복하고 반복되는 것을 한 번만 사용하여 메모리 사용을 최대한 줄이도록 고안된 것이 서브루틴(Sub-routine)이다. 이는 메인루틴(Main-routine)의 대비되는 개념으로 혼자 쓰이는 것이 아닌 메인루틴에 붙어 보조하는 역할을 한다. 반복되는 특정한 기능을 모아 놓아 이름을 붙여 놓았다는 것은 매크로와 같지만 프로그램 흐름이 메인루틴에 있지 않고 별도의 공간에 한 번만 생긴다는 것이 다르다. 아래 예를 통해서 서브루틴에 대한 개념을 정확히 알아보도록 하자.

아래는 매우 간단한 프로그램의 예이다.

 #include "stdio.h"

int func(int a, int b)
{
       int c;
       c = a + b;
       return c;
}

int main(int argc, char *argv[])
{
       int res, res2;
       res = func(1, 2);
       printf("1 + 2 = %d\n", res);

       res2 = func(2, 3);
       printf("2 + 3 = %d\n", res2);
       return 0;
}


쉽게 프로그램의 구조를 해석할 수 있을 것이다. main 함수에서 func 함수를 두 번 호출하게 되고 func 함수는 전달되는 파라미터 값을 더해서 리턴해 주는 간단한 프로그램이다.

Olly Debugger를 이용하여 프로그램의 메인 함수 부분을 살펴보자.

위와 같이 0040B780 ~ 0040B7EA 주소의 메모리에 main 함수가 위치하며 func 함수를 call 하는 부분이 두 번 등장하는 것을 볼 수 있다. func 함수의 경우 0040100A 주소에 위치해 있는 것을 알 수 있다.

반복되는 기능에 대해서 하나의 서브루틴(func)을 메모리에 적재한 뒤 필요시마다 해당 메모리를 호출하여 기능을 실행하는 것을 알 수 있다. 즉, 한번의 메모리 적재 후 여러 번의 사용을 통해 메모리 사용량을 줄일 수 있다.

그렇다면 실제로 서브루틴 호출과 이후의 프로그램의 흐름에 대해서 알아보자.
func 함수의 00401010 ~ 0040103A의 메모리 주소에 적재되는 것을 알 수 있다. 또한 함수의 기능을 수행한 뒤에 마지막에 RETN 명령어를 통하여 메인루틴의 주소로 돌아가는 것을 알 수 있다.(서브루틴의 기능에 대해서 설명하는 포스팅이므로 자세한 기능에 대해서는 생략한다. 절대 귀찮아서는 아니다.( __))

그렇다면 서브루틴을 호출하기 전 메인루틴에서는 어떻게 서브루틴 종료 후 다시 돌아올 주소값을 저장할까? 정답은 CALL 명령어를 이용하여 서브루틴(func 함수)을 호출할 시에 CALL 명령어 다음의 메모리 주소(0040B7A1)를 스택에 저장하는 것을 볼 수 있다. 이 후 서브루틴의 기능을 수행하고 RETN 명령어를 만나면 현재 ESP(Extended Stack Pointer) 레지스터가 가르키고 있는 스택의 값을 읽어서 분기하게 된다.(물론 RETN을 만났을 때 ESP가 가르키는 곳에는 메인루틴의 CALL 명령어 다음의 주소가 저장되어 있다.)

이 과정을 정리하면 다음과 같다.
① 지금 실행하고 있는 명령어가 담긴 주소 바로 다음 주소를 저장
② 서브루틴에 보낼 파라미터를 약속된 장소에 저장(위의 예제의 경우 stack에 파라미터를 저장한다.)
③ 서브루틴은 약속된 장소에서 파라미터를 꺼내 자신을 실행
④ 서브루틴의 작업을 마치면 ①에 저장해 놓은 다음 주소를 꺼내와 EIP(Extended Instruction Pointer) 주소에 넣음

3. 결 론
프로그래밍시에나 리버싱 시에도 서브루틴에 대한 개념은 기본인 듯하다. 쉽게 지나치기 쉬운 개념인데 서브루틴에 대한 개념을 알고나면 함수의 작동원리와 기능에 대해 조금더 이해하기 쉽지 않을까 한다.

4. 참고문헌
- 해킹 파괴의 광학(김성우 저) / 제2장 시스템 프로그래밍 그리고 윈도우

                                                                                                    +---------------------------------+
                                                                                                    | Infinite Flow..                              |

                                                                                                    | mail : geekspark@gmail.com         |
                                                                                                    | Blog : http://sinun.tistory.com       |
                                                                                                    | twitter : @unpacker                      |
                                                                                                    | CISSP                                        |
                                                                                                    +----------------------------------+
저작자 표시 비영리 변경 금지
신고
Posted by By. PHR34K