[혼공컴운] Ch03. 명령어
소스 코드와 명령어
컴퓨터 언어는 크게 고급 언어와 저급 언어로 구분됩니다.
고급 언어와 저급 언어
고급 언어는 개발자가 읽고 쓰기 편하게 만들어진 언어이며, 예시로는 C언어, 자바, 파이썬 등이 있습니다. (현대 프로그래밍 언어)
반면 저급 언어는 컴퓨터가 이해하고 실행하기 위해 만들어진 언어로, 기계어와 어셈블리어가 있습니다. (본래 기계어만 있었으나, 사람들이 그나마 기계어에 비해 읽고 쓰기 편하도록 어셈블리어를 개발하였습니다. (아래는 어셈블리어의 예시입니다.)
push rbp
mov rbp, rsp
mov DWORD PTR [rbp-4], 1
mov DWORD PTR [rbp-8], 2
mov edx, DWORD PTR [rbp-4]
mov eax, DWORD PTR [rbp-8]
add eax, edx
mov DWORD PTR [rbp-12], eax
mov eax, 0
pop rbp
ret
모든 개발자가 저급 언어로 개발할 일은 없긴 하지만, 하드웨어와 밀접하게 맞닿아있는 프로그램을 개발하는 사람들은 어셈블리어를 이용하기도 합니다.
고급 언어 - 저급 언어 변환 과정
아무래도 고급 언어, 즉 현대 프로그래밍 언어를 개발하면 컴퓨터가 이해하기 힘들겠죠? 그래서 고급 언어를 작성했을 시 이를 저급 언어로 바꿔주어야 합니다. 이때 컴파일 언어는 컴파일 (compile) 되고, 인터프리터 언어는 인터프리트 (interpret) 되어 저급 언어로 변환됩니다.
컴파일 언어는 작성한 소스 코드가 컴파일러에 의해 저급 언어인 목적 코드로 변환되며, 이 때 컴파일러는 소스 코드를 전체적으로 훑어봅니다. 이 때 문법상 에러가 생긴다면 컴파일 예외가 발생합니다.
반면 인터프리터 언어는 인터프리터에 의해 소스 코드가 한 줄씩 실행 (이 점 때문에 인터프리터 언어가 컴파일 언어보다 속도가 느립니다. 인터프리터 언어는 소스 코드 마지막에 이를 때 까지 저급 언어로 각각 해석하며 실행합니다.) 되며, N번째 줄에서 오류가 생길 경우 N-1번째 줄 까지는 실행이 되도록 합니다.
가끔 프로그래밍 언어를 구분지을 때 "자바는 컴파일 언어고, 파이썬은 인터프리터 언어다"는 내용을 들으신 적이 있을 것입니다.
하지만 엄밀히 말해서 컴파일 언어와 인터프리터 언어는 완벽히 구별될 수 없습니다. 파이썬은 도중에 컴파일이 일어나기도 하며, 자바의 경우 저급 언어가 되는 과정에서 컴파일과 인터프리터를 동시에 수행하기도 합니다.
목적 코드 vs 실행 파일
목적 파일은 목적 코드로 이루어진 파일을 뜻하며, 실행 파일은 실행 코드로 이루어진 파일을 뜻합니다.
목적 코드가 실행 파일이 되기 위해서는 링킹 (Linking) 작업을 거쳐야 합니다.
목적 코드, 실행 파일은 간단히 말하면 여러분이 C언어로 개발한 계산기 프로그램이 있다고 할 때, 해당 작성 코드를 컴파일하면 생기는 파일이 목적 코드이며, 직접 실행할 수 있는 파일 (exe 등)이 실행 파일이 됩니다.
링킹 작업이 필요한 이유는 기능들이 여러 파일들에 나뉘어 있을 때 이를 하나로 엮기 위해서입니다. 예시로 덧셈/뺄셈 기능, 곱셈/나눗셈 기능, 출력 기능이 각각 하나의 C언어 파일에 작성되어 있다고 했을 시, 출력 기능 입장에서는 나머지 두 기능들에 대해서도 알아야겠죠.
명령어의 구조
다음으로는 저급 언어를 좀 더 자세히 보겠습니다. 저급 언어의 핵심은 명령어로 구성되어 있다는 것입니다.
오퍼랜드 (operand)
우리가 어떤 것에 명령을 할 때는 [누구에게] [무엇을 하라]는 식으로 명령을 합니다. 이와 유사하게, 명령어 또한 비슷한 구조를 가지고 있습니다. 이때 명령을 수행할 주체를 컴퓨터에서는 오퍼랜드 (operand)라 합니다. (어셈블리어 구조의 오른쪽 단어가 오퍼랜드를 의미합니다.)
오퍼랜드의 개수는 여러 개가 될 수도, 아예 없을 수도 있습니다. 오퍼랜드의 개수에 따라 n-주소 명령어라 합니다.
특이한 점은 오퍼랜드에는 직접적인 값이 아니라, 이 값이 들어있는 주소가 담길 수도 있다는 점 입니다. 그리고 실제적인 값에 비해 주소가 더 자주 저장됩니다.