728x90
안녕하세요. 해당 포스트는 강민철 저자님의 '혼자 공부하는 컴퓨터 구조+운영체제'를 읽고 정리한 포스트입니다.
03-1. 소스 코드와 명령어
모든 소스 코드는 컴퓨터 내부에서 명령어로 변환됨!
고급 언어와 저급 언어
고급언어
- JAVA, Python, C, C++ 같은 프로그래밍 언어
- 개발자(사람)를 위한 언어
저급언어
- 컴퓨터가 직접 이해하고 실행할 수 있는 언어
- 기계어 : 0과 1의 명령어 비트로 이루어진 언어(16진수로 표현하기도 함)
- 어셈블리어 : 0과 1로 표현된 명령어(기계어)를 읽기 편한 형태로 번역한 언어
컴파일 언어와 인터프리터 언어
고급 언어가 저급 언어로 변환되는 방식
- 컴파일 방식
- 인터프리터 방식
컴파일 언어
- 컴파일 방식으로 작동하는 프로그래밍 언어
- 컴파일 언어로 작성된 소스 코드는 컴파일러에 의해 저급 언어로 변환(컴파일)되고, 컴파일의 결과로 저급 언어인 목적 코드가 생성됨
- 컴파일러가 소스 코드 내에서 오류를 하나라도 발견하면 해당 소스 코드는 컴파일에 실패함. 소스 코드를 통째로 컴파일함
- 대표적으로 C가 있음
인터프리터 언어
- 인터프리트 방식으로 작동하는 프로그래밍 언어
- 소스 코드를 한 줄씩 저급 언어로 변환(인터프리터)하여 실행함
- 한 줄씩 실행하기 때문에 소스 코드 전체를 저급 언어로 변환하는 시간을 기다릴 필요가 없음
✔️ 컴파일을 통해 나온 목적 코드는 컴퓨터가 이해하고 실행할 수 있는 저급 언어인 반면, 인터프리터 언어는 소스 코드 마지막에 이를 때까지 한 줄씩 저급 언어로 해석하며 실행하기 때문에 일반적으로 인터프리터 언어가 컴파일 언어보다 느림!
C언어의 컴파일 과정
전처리기(Preprocessor)
- test.c → test.i
- 컴파일 전 처리할 작업들
- 외부에 선언된 다양한 소스 코드, 라이브러리 포함 (e.g. #include)
- 프로그래밍의 편의를 위해 작성된 매크로 변환 (e.g. #define)
- 컴파일할 영역 명시 (e.g. #if, #indef)
컴파일러(Compiler)
- test.i → test.s
- 전처리가 완료되어도 여전히 소스 코드임!
- 전처리가 완료된 소스 코드를 저급 언어(어셈블리 언어)로 변환
어셈블러(Assembler)
- test.s → test.o
- 어셈블리어를 기계어로 변환
- 목적 코드를 포함하는 목적 파일이 됨
링커(Linker)
- test.o → test.exe
- 각기 다른 목적 코드를 하나의 실행 파일로 묶어주는 작업 -> 링킹(linking)
03-2. 명령어의 구조
연산 코드와 오퍼랜드
명령어는 연산 코드(operation code)와 오퍼랜드(operand)로 구성되어 있음
연산 코드가 담기는 영역을 연산 코드 필드, 오퍼랜드가 담기는 영역을 오퍼랜드 필드라고 함
연산 코드(=연산자)
- 명령어가 수행할 연산
- 연산 코드의 종류와 생김새는 CPU마다 다름
- 연산 코드 종류
- 데이터 전송
- 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 : 입출력 장치의 상태를 확인하라
- 데이터 전송
오퍼랜드(=피연산자)
- 연산에 사용할 데이터 또는 연산에 사용할 데이터가 저장된 위치(이게 훨씬 더 많이 저장함!!)
- 주소 필드라고 부르기도 함
- 오퍼랜드가 하나도 없는 명령어(0-주소 명령어)가 있을 수도 있고 오퍼랜드가 n개인 명령어(n-주소 명령어)가 있을 수도 있음
주소 지정 방식
- 명령어의 오퍼랜드에 값을 직접 넣지 않고 메모리나 레지스터의 주소를 담는 이유? 명령어의 길이 때문!
- 유효 주소 : 연산 코드에 사용할 데이터가 저장된 위치
즉시 주소 지정 방식
- 연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시하는 방식
- 데이터의 크기가 작아지는 단점이 있음
- 연산에 사용할 데이터를 메모리나 레지스터로부터 찾는 과정이 없기 때문에 빠름
직접 주소 지정 방식
- 오퍼랜드 필드에 유효 주소를 직접적으로 명시하는 방식
- 표현할 수 있는 오퍼랜드 필드의 길이가 연산 코드의 길이만큼 짧아져 표현할 수 있는 유효 주소에 제한이 생길 수 있음
간접 주소 지정 방식
- 유효 주소의 주소를 오퍼랜드 필드에 명시
- 직접 주소 지정 방식보다 표현할 수 있는 유효 주소의 범위가 넓어졌지만 두 번의 메모리 접근이 필요하기 때문에 느린 방식임 (CPU가 메모리 접근을 최소화하는 것이 속도면에서는 무조건 좋음!)
레지스터 주소 지정 방식
- 연산에 사용할 데이터를 저장한 레지스터를 오퍼랜드 필드에 직접 명시
레지스터 간접 주소 지정 방식
- 연산에 사용할 데이터를 메모리에 저장하고 그 주소(유효 주소)를 지정한 레지스터를 오퍼랜드 필드에 명시하는 방법
스택과 큐
스택(stack)
- 한쪽 끝이 막혀 있는 통과 같은 저장 공간
- 메모리에 위치해있음
- 나중에 저장한 데이터를 가장 먼저 빼내는 데이터 관리 방식(LIFO, Last In First Out, '리포')
큐(queue)
- 양쪽이 뚫려 있는 통과 같은 저장 공간
- 선입선출(FIFO, First In First Out, '피포')
728x90
'CS > 컴퓨터구조' 카테고리의 다른 글
[CS/컴퓨터구조] 메모리 구조 (1) | 2024.11.08 |
---|---|
[CS/컴퓨터구조] 2. 데이터 (1) | 2024.01.14 |
[CS/컴퓨터구조] 1. 컴퓨터 구조 시작하기 (0) | 2024.01.14 |