ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 연산자 (sizeof), 디스어셈블
    C언어 2020. 2. 24. 10:16

    이번 포스트에서는 C의 연산자 중 하나인 sizeof 연산자에 대해서 다룰 것이다.

    sizeof 연산자는 피연산자의 자료형에 대한 연산을 수행해준다. 즉 sizeof (5)라고 입력이 되면 피연 사자 5는 int 자료형임으로 int 자료형의 크기인 4byte가 반환된다. 이와 같이 sizeof 연산자는 피연산자의 자료형에 대한 값을 반환해주는 연산자이다.

    + sizeof 연산자의 피연산자가 연산 식이라면?

    위와 같은 경우 연산식은 실행하지 않으며 해당 연산식의 결과에 해당하는 자료형의 크기가 반환된다.

    printf("% d", sizeof ( 10 + 0.2 ))

    결과는 10 => int, 0.2 => double 따라서 형 승격이 이루어지면서 더 큰 자료형인 double 자료형의 크기가 출력된다.

     

    또한 sizeof 연산자는 프로그램을 빌드하고 CPU가 실행하는 런타임 연산자가 아니며 컴파일러가 컴파일 타임에 수행하는 연산자이다. 즉 CPU를 사용하지 않기 때문에 많이 사용해도 성능에 영향을 미치지 않으며 많이 사용할수록 추후 프로그램의 유지보수 측면이 쉬워지기 때문에 프로그램 작성 시 많이 사용해야 하는 연산자이다.

    예를 들어 int 자료형의 5개의 집합인 배열을 선언하고 0 초기화를 했다고 가정하면 메모리의 특정 주소부터 int (4byte) * 5의 크기만큼의 메모리는 0이라는 값이 담겨있을 것이다. 이후 sizeof 연산자를 이용해 피연산자에 배열의 주소(이름)를 입력한다면 20이라는 값이 반환될 것이라고 추측이 가능할 것이다.

    위의 자료와 같이 sizeof 연산자의 결과로 20이 출력되는 것을 확인 가능하다.

    그렇다면 기계어 수준에서 sizeof 연산자가 반환해주는 값은 무엇일까?

    위에서 이런 말을 하였다 "sizeof 연산자는 프로그램을 빌드하고 CPU가 실행하는 런타임 연산자가 아니며 컴파일러가 컴파일 타임에 수행하는 연산자이다" 따라서 컴파일러가 컴파일 과정인 컴파일타임에 수행한 sizeof 연산자의 결과로 어떠한 값이 반환되었는가?라는 의문이 생길 것이다. 

    위의 의문은 디스 어셈블 도구 (어셈블리 코드로 변경된 코드를 보여줌)를 통해 컴파일 타임이 끝난 뒤 어떤 값이 반환되는지 살펴볼 수 있다.

     

    위의 자료는 디버깅 중 디스 어셈블을 통해 나온 정보이다. printf 함수가 머신 (CPU)에게 어떤 명령을 내리는지 알 수 있다. mov는 레지스터 esi에 있는 값을 esp로 옮기라는 명령이며 중요하게 봐야 할 부분은 push이다. push는 어떤 정보를 보낼지에 대한 내용인데 이때 14h라는 값을 보내는 것을 확인할 수 있다.

    14h는 16진수 14를 의미하며 따라서 16진수 0x 10 + 4 => 10진수 16 + 4와 같다 따라서 20이라는 값이 보내지는 것을 볼 수 있다. 따라서 sizeof 연산자를 통해 해당 자료형의 크기를 구한 값이나 사용자가 직접 명시한 상수 20이나 똑같이 20이라는 값이 CPU에서 처리되는 것을 볼 수 있다.   

    위와 같이 디버그 모드를 통해 디스 어셈블 창을 확인한 것과 같이 내부적으로 어떤 식으로 동작하는지 확인하는 습관은 매우 큰 도움이 되며 따라서 이해가 가지 않는 부분이 있으면 다음과 같이 디버그 과정을 통해 내부적으로 어떤 일이 일어나는지 확인함으로써 보다 본질적은 이해를 한다면 실력 향상에 많은 도움이 된다.

    댓글

Designed by Tistory.