[CS:APP] 컴퓨터 시스템 1.1 ~ 1.4 Review

@developer/takealittle.time·2024년 9월 19일
1

Reading Book

목록 보기
1/5

요점만 간단히.


1.1 정보는 비트와 컨텍스트로 이루어진다.

  • 소스 프로그램은 0 또는 1로 표시되는 '비트'들의 연속.
  • 바이트 = 8비트 → 각 바이트로는 텍스트 문자를 나타낼 수 있다.
  • 대부분의 컴퓨터 시스템 → 아스키(ASCII) 표준을 이용해 텍스트 표시.

<아스키 (ASCII) 코드 표>

  • 아스키 문자들로만 이루어진 파일 = 텍스트 파일.
  • 다른 모든 파일들 = 바이너리 파일.

작성자의 KICK

  • 컴퓨터는 0과 1로 이루어진 '비트', 즉, '기계어'만 알아들을 수 있다. 우리가 C나 Python 등 고급 언어로 프로그램을 작성하면, '컴파일러'나 '인터프리터', '어셈블러'라는 통역가가 가운데 껴서 고급 언어를 컴퓨터가 알아들을 수 있는 저수준의 기계어로 번역해준다고 생각하면 쉽다.
  • ASCII는 이러한 기계어를 알파벳으로 나타내기 위한 일종의 '약속' 표준이다. (ex) '012'를 'A'라고 약속하자!

1.2 프로그램은 다른 프로그램에 의해 다른 형태로 번역된다.

책에서는 1장에서 hello.c 프로그램을 예시로 다루면서, 우리가 작성한 프로그램이 논리적으로, 또 물리적으로 어떤 과정을 거치는지 설명하고 있다.

  • 우리가 작성한 hello.c를 컴퓨터에서 실행시키려면 기계어 인스트럭션 수준으로 번역되어야 한다. → 이러한 인스트럭션들은 '실행가능 목적 프로그램 (Executable Object File)'의 형태로 저장된다.

컴파일 시스템: 전처리기, 컴파일러, 링커

1. 전처리 단계 ( hello.c → hello.i ): 본래의 C 프로그램을 #문자로 시작하는 directive에 따라 수정. ex) #include <stdio.h> → stdio.h 헤더 파일을 프로그램 문장에 직접 삽입.
2. 컴파일 단계 ( hello.i → hello.s ): hello.i 파일을 어셈블리어 수준으로 번역.
3. 어셈블리 단계 ( hello.s → hello.o ): 어셈블러(as)가 hello.s 파일을 기계어 인스트럭션 수준으로 번역, '재배치 가능 목적프로그램'의 형태로 묶어 hello.o 파일에 결과 저장.
4. 링크 단계( hello.o + printf.o → hello ): C 라이브러리에 있는 printf.o 목적 파일과 hello.o 목적 파일을 링커 프로그램(ld)이 결합 해 실행가능 목적 파일로 만든다.


1.3 컴파일 시스템이 어떻게 동작하는지 이해하는 것은 중요하다.

1.3 에서는 우리가 왜 이런 컴퓨터 언어의 번역에 대해 배워야하는지, 그 이유에 대한 대략적인 소개다.

다음과 같은 이유로 우리가 컴파일 시스템의 동작에 대해 배워야한다고 소개하는 내용이다.

  • 프로그램 성능 최적화하기
  • 링크 에러 이해하기
  • 보안 약점 피하기

1.4 프로세서는 메모리에 저장된 인스트럭션을 읽고 해석한다.

  • 1.2에서 컴파일 시스템을 다루면서 hello.c 소스 프로그램이 목적파일로 번역되는 과정을 살펴봤다.
  • 유닉스 시스템에서는 이 목적파일을 실행하기 위해서 '쉘(Shell)' 에 그 이름을 입력한다.
    →쉘은 명령어 라인이 내장 명령어가 아닌 경우 실행 파일의 이름으로 판단 → 파일을 로딩해서 실행해 준다.
linux> ./hello
hello, world
linux>

1.4.1 시스템의 하드웨어 조직

  • 버스 (BUS): 시스템 내를 관통하는 전기적 배선군.

  • 워드 (Word): 버스에서 전송되는 데이터의 단위 (바이트, 고정 단위).

  • 입출력 장치 (Input/Output Devices): 시스템 ↔ 외부세계. (ex. 키보드, 마우스, 디스플레이(모니터), 디스크 드라이브 등.)
    입출력 버스 / 컨트롤러 / 어댑터를 통해 연결.

  • 메인 메모리(Main Memory): 프로세서가 프로그램을 실행하는 동안 데이터와 프로그램을 모두 저장하는 임시 저장장치.

    • 물리적으로는 DRAM으로 구성
    • 논리적으로는 연속적인 바이트의 배열. (각 데이터는 고유한 주소를 가짐)
  • 프로세서(CPU, 주처리장치): 메인 메모리에 저장된 인스트럭션들을 해독(실행)하는 엔진.
    • 프로그램 카운터(PC): 메인 메모리의 기계어 인스트럭션 순서를 지칭하는 역할. / 프로세스들이 특정한 순서대로 실행될 수 있도록. (물리적으로는 워드 크기의 저장장치)
    • 레지스터 파일(Register File)레지스터(Register)에 값을 가져와 수식/논리 처리기(ALU) 에서 실제 수식을 처리하고, 새 데이터를 다시 레지스터에 저장하는 식으로 각종 연산들을 수행.
    • CPU 작업의 예시
      1. 적재(LOAD): 메인 메모리 → (데이터) → 레지스터
      2. 저장(STORE): 레지스터 → (데이터) → 메인 메모리
      3. 작업(OPERATION): 두 레지스터의 값 → ALU에서 두 개의 워드로 수식연산 → 결과를 레지스터에 덮어쓰기
      4. 점프(JUMP): 인스트럭션에서 한 개 워드를 추출하고, 프로그램 카운터(PC)에 덮어쓰기.
  • 점프(JUMP) 동작에 대해 추가 설명: 예를 들어, 우리가 프로그램 내에서 반복문을 사용한다고 하면, 프로그램이 위에서부터 아래로 절차적으로 수행되다가 다시 윗 줄이 수행되어야 할 수 있다. 이럴 떄 프로그램 카운터가 다시 위 쪽 명령을 지칭해야하는데, 이를 점프 동작을 통해 수행한다.

1.4.2 hello 프로그램의 실행

1: 사용자가 linux 쉘에 "./hello' 입력

linux> ./hello

2 ~ 5: 쉘 프로그램은 각각의 문자를 레지스터에 읽어들여 메인 메모리에 저장.

→ Enter 키를 누르면 쉘은 명령 입력이 끝난다는 것을 인식하고, hello가 실행 파일의 이름임을 인식 → 실행 파일 hello를 디스크에서 가져오려 함.

1~3. 디스크에서 메인 메모리로 실행 파일 hello를 가져옴.
위처럼 데이터를 디스크에서 메인 메모리로 바로 가져오는 기법을 '직접 메모리 접근(DMA)'라고 한다.


1. hello 코드의 데이터가 메모리에 적재

2~3. 프로세서가 hello 프로그램의 main 루틴의 기계어 인스트럭션들 ("hello, wordl\n" 스트링을 메인 메모리에서 레지스터 파일로 복사하는 작업)을 실행

4~5. "hell, world\n" 스트링을 디스플레이 화면에 전송


참고 자료 / 이미지 출처 ::

이미지 참고

https://velog.io/@emplam27/CS-컴퓨터-시스템-1장-정리

https://velog.io/@binsu/CS-컴퓨터-시스템-하드웨어-구조

https://blog.naver.com/bonamy/223089433787?viewType=pc

profile
능동적으로 사고하고, 성장하기 위한. 🌱

0개의 댓글

관련 채용 정보