컴퓨터 구조란 무엇일까?
- 모든 프로그램은 컴퓨터 부품이 실행한다. : 성능&용량&비용
- 프로그램을 이루는 두 정보(0과 1로 이루어진 정보) : 명령어, 데이터
- 명령어 : 컴퓨터를 동작시키는 실질적인 정보
- 데이터 : 명령어의 대상(재료)
- 컴퓨터 네 가지 핵심 부품
- CPU : 명령어 해석, 실행 담당하는 장치
- 내부 구성 : 레지스터(저장장치, 여러개), ALU(계산기 회로), 제어 장치(명령어 해석, 제어 신호)
- 메인 메모리 & 캐시 메모리 : 실행 중인 프로그램 저장하는 장치(전원이 꺼지면 삭제)
- 주소
- 보조기억장치 : 보관할 프로그램 저장하는 장치(전원이 꺼져도 저장 유지)
- HDD, SSD, ...
- 입출력장치 : 컴퓨터 내외부와 정보를 주고받는 장치
- 모니터, 키보드, 스피커, ...
- CPU : 명령어 해석, 실행 담당하는 장치
명령어
- 고급 언어로 작성된 소스 코드는 내부적으로 저급 언어로 구성된 명령어와 데이터로 변환된다.
- 저급 언어의 두 종류 : 기계어, 어셈블리어
- 기계어 : 컴퓨터가 직접 이해하는 언어, 16진수
- 어셈블리어 : 사람들이 조금 읽기 쉽게 만든 언어
- ex) sub sp, sp, #16
- cpu와 컴파일러에 따라 기계어와 어셈블리어가 달라질 수 있다.
- 고급 언어에서 저급 언어로 변환되는 대표적인 방식 : 컴파일, 인터프리트
- 컴파일
- 소스 코드 전체가 컴파일러(gcc, clang, visual studio, ..)에 의해 검사, 목적 코드(Object Code)로 변환
- C/C++, Rust
- 인터프리트
- 소스 코드 한 줄씩 인터프리터에 의해 검사, 목적 코드로 변환
- Python, JavaScript
- 오개념 주의!!
- 소스 코드가 저급 언어로 변환되는 대표적인 방식일 뿐. 컴파일 방식과 인터프리터 방식을 칼로 자르듯 구분되는 개념은 아니다.
- 컴파일 언어의 특성과 인터프리터 언어의 특성을 모두 갖춘 언어도 있다. (Java, Python, ..)
- 컴파일
* 명령어 실습하기 (godbolt.org)
- 명령어 구조
- 무엇을 대상(명령의 대상)으로 무엇을 수행(명령의 동작)하라
- 오퍼랜드로 연산 코드를 수행하라!
- 오퍼랜드(operand) : 명령어를 수행할 대상(=피연산자)
- 대상(데이터)이 직접 명시되기로 하고, 대상의 위치가 명시되기도 함
- 연산 코드(op-code)
- 오퍼랜드로 수행할 동작
- 예시
- 오퍼랜드의 갯수에 따라 같은 코드가 실행하는 단계의 갯수가 달라질 수 있다!
연산 코드 알아보기
- 데이터 전송
- 산술/논리 연산
- 제어 흐름 변경
- 입출력 제어
주소 지정
- 왜 데이터를 직접 명시하지 않고 위치를 명시하는 걸까?
- 그 이유는 명령어의 길이는 한정되어 있기 때문이다.
- 유효주소
- 연산 코드에 사용할 데이터가 저장된 위치, 즉 연산의 대상이 되는 데이터가 저장된 위치
- 주소 지정
- 유효 주소를 찾는 방법(=실제가 데이터가 있는 곳을 찾는 방법)
- CPU마다 차이가 있다!
- 주소 지정 종류
- 즉시 주소 지정
- 연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시
- 가장 빠른 주소 지정 + 데이터 크기에 제한
- 직접 주소 지정
- 오퍼랜드 필드에 유효 주소(연산에 사용될 데이터가 저장된 메모리 주소) 명시
- 오퍼랜드 필드로 표현 가능한 메모리 주소 크기에 제한
- cpu가 레지스터/메모리 접근 주소 속도가 느림
- 간접 주소 지정
- 오퍼랜드 필드에 유효 주소의 주소 명시
- 유효 주소 크기에 제한은 없으나, 속도가 비교적 느림
- 레지스터 주소 지정
- 연산에 사용할 데이터를 저장할 레지스터를 오퍼랜드 필드에 직접 명시
- 레지스터 접근은 메모리보다 빠르다!
- 레지스터 간접 주소 지정
- 연산에 사용할 데이터를 메모리에 저장하고
- 그 주소(유효 주소)를 저장한 레지스터를 오퍼랜드 필드에 명시
- 메모리 접근은 한 번
- 즉시 주소 지정