본문 바로가기

CS/CS Book

[컴퓨터 시스템 딥다이브] ch06 어셈블리에 뛰어들기

💡이 글은 컴퓨터 시스템 딥다이브(수잰 J. 매슈스, 한빛미디어 2024)를 읽고 적은 글입니다.

 

컴퓨터가 동작하기 위해서는 0,1로 되어있는 기계어가 필요하다.

어셈블리어는 기계어에 가깝다. 효율적인 어셈블리 코드를 작성하기 위해서는 기계 아키텍처 동작을 구석구석 이해 해야 한다고 한다.

컴파일러 개발 이후에는 컴파일러가 사람이 읽을 수 있는 형태의 언어를 기계가 이해할 수 있는 언어로 번역해 주기에 어셈블리를 배울 이유가 모호해질 수 있다 느낄 수 있다.

하지만 어셈블리를 배워야 할 타당한 이유가 있다.

가치 있는 프로그램의 세부 사항을 감추는 고수준의 추상화

아래의 코드 경우 결과가 어떻게 될 것인가

assign() 함수를 호출하지만 호출하는 곳에서 return 값을 변수에 담아두지 않는다.

adder() 함수 내부에 있는 지역변수는 초기화하지 않은 상태에서 덧셈 연산을 한 뒤 그 값을 return 한다.

#include <stdio.h>

int adder()
{
  int a;

  return a + 2;
}

int assign()
{
  int y = 40;

  return y;
}

int main()
{
  int x;

  assign();
  x = adder();
  printf("x is : %d\\n", x);

  return 0;
}

 

책에서는 대부분의 64비트 머신에서는 42가 결과로 나올 것이라 한다.

힌트는 스택 프레임과 함수가 실행하는 방법을 이해하면 알 수 있을 것이라 한다.

 

이처럼 어셈블리 이해고급 언어가 기계어서 어떻게 동작하는지 이해하는데 도움을 준다.

 

그 외에 리소스가 제한되어 컴파일러를 쓸 수 없는 컴퓨팅 시스템들(센서, 마이크로컨트롤러, 기타 임베디드 프로세서 등)에게는 일반적인 프로그래밍 언어에 요구되는 런타임 라이브러리에 의존하지 않는 독립된 어셈블리 프로그램이 필요하다며 필요성을 이야기한다.

 

취약점 분석에도 쓰인다. 보안 전문가들은 멀웨어나 위험한 소프트웨어의 위험한 코드를 역엔지니어링 하는 데 주력한다고 한다. 자신이 작성한 코드가 어셈블리로 변환되는 방법을 이해하지 못하는 개발자는 의도치 않게 취약한 코드를 작성하고 만다고 한다.

 

컴퓨터 시스템의 일부 컴포넌트컴파일러에 의해 충분하게 최적화될 수 없다.

시스템 레벨에서 성능상 머신 전용 최적화가 필요한 곳에는 어셈블리 코드를 직접 작성한다고 한다. 모든 컴퓨터의 부트 시퀀스어셈블리 코드로 작성된다. OS의 스레드나 프로세스 컨텍스트 스위칭을 위해 어셈블리 코드를 직접 작성한다.

 

챕터 06은 어셈블리를 왜 배워야 하는지 이유와 배우면 왜 좋겠는지 알 수 있게 해 주었다.

 

위에 적은 코드의 결과가 64비트 머신에서 대체로 42인 구체적인 이유는 어떤 동작 때문에 저렇게 나오는지 아직은 모르겠다. 하지만 찾아보는 과정은 꽤나 재밌을 거 같다.

이후 장들에서는 여러 CPU 아키텍쳐에서의 어셈블리에 대해 배운다 한다.