컴퓨터 시스템 : 하드웨어 + 시스템 소프트웨어
: 어떤 언어로 쓰인 프로그램을 다른 언어의 동등한 프로그램으로 번역하는 것
hello.c 파일을 기준으로 설명하려 한다.#include <stdio.h>
int main() {
printf("hello, world!\n");
return 0;
}
.c 소스 텍스트 → 전처리된 소스 텍스트(.i)#으로 시작하는 지시자만 처리#include <...>의 경우 해당 헤더 파일의 내용을 그 자리에 통째로 복사 붙여넣기 한다.gcc -E hello.c -o hello.i

main 함수 위로 헤더 파일의 내용이 들어온 것을 확인할 수 있다.
.i) → 어셈블리 텍스트(.s)int에 포인터를 대입하면 경고가 나오는 단계이다.3*4를 컴파일 시점에 12로), 루프 최적화 등gcc -S hello.i -o hello.s

어셈블리 텍스트로 변경된 것을 확인할 수 있다.
.s) → 오브젝트 파일(.o)gcc -c hello.s -o hello.o

어셈블리가 기계어 바이트로 바뀐 것을 확인할 수 있다.
.o) + 라이브러리 → 실행 파일gcc hello.o -o hello
모든 컴파일 과정이 이러한 것은 아니다. 어셈블리로 작성한 코드는 고급 언어를 어셈블리로 변환하는 컴파일까지의 단계는 필요하지 않을 것이고, 기계어로 직접 실행 파일을 작성하는 것도 가능하다. 또한 고급 언어라 하더라도 Go, Rust, Java 등에는 독립된 전처리 단계가 없고, Java의 JIT 컴파일과 같이 컴파일 과정이 다른 경우도 있다.
컴퓨터의 하드웨어와 소프트웨어 간의 인터페이스를 정의하는 개념
기계어를 작성하기 위해 필요한 모든 정보를 말하며, 단순히 명령어(instruction)의 집합뿐만 아니라 레지스터, 메모리 모델, 주소 지정 방식(addressing mode) 등을 포함한 모든 정보를 의미한다.
하나의 표준이 존재하는 게 아니라 각 회사가 목표로 하는 설계 철학, 성능 요구 사항, 전력 소비, 응용 분야 등에 따라 다양하게 존재한다.
우선 메모리 구조에 대해 이미지로 간략히 확인하고 가겠다.

: 작업의 단위로 실행 중인 프로그램
각 프로세스는 자신만의 가상 주소 공간(페이지 테이블), [코드, 전역 변수, 힙, 스택] 영역, 열린 파일 디스크립터 테이블, 시그널 핸들러, 현재 작업 디렉터리 등을 갖는다.
: 실행 흐름의 단위로, 같은 프로세스의 스레드들은 자원을 공유
각 스레드는 각자 실행을 하기 위해 레지스터 상태, 스택 영역, 스케줄링 상태, errno, TLS 등을 갖는다.
errno, TLS 등 익숙하지 않은 개념들에 대해서는 이어지는 챕터들에서 학습할 수 있을 것으로 기대한다.
복잡한 시스템에서 본질적인 부분만 남기고 세부 사항을 감추는 것
필자가 학습할 때는 세탁기 비유로 학습했는데, 이미지는 찾지 못했지만 적절한 비유라고 생각이 돼서 설명해보겠다.
세탁기를 사용할 때 세탁물을 넣고 버튼만 누르면 세탁이 되고, 작업이 끝나면 세탁물을 돌려받는다. 이때 내부에서 사람이 들어가서 빨래를 하는지, 어떤 식으로 작동하는지는 우리가 알 필요가 없다.
이러한 개념을 사용하는 API, 함수, 네트워크 계층 구조 등 모두 추상화라고 할 수 있고, 앞서 설명한 명령어 집합 구조에서 해당 명세만 따르면 하드웨어와 소프트웨어가 서로에 대해 이해하지 않아도 되는 것 역시 추상화라고 볼 수 있다.
부족한 내용이나 잘못된 정보가 있다면 jeong.jinyeong95@gmail.com으로 연락 바랍니다.