어셈블리어에 대한 개념 정리

2024. 9. 28. 17:07STUDY/내가 궁금해서 끄적한 내용

어셈블리어

어셈블리어 : 컴퓨터 언어는 0과 1로 구성된 기계어이다. 이를 사람이 이해하긴 어렵다. 
예를 들어 '01001100 00001000 10000001 10010000' 같은 기계어 명령어를 어셈블리어에서는 'MOV'라고 하면 된다. 
물론 컴퓨터는 'MOV' 라는 명령어를 전혀 이해하지 못한다. 컴퓨터는 0과 1만 알아듣기 때문이다. 그래서 이 어셈블리어는 일종의 번역 과정을 거쳐 컴퓨터가 이해하는 기계어 코드로 변환되는데, 이것을 컴파일 이라고 한다. 프로그래머가 어셈블리어로 프로그램 코드를 작성한 후 컴파일러라는 소프트웨어를 이용하여 실행 파일을 만들어내는데, 이 실행 파일이 바로 프로그램이다. 어셈블리어처럼 프로그램을 작성하기 위해 만들어진 인공 언어 체계를 '프로그래밍 언어'라고 한다.

어셈블리어에 대해 조금더 자세히 알아보자.
어셈블리어는 저수준의 프로그래밍 언어로 거의 기계어와 1:1로 대응된다. 하지만 대두분의 프로그램을 개발할때 어셈블리어로 작성하는 것은 비효율적이기 때문에 실제로는 C, C++와 같은 고수준언어로 작성하고 컴파일러를 통해 생성한다.  실제로 어셈블리어로 코딩을 하는 경우는 장치 드라이버나 임베디드 시스템을 만드는 경우등 한정적이다.

게다가 어셈블리어라는 것은 기계어와 대응되는 만큼 기계마다 동일하지 않다. 대체로 유사하지만 같은 코드를 다양한 기계에서 사용할 수 없다는 것이다. 하지만 어셈블리어는 기계어에 가깝기 때문에 파이썬과 같은 고수준 프로그래밍 언어에는 배울 수 없는 많은 것들을 경험하게 된다.

[어셈블리어를 배워야하는 이유]

1. 아키텍처에 대한 이해 향상
어셈블리어는 기계를 직접 조작하는 명령어의 모음이다. 이때 기계라는 것은 단순히 '컴퓨터'같은 것이 아니라 이 구성 요소인 CPU, 메모리 등을 말합니다. 단순한 계산 명령을 위해서도 프로세서의 레지스터를 조작해야 하고, 직접 메모리 주소를 지정해가며 모니터 화면에 출력하는 것과 같은 하드웨어 조작을 위한 입/출력도 세세하게 모두 지정해야 한다.

2. 개발 도구에 대한 이해 향상
파이썬과 같은스크립트언어는 코딩하고 실행하면 결과가 나온다. 당연하다.
당연한가?
컴퓨터는 기계어밖에 못하고 결국에는 어떤 언어가 되었든 기계어로 번역되어야 한다. 추상화에 추상화를 거듭해서 편린한 IDE를 쓰면 빌드 버튼을 클릭하는 것으로 모든게 한번에 당연한듯 처리된다. 하지만 내가 작성한 코드가 빌드 버튼을 클릭했을때 어떻게 변환되어 컴퓨터에 전달되는지 궁금하지 않은가? 빌드 버튼 클릭시 처리되는 컴파일, 어셈블, 링킹 등을 어셈블리어를 배우면서 자세히 살펴볼 수 있다.

3. 함수 호출 방식에 대한 이해 향상
함수를 로직의 분리 정도로 이해하고 있나? 어셈블리어를 학습하다보면 전역 변수와 지역 변수가 위치하는 구조, 프로그램의 실행 흐름이 함수 호출로 어떻게 변경되는지 이때 일어나는 일들이 무엇인지 알게 된다.

4. 하드웨어에 직접 엑세스
이건 어셈블리어가 아니면 다른 언어로는 할 수 없는 영역이 될 수도 있다. 말 그대로 하드웨어를 직접 제어하는 것이니까,
고수준의프로그래밍 언어로 기계 장치를 제어한다는 거은 OS의 API를 호출하는 것이다. 즉 OS에 하드웨어 조작을 부탁하는 것이다. 대부분의 사용자가 사용하는 OS는 동시에 여러가지 앱을 실행하게 되므로 이렇게 중간에서 OS가 처리해주지 않으면 하드웨어를 직접 조작하려는 앱들 간의 충돌로 지금과 같이 안정적으로 스마트폰이나 컴퓨터를 사용할 수 없을 것이다.
OS도 결국엔 하드웨어 조작을 위해 이를 처리해주는 프로그램이 필요한데, 이런 것을 대신 해주는프로그램이 장치 드라이버이며 어셈블리어로 만들게 된다.
임베디드 시스템과 같이 제한된 환경에서는 언어 선택지도 제한되어 있고 그렇다면 이때 사용하게 될 언어는 어셈블리어다.

5. 문제 해결 범위 증가
Chrome에서 문제가 발생해서 자바 스크립트 실행이 중단된 상황을 가정해보자. 
(물론 대부분의 경우 내 코드가 문제일테지만)내가 작성한 코드에서는 문제를 확인할 수 없다. 이렇게 까다로운 문제가 발생했을때 어셈블리어를 배워두면 실제로 작성하지 않더라도 이런 경우 컴파일된 어셈블리어 코드를 보고 문제의 원인을 파악할 수 있게 된다.
꼭 버그를 찾는 경우가 아니라, 바이너리만 있는 다른 프로그램의 내용을 보는 경우, 즉 리버스 엔지니어링을 할 때에도 어셈블리어는 필요하다.

 

참고 자료