Chapter 03 명령어
03-1 소스 코드와 명령어
1. 고급 언어와 저급언어
① 고급 언어(high-level programming language)
-사람을 위한 언어 (사람이 읽고 쓰기 편하며, 더 나은 가독성, 편리한 문법 제공 덕분에 복잡한 프로그램을 구현할 수 있다)
-대부분의 프로그래밍 언어가 고급 언어에 속한다.
-고급 언어로 작성된 소스 코드는 반드시 저급 언어(명령어)로 변환되어야 실행이 가능하다.
② 저급 언어(low-level programming language)
-컴퓨터가 직접 이해하고 실행할 수 있는 언어 (프로그래머에게 작성의 대상이자 관찰의 대상, 프로그램의 작동 절차를 추적하고 관찰할 수 있다)
-명령어로 이루어져 있다.
-저급 언어에는 기계어와 어셈블리어 두 가지가 있다.
②-1 기계어(machine code)
-0과 1의 명령어 비트로 이루어진 언어
-이진수의 나열, 혹은 가독성을 위하여 십육진수로 표현하기도 한다.
②-2 어셈블리어(low-level programming language)
-기계어를 읽기 편한 형태로 번역한 언어
롤러코스터 타이쿤이라는 게임이 어셈블리어로 프로그래밍 된 게임이라는 얘기를 들은 것 같다.
2. 컴파일 언어와 인터프리터 언어
① 컴파일 언어
-컴파일 방식으로 작동하는 프로그래밍 언어
ex) C
-컴파일(compile) : 컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되는 과정. 컴파일러가 소스 코드 내에서 오류를 하나라도 발견할 시 해당 소스 코드는 컴파일에 실패한다.
-컴파일러(compiler) : 컴파일을 수행해 주는 도구. 소스 코드의 문법적 오류의 존재 여부, 실행 가능성, 실행 시 불필요한 코드가 없는지 확인하며 컴파일을 진행한다.
-목적 코드(object code) : 컴파일러를 통한 컴파일이 성공했을 때 저급 언어로 변환된 코드
-컴파일 언어의 장점 : 소스 코드를 목적 코드로 만들어서 컴퓨터가 이해하고 실행하기 때문에 빠르다.
ex) 다른 언어의 연설문을 미리 번역하여 빠르게 읽어내리는 것과 같다.
-컴파일 언어의 단점
: 소스 코드 전체를 저급 언어로 변환하는 데에 시간이 든다.
: 소스 코드에 오류가 단 하나라도 있을 시 실행이 불가능하다.
: 소스 코드가 바뀌면 다시 컴파일을 해야한다.
② 인터프리터 언어
-인터프리트 방식으로 작동하는 프로그래밍 언어
ex) Python
-인터프리트(interpret) : 인터프리터에 의해 소스 코드가 한 줄씩 실행되는 과정
-인터프리터(interpreter) : 소스 코드를 한 줄씩 저급 언어로 변환하여 실행해 주는 도구
-인터프리터 언어의 장점
: 소스 코드 전체를 저급 언어로 변환하는 시간을 기다릴 필요가 없다.
: 소스 코드에 오류가 있더라도 오류가 있는 줄의 전 줄까지는 올바르게 수행할 수 있다.
: 소스 코드가 바뀌어도 실행 지점이 바뀐 부분까지 도달하지 않았다면 다시 실행할 필요가 없다.
-인터프리터 언어의 단점 : 소스 코드를 한 줄씩 저급 언어로 변환하기 때문에 느리다.
ex) 다른 언어의 연설문을 한 줄 씩 번역하며 읽어내리는 것과 같다.
+컴파일 언어와 인터프리터 언어의 구분에 대하여
-하나의 프로그래밍 언어가 반드시 둘 중 하나의 방식만으로 작동하는 것은 아니다.
ex) Python도 컴파일을 하기는 하며, Java는 컴파일과 인터프리트를 동시에 수행한다.
≫'고급 언어를 저급 언어로 변환하는 방식에 컴파일 방식과 인터프리트 방식이 있다' 정도로만 이해하자.
3. 목적 파일 vs 실행 파일
① 목적 파일
-목적 코드로 이루어진 파일
-링킹 : 목적 코드를 실행 파일로 만드는 과정에서 목적 코드 간 기능을 연결 짓는 과정
소스 코드 | helper.c : 'HELPER_더하기'라는 기능이 구현되어 있다. |
main.c : helper.c에 구현된 'HELPER_더하기'와 프로그래밍 언어가 기본으로 제공하는 '화면_출력'이라는 기능을 사용 | |
컴파일 | helper.c를 컴파일 하여 helper.o라는 목적 파일을 생성 |
main.c를 컴파일 하여 main.o라는 목적 파일을 생성 | |
링킹 | main.o에는 'HELPER_더하기'와 '화면_출력'을 실행하는 방법이 없다. >main.o에 없는 외부 기능을 main.o와 연결 짓는 작업이 필요 >>링킹 실행 |
실행 파일 | 링킹 작업이 완료 되면 실행 파일을 생성 |
② 실행 파일
-실행 코드로 이루어진 파일
ex) .exe 확장자를 가진 파일
확인 문제
1. ③, ④
2. ②
03-2 명령어의 구조
1. 연산 코드와 오퍼랜드
① 명령어
-연산 코드와 오퍼랜드로 구성되어 있다.
-연산 코드 필드에는 연산 코드가, 오퍼랜드 필드(주소 필드)에는 오퍼랜드(숫자, 문자 등의 데이터/(대부분의 경우) 메모리 주소나 레지스터 이름)가 담긴다.
①-1 연산코드(operation code, 연산자)
-명령어가 수행할 연산
-기본적으로 데이터 전송, 산술/논리 연산, 제어 흐름 변경, 입출력 제어의 네 가지로 나뉜다.
데이터 전송 | MOVE | 데이터를 옮겨라 |
STORE | 메모리에 저장하라 | |
LOAD(FETCH) | 메모리에서 CPU로 데이터를 가져와라 | |
PUSH | 스택에 데이터를 저장하라 | |
POP | 스택의 최상단 데이터를 가져와라 | |
산술/논리 연산 | ADD / SUBTRACT / MULTIPLY / DIVIDE | 덧셈 / 뺄셈 / 곱셈 / 나눗셈을 수행하라 |
INCREMENT / DECREMENT | 오퍼랜드에 1을 더하라 / 오퍼랜드에 1을 빼라 | |
AND / OR / NOT | AND / OR / NOT 연산을 수행하라 | |
COMPARE | 두 개의 숫자 혹은 TRUE / FALSE 값을 비교하라 | |
제어 흐름 변경 | JUMP | 특정 주소로 실행 순서를 옮겨라 |
CONDITIONAL JUMP | 조건에 부합할 때 특정 주소로 실행 순서를 옮겨라 | |
HALT | 프로그램의 실행을 멈춰라 | |
CALL | 되돌아올 주소를 저장한 채 특정 주소로 실행 순서를 옮겨라 (함수를 호출하는 명령어) |
|
RETURN | CALL을 호출할 때 저장했던 주소로 돌아가라 (함수에서 리턴하는 명령어) |
|
입출력 제어 | READ(INPUT) | 특정 입출력 장치로부터 데이터를 읽어라 |
WRITE(OUTPUT) | 특정 입출력 장치로 데이터를 써라 | |
START IO | 입출력 장치를 시작하라 | |
TEST IO | 입출력 장치의 상태를 확인하라 |
①-2 오퍼랜드(operand, 피연산자)
-연산에 사용할 데이터, 혹은 연산에 사용할 데이터가 저장된 위치
-오퍼랜드의 개수에 따른 명령어
오퍼랜드의 개수 | 이름 |
없다(0) | 0-주소 명령어 |
1개 | 1-주소 명령어 |
2개 | 2-주소 명령어 |
3개 | 3-주소 명령어 |
2. 주소 지정 방식
① 주소 지정이 필요한 이유
-명령어의 길이는 한정적이기 때문이다. 명령어가 n비트이며 1-주소 명령어이고, 연산 코드 필드가 m비트일 때, 오퍼랜드 필드는 n-m비트이다.
-오퍼랜드 필드 안에 데이터 자체가 아닌 메모리 주소(혹은 레지스터 이름)가 담길 때, 표현할 수 있는 데이터의 크기는 하나의 메모리 주소에 저장할 수 있는 공간만큼 커진다.
-유효 주소(effective address) : 연산의 대상이 되는 데이터가 저장된 위치
-주소 지정 방식(addressing mode) : 연산에 사용할 데이터 위치를 찾는 방법
② 즉시 주소 지정 방식(immediate addressing mode)
-오퍼랜드 필드에 연산에 사용할 데이터를 직접 명시하는 방식
-장점 : 연산에 사용할 데이터를 메모리나 레지스터에서 찾는 과정이 없어서 다른 주소 지정 방식들보다 빠르다.
-단점 : 표현할 수 있는 데이터의 크기가 작아진다.
③ 직접 주소 지정 방식(direct addressing mode)
-오퍼랜드 필드에 유효 주소를 직접적으로 명시하는 방식
-장점 : 표현할 수 있는 데이터의 크기가 즉시 주소 지정방식보다 크다.
-단점 : 오퍼랜드 필드의 길이가 연산 코드의 길이만큼 짧아졌기 때문에 표현할 수 있는 유효 주소의 길이에 제한이 생길 수 있다.
④ 간접 주소 지정 방식(indirect addressing mode)
-오퍼랜드 필드에 유효 주소의 주소를 명시하는 방식
-장점 : 직접 주소 지정 방식보다 표현할 수 있는 유효 주소의 범위가 더 넓다
-단점 : 두 번의 메모리 접근이 필요하여 위에 설명한 방식들보다 일반적으로 느리다.
데이터가 레지스터에 저장되어 있을 때 사용할 수 있는 방식들
⑤ 레지스터 주소 지정 방식(register addressing mode)
-오퍼랜드 필드에 연산에 사용할 데이터를 저장한 레지스털르 직접 명시하는 방식
-장점 : CPU 외부의 메모리보다 CPU 내부의 레지스터에 접근할 수 있기에 직접 주소 지정 방식보다 빠르게 데이터에 접근할 수 있다.
-단점 : 표현할 수 있는 레지스터 크기에 제한이 생길 수 있다.
⑥ 레지스터 간접 지정 방식(register indirect addressing mode)
-오퍼랜드 필드에 연산에 사용할 데이터를 메모리에 저장하고 그 유효 주소를 저장한 레지스터를 명시하는 방식
-장점 : 메모리 접근 횟수가 1회로 줄어서 간접 주소 지정 방식보다 빠르다.
3. 스택과 큐
① 스택(stack)
-제일 마지막으로 삽입된 데이터가 제일 먼저 삭제되는 형식의 저장 공간(LIFO;Last-In-First-Out, 후입 선출)
-PUSH : 스택에 새로운 데이터를 저장하는 명령어
-POP : 스택에 마지막으로 삽입된 데이터를 꺼내는 명령어
② 큐(queue)
-제일 처음에 삽입된 데이터가 제일 먼저 삭제되는 형식의 저장공간(FIFO;First-In-First-Out, 선입 선출)
-새로운 원소가 삽입되는 끝을 rear, 원소가 삭제되는 끝을 front라고 한다.
-Enqueue (PUSH, insertion, addition, put 등을 사용하기도 한다) : 큐의 rear에 새로운 데이터를 저장하는 명령어
-Dequeue (POP, deletion, removal 등을 사용하기도 한다) : 큐의 front에서 데이터를 꺼내는 명령어
-간혹 스택과 동일한 PUSH, POP 명령어를 쓰기도 한다.
확인 문제
1. ②
2. ① 6, ② 200
'혼자 공부하는 컴구, 운체' 카테고리의 다른 글
[3주차] Chapter 06. RAM, 메모리 주소, 캐시 메모리 (0) | 2023.07.23 |
---|---|
[2주차] Chapter 05. 클럭, 멀티코어, 멀티스레드, 명령어 병렬 처리 기법, CISC, RISC (0) | 2023.07.16 |
[2주차] Chapter 04. ALU, 제어장치, 레지스터, 명령어 사이클, 인터럽트 (0) | 2023.07.16 |
[1주차] Chapter 02. 이진법, 십육진법, 아스키코드, 유니코드 (0) | 2023.07.09 |
[1주차] Chapter 01. 컴퓨터 구조, 데이터, 명령어 (0) | 2023.07.09 |