[혼공컴운] chapter03 명령어

소스코드와 명령어

저급언어, 고급언어

'사람을 위한 언어'를 고급언어, '컴퓨터가 직접 이해하고 실행할 수 있는 언어'를 저급언어라고 한다. 

그래서 고급 언어로 작성된 소스 코드가 실행되려면 반드시 저급언어, 즉 명령어로 변환되어야 한다.

저급언어에는 두 가지 종류가 있다. 

  • 기계어

0 과 1의 명령어 비트로 이루어진 언어이다. 가독성을 위해 십육진수로 표현하기도 한다.

  • 어셈블리어

0과 1로 표현된 명령어를 읽기 편한 형태로 번역한 언어이다.

etc-image-0
어셈블리어 https://ko.wikipedia.org/wiki/%EC%96%B4%EC%85%88%EB%B8%94%EB%A6%AC%EC%96%B4

컴파일 언어와 인터프리터 언어

개발자들이 고급 언어로 작성한 소스코드는 두 가지 방식으로, 컴파일러와 인터프리터로 인해 저급언어로 변환된다.

  • 컴파일 언어

컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 고급 언어이다. (예 : c)

컴파일이 성공적으로 수행되면 컴파일러를 통해 저급 언어로 변환된 목적 코드가 만들어진다.

  • 인터프리터 언어

인터프리터에 의해 소스 코드가 한 줄씩 실행되는 고급 언어이다. (예: python)

소스 코드를 한 줄씩 저급 언어로 변환하여 실행하는 인터프리터를 사용하여 컴파일 언어보다 빠르다고 생각할 수 있지만, 

일반적으로 인터프리터 언어는 컴파일 언어보다 느리다.

 

자바의 경우, 컴파일과 인터프리트를 동시에 수행한다

자바 컴파일러(Java Compiler)로 작성한 Java 코드를 자바 가상 머신(Java Virtual Machine, JVM)이 실행시킬 수 있는 자바 바이트 코드로 번역한다.

하지만

하지만 자바 바이트 코드는 자바 가상 머신(JVM)의 자바 인터프리터(Java Interpreter)를 이용해 한 줄씩 실행된다. 조금 더 자세하게 말하자면, 자바 바이트 코드로 작성되어 있는 실행 프로그램을 자바 인터프리터가 한 줄씩 읽으면서 컴퓨터가 이해할 수 있는 2진 코드로 번역한 후 실행시킨다는 뜻이다. 

etc-image-1

따라서 자바는 하이브리드 언어라고 불린다.

원래 인터프리터 언어였는데 성능 향상을 위해 컴파일러를 가져왔다고 한다.

 

명령어의 구조

연산 코드와 오퍼랜드

명령어 = 연산코드 + 오퍼랜드

연산 코드(연산자) : 명령어가 수행할 연산

오퍼랜드(피연산자) : 연산에 사용할 데이터가 저장된 위치 (주소필드)

이때 연산 코드는 네 가지 유형으로 나눌 수 있다.

  • 데이터 전송
  • 산술/논리 연산
  • 제어 흐름 변경
  • 입출력 제어

즉시 주소 지정 방식

즉시 주소 지정 방식은 

연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시하는 방식이다.

이런 방식은 표현할 수 있는 데이터 크기가 작아지는 단점이 있지만, 

연산에 사용할 데이터를 메모리나 레지스터로부터 찾는 과정이 없기 때문에 이하 설명할 주소 지정 방식보다 빠르다.

etc-image-2

직접 주소 지정 방식

직접 주소 지정 방식은

오퍼랜드 필드에 유효 주소를 직접적으로 명시하는 방식이다.

오퍼랜드 필드에서 표현할 수 있는 데이터의 크기는 즉시 주소 지정 방식보다 더 커졌지만, 

여전히 유효 주소를 표현할 수 있는 범위가 연산 코드의 비트 수만큼 줄었다. 표현할 수 있는 유효 주소 (데이터가 저장된 위치) 에 제한이 생길 수 있다.

etc-image-3

간접 주소 지정 방식

간접 주소 지정 방식은

유효 주소의 주소를 오퍼랜드 필드에 명시한다. 직접 주소 지정 방식보다 표현할 수 있는 유효 주소의 범위가 더 넓어졌지만, 두 번의 메모리 접근이 필요해 일반적으로 느린 방식이다.

etc-image-4

레지스터 주소 지정 방식

레지스터 주소 지정 방식은

데이터를 저장한 레지스터를 오퍼랜드 필드에 직접 명시하는 방법이다.

CPU 외부에 있는 메모리에 접근하는 것보다 CPU내부에 있는 레지스터에 접근하는 것이 더 빠르다.

etc-image-5

 

레지스터 간접 주소 지정 방식

레지스터 간접 주소 지정 방식은

연산에 사용할 데이터를 메모리에 저장하고, 그 주소를 저장한 레지스터를 오퍼랜드 필드에 명시하는 방법이다.

간접 주소 지정 방식 과 비슷하지만, 메모리에 접근하는 횟수가 한 번으로 줄어든다는 장점이 있다.

따라서 레지스터 간접 주소 지정 방식간접 주소 지정 방식보다 빠르다.