[CS:APP] 컴파일 시스템

Laska·2025년 3월 14일
post-thumbnail

컴퓨터 시스템으로의 여행


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


#include <stdio.h>

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

hello 프로그램은 프로그래머가 에디터로 작성한 소스 프로그램(또는 소스파일)으로 생명을 시작하며, hello.c라는 텍스트 파일로 저장됨.

소스 프로그램이란?

  • 0 또는 1로 표시되는 비트들의 연속이며, 바이트(8bit = 1byte) 단위로 구성됨.
  • 각 바이트는 프로그램의 텍스트 문자를 나타냄.
  • 대부분의 컴퓨터 시스템은 아스키(ASCII) 표준을 사용하여 텍스트 문자를 표시함.

아스키(ASCII) 표준이란?

  • 각 문자를 바이트 길이의 정수 값으로 나타내는 표준.
  • 예를 들어 #include <stdio.h>에서 첫 번째 바이트 35는 # 문자에 대응, 두 번째 바이트 105는 i 문자에 대응됨.
  • 각 텍스트 라인의 끝에는 개행문자(\n) 등이 포함되어 있음.

텍스트 파일 vs 바이너리 파일

  • hello.c와 같이 아스키 문자로 이루어진 파일 → 텍스트 파일
  • 실행파일, 이미지, 동영상 등 바이너리 데이터로 저장 → 바이너리 파일

💡 프로그램들이 서로 다른 객체를 구분하는 방법?

👉 컨텍스트(Context) 를 통해 구분함!

컨텍스트(Context)란?

바이트들의 의미를 결정하는 환경

  • 같은 데이터를 바라보는 방식(환경)에 따라 해석이 달라짐

예제 1: 숫자 1234의 다양한 해석

컨텍스트해석 방식결과
정수(int)그냥 숫자로 보기1234
문자열(str)문자로 보기"1234"
16진수(hex)다른 진법으로 보기0x4D2
네트워크 데이터전송 데이터로 보기다르게 저장됨
메모리 명령어CPU가 실행할 코드로 보기특정 연산 수행

예제 2: 메모리 속 데이터 해석

메모리에 저장된 바이트를 다르게 해석할 수 있음.

01000001 (A)  01000010 (B)  01000011 (C)  01000100 (D)
컨텍스트해석 결과
문자(char)"ABCD"
정수(int)1094861636
명령어(CPU instruction)특정 연산 수행

📌 결론

  • 컨텍스트(Context)는 데이터를 해석하는 방식(환경)이다!
  • 같은 데이터라도 컨텍스트에 따라 다르게 해석될 수 있다!
  • 정확한 컨텍스트를 이해하지 못하면, 데이터가 엉뚱하게 해석될 수 있다!

1.2 프로그램은 다른 프로그램에 의해 다른 형태로 변형된다

hello 프로그램은 인간이 이해할 수 있는 고급언어로 작성됨.

💡 컴퓨터는 인간의 언어(고급언어)를 이해하지 못함!

👉 따라서 컴퓨터가 이해할 수 있는 "기계어(0과 1)"로 번역해야 함

인스트럭션(Instruction)이란?

CPU(중앙처리장치)가 수행하는 명령어

이 명령어들이 모여 CPU가 수행할 작업을 결정!
실행가능 목적 프로그램 형태로 합쳐져서 바이너리 디스크 파일로 저장됨!

컴파일 과정 (소스파일 → 실행파일 변환)

linux> gcc -o hello hello.c

📌 gcc 컴파일러 드라이버는 소스파일 hello.c를 실행파일 hello로 변환하며, 4단계를 거쳐 실행됨.

컴파일 시스템

1. 전처리 단계 (Preprocessing) - cpp

  • #include 같은 디렉티브를 처리하여 코드 변형.
  • 결과물: hello.i (수정된 C 코드)

2. 컴파일 단계 (Compilation) - cc1

  • C 코드 → 어셈블리어 변환
  • 결과물: hello.s (어셈블리 코드)
main:
    subq    $8, %rsp
    movl    $.LCO, %edi
    call    puts
    movl    $0, %eax
    addq    $8, %rsp
    ret

3. 어셈블 단계 (Assembly) - as

  • 어셈블리어 → 기계어 변환
  • 결과물: hello.o (목적 파일, 실행 불가)

4. 링크 단계 (Linking) - ld

  • 표준 라이브러리와 연결 (ex: printf.o + hello.o)
  • 결과물: hello (실행 파일)

📌 최종 요약

단계역할결과물
전처리 (cpp)#include 처리, 코드 변형hello.i
컴파일 (cc1)C 코드 → 어셈블리어 변환hello.s
어셈블 (as)어셈블리어 → 기계어 변환hello.o
링크 (ld)목적파일 + 라이브러리 연결hello (실행파일)

🚀 즉, gcc hello.c는 위 과정을 거쳐 "소스 코드 → 실행 파일"로 변환하는 과정임!

profile
똑똑해지고 싶어요

0개의 댓글