모든 프로그램은 컴퓨터 부품이 실행하며, 이는 성능, 용량, 그리고 비용을 결정한다.

✔️ 컴퓨터구조의 큰 두 분류
1. 프로그램을 이루는 두 정보
1) 명령어 (instruction) : 컴퓨터를 동작시키는 실질적인 정보
2) 데이터 (data) : 명령어의 대상 (재료)


2. 컴퓨터의 네 가지 핵심 부품

1) CPU : 명령어 해석, 실행 담당하는 장치

  • fetch를 해서 execute를 함
  • 레지스터, ALU (계산기회로), 제어장치(명령어를 해석하여 제어 신호를 송출)로 구성

2) 메인 메모리 & 캐시 메모리 : 실행 중인 프로그램 저장하는 장치

  • 휘발성 메모리

3) 보조기억장치 : 보관할 프로그램 저장하는 장치

  • 비휘발성 메모리

4) 입출력장치(I/O) : 컴퓨터 내외부와 정보를 주고 받는 장치

메인 보드(마더보드) : 이러한 핵심 부품들을 연결할 기판
시스템 버스 : 부품 간 정보를 주고받을 통로

📍 명령어

  • 소스코드 : 사람(개발자)이 이해하기 편한 언어 → 고급 언어
  • 명령어와 데이터 : 컴퓨터가 이해하기 편한 언어 → 저급 언어

    즉, 고급 언어로 작성된 소스코드는 내부적으로 저급 언어로 구성된 명령어와 데이터로 변환된다. 따라서 CPU나 컴파일러의 종류에 따라 변환되는 언어의 형태가 달라질 수 있다.

✔️ 저급 언어의 두 종류

  • 기계어 (machine code)
  • 어셈블리어 (assembly language)

✔️ 고급 언어에서 저급 언어로 변환되는 대표적 방식

  • 컴파일

    • 소스 코드 전체가 컴파일러에 의해 검사, 목적 코드로 변환
    • 대표적 언어 : C/C++, Rust
    • 대표적 활용 : gcc, clang, Visual Studio
  • 인터프리트 (interpret)

    • 소스 코드 한 줄씩 인터프리터에 의해 검사, 목적 코드로 변환
    • 대표적 언어 : Python, Javascript

오개념 주의

  • 소스 코드가 저급 언어로 변환되는 대표적인 방식일 뿐, 파일 방식과 인터프리트 방식은 칼로 자르듯 구분되는 개념은 아님!
  • 대표적으로 Java처럼, 컴파일 언어의 특성과 인터프리트 언어의 특성을 모두 갖춘 언어도 존재함

고급언어에서 저급언어로 바뀌는 과정은 complier explorer에서 확인 가능하다. (https://www.godbolt.org/)

사진에서와 같이 색깔로 구분지어 각 코드 라인이 어떻게 변환되는지 시각적으로 확인이 가능하다.

putty등과 같은 곳에서 컴파일을 해보자

$cat hello.c // 파일 내용을 복사하여 출력
#include <stdio.h>

int main()
{
	printf("hello world\n");
    return 0;
}

$gcc -o hello hello.c // hello라는 파일에 hello.c을 컴파일한 결과를 저장
$ ./hello
hello world

$gcc -S hello.c -o hello.S //hello.c로 어셈블리어 생성하여 hello.S에 저장

📌 명령어 구조

이때, 명령어는 어떤 것을 대상으로 어떤 것을 수행할 것을 명시하는 것이다.
명령의 대상오퍼랜드(operand)라고 하며, 명령의 동작연산코드(op-code)라고 한다.

오퍼랜드는 대상(데이터)이 직접 명시되기도 하고, 대상의 위치 즉 레지스터 이름이나 메모리 주소가 명시되기도 한다.

연산코드설명
데이터MOVE데이터를 옮겨라
전송STORE메모리에 저장해라
LOAD(FETCH)메모리에서 가져와라
PUSH스택 최상단에 데이터를 저장하라
POP스택 최상단의 데이터를 가져와라
---------
산술ADD/SUBTRACT/MULTIPLY/DIVIDE덧셈/뺄셈/곱셈/나눗셈을 수행하라
논리INCREMENT/DECREMENT1 증가/감소시켜라
연산AND/OR/NOTAND/OR/NOT 연산을 수행해라
COMPARE두 숫자 또는 TRUE/FALSE 값을 비교하라
---------
제어JUMP특정 주소로 실행 순서를 옮겨라
흐름CONDITIONAL JUMP조건에 부합할 경우 특정 주소로 실행 순서를 옮겨라
HALT프고르매 실행을 멈춰라
CALL되돌아올 주소를 저장한 채 특정 주소로 실행 순서를 옮겨라
RETURNCALL 호출 시 지정했던 주소로 돌아가라
---------
입출력READ(INPUT)특정 입출력장치로부터 데이터를 읽어라
제어WRTIE(OUTPUT)특정 입출력장치로 데이터를 써라
START IO입출력장치를 시작하라
TEST IO입출력장치의 상태를 확인하라

📌 주소 지정

주소를 지정하여 이야기하는 이유는 명령어의 길이가 한정되어 있기 때문!

  • 유효 주소 : 연산 코드에 사용할 데이터가 저장된 위치, 즉 연산의 대상이 되는 데이터가 저장된 위치
  • 주소 지정 : 유효 주소를 찾는 방법으로, CPU마다 차이가 있음

✔️ 주소 지정 방식
1. 즉시 주소 지정
- 연산에 사용할 데이터를 오퍼랜드 필드에 직접 명시
- 가장 빠른 주소 지정 + 데이터 크기에 제한

  1. 직접 주소 지정
    • 오퍼랜드 필드에 유효 주소(연산에 사용될 데이터가 저장된 메모리 주소) 명시
    • 오퍼랜드 필드로 표현 가능한 메모리 주소 크기에 제한
  2. 간접 주소 지정
    • 오퍼랜드 필드에 유효 주소의 주소 명시
    • 유효 주소 크기에 제한은 없으나, 속도가 비교적 느림
  3. 레지스터 주소 지정
    • 연산에 사용할 데이터를 저장한 레지스터를 오퍼랜드 필드에 직접 명시
    • 레지스터 접근은 메모리보다 빠름!
  4. 레지스터 간접 주소 지정
    • 연산에 사용할 데이터를 메모리에 저장하고,
    • 그 주소(유효 주소)를 저장한 레지스터를 오퍼랜드 필드에 명시
    • 메모리 접근은 한 번!

📍 데이터

컴퓨터는 0과 1만을 이해한다.

  • 모든 양수를 0과 1로 표현하는 방법 : 이진수
  • 모든 음수를 0과 1로 표현하는 방법 : 2의 보수
  • 모든 소수를 0과 1로 표현하는 방법 : 부동 소수점
  • 모든 문자를 0과 1로 표현하는 방법 : 문자 집합 & 인코딩

📌 이진수와 2의 보수

  • 이진법 : 0과 1로 모든 수를 표기하는 방법
  • 이진수 (binary) : 0과 1만으로 표현된 수
  • 1을 넘어가는 시점에 자리 올림!
  • 단점 : 숫자가 너무 길어짐

2의 보수법

  • CPU 내부의 정보, 플래그(flag)
    • 플래그(flag) : CPU가 명령어를 실행하는 과정에서 참고할 정보의 모음
  • 음수 플래그가 세팅되어 있을 경우 : 음수
  • 음수 플래그가 세팅되어 있지 않을 경우 : 양수

👉 16진법(16진수)

  • 2진수의 길이가 너무 길어진다는 점을 보완
  • 1~9과 A~F로 모든 수를 표기하는 방법
  • 15(F)를 넘어가는 시점에 자리 올림!
    • A:10, B:11, C:12, D:13...

📌 부동 소수점
십진수 소수를 이진수로 표현할 때 십진수 소수와 이진수 소수 표현이 딱 맞아 떨어지지 않을 수 있어, 십진수 소수 값을 계산하여 그 값을 비교할 때 원하는 값이 도출되지 않을 수 있다.

ex. 1/3이라는 분수를 m X 3^n 꼴로 표현하면 딱 떨어지지만, mx X 10^n 꼴로 표현하면 무한히 많은 가수가 필요하다.


📌 문자 인코딩과 디코딩

0과 1로 문자 표현하기

  • 문자 집합 : 표현 가능한 문자들의 집합
  • 문자 인코딩 : 문자를 0과 1로 이루어진 문자 코드로 변환
  • 문자 디코딩 : 0과 1로 이루어진 문자 코드를 문자로 변환

흔히 코딩을 하다보면 문자가 깨지는 경우를 만날 수 있을 것이다. 이러한 경우는 인코딩 버전이 맞지 않아 발생하는 문제이다!

  • 아스키코드(ASCII) : 초창기 문자 집합으로, 알파벳 + 아라비아 숫자 + 일부 특수 문자 + 제어 문자
    • 7bit로 구성
    • 호환 가능 - 대응이 곧 인코딩


📍 CPU

📌 CPU 구성 요소

  • ALU(산술논리연산장치) : 연산을 수행하는 장치 (계산을 담당하는 회로)

    • 레시스터로부터 피연산자 (연산의 대상)을 받아들이고 제어 장치로부터 제어 신호 (연산할 작업)를 받아들임
    • 연산의 결과를 레지스터, 플래그 레지스터에 저장함

  • 제어 장치 : 명령어를 해석하고 제어 신호를 내보내는 장치

  • 레지스터 : 명령어 처리 전후로 값을 임시 저장하는 장치

    • 플래그 레지스터 : 연산의 결과에 대한 부가 정보
      • 부호 플래그 : 연산의 결과의 부호를 나타냄
      • 제로 플래그 : 연산 결과가 0인지 여부를 나타냄
      • 캐리 플래그 : 연산 결과 올림수나 빌림수가 발생했는지 여부를 나타냄
      • 오버플로우 플래그 : 오버플로우가 발생했는지 여부를 나타냄
      • 인터럽트 플래그 : 인터럽트가 가능한지 여부를 나타냄
      • 슈퍼바이저 플래그 : 커널 모드로 실행 중인지, 사용자 모드로 실행 중인지를 나타냄

📌 레지스터 살펴보기


📌 명령어 사이클과 인터럽트


profile
욕심 많은 공대생

0개의 댓글