개인적으로 이해한 내용.
해당 책의 목적은
프로그램의 정확성, 성능, 유용성에 영향을 주는 개념을 숙지하기 위해, 파워 프로그래머를 염두에 두고 작성했다.
1장은 컴퓨터 일생 주기를 추적하며,
컴퓨터 시스템의 주요 아이디어 및 주제를 제시한다.
C언어 기준으로 얘기한다.
단순히 요약하고 옮겨 적는게 아닌, 총체적 통합과 이해를 목표로한다.
순서는 이렇다.
일반적으로 우리가 작성하는 파일, 소스 코드가 무엇으로 이루어져있는지 설명한다.
그리고 그러한 소스코드가 어떻게 컴퓨터가 이해할수 있는 언어로 번역되는지 과정을 나열한다.
대체 왜 우리가 번역하는 과정까지 이해할 필요가 있는지 제시한 후,
컴퓨터에서 전체적으로 경로가 어떻게 이어지는지 각각의 컴퓨터 작동 장치를 설명하고 작동 경로를 설명한다.
우리가 hello World를 출력해달라고 한다.
입력한 코드가 적힌 파일은
소스 파일이라고 한다.
소스 코드 파일의 확장자는 대개 텍스트 파일이다.
8비트, 즉 1바이트의 단위로 구성되어있다.
1바이트당 하나의 문자를 넣을 수 있는데,
문자마다 대응하는 아스키 코드 (ASCII)가 있다.
아스키 코드 문자로만 이루어진 걸 텍스트 파일,
그 외의 코드도 있다면 바이너리 파일이라고 한다.
같은 숫자여도, context에 따라 다르게 해석할 수 있다.
? context : 런타임 시 생성되는 정보. 하고자하는 의도나 목적에 따른 맥락.
? instruction : 컴퓨터가 알아듣는 기계어 명렁 단위.
? 기계어 : CPU가 직접 해독, 실행 가능한 비트 단위의 단어.
? 실행가능 : CPU이외 시스템 자원이 모두 할당된 실행 단위가 CPU의 사용권이 주어지는 것을 기다리고 있는 상태.
소스 코드는 instruction들로 이루어져, 번역 과정을 거쳐 기계어가 된다.
이 소스 코드를 실행가능 목적 프로그램(dispatchable...)이라고 한다.
번역을 거치면 바이너리 형식의 디스크 파일이 된다.
이 과정을 C언어에서는 이런 명령어를 쓴다.
gcc -o hello hello.c
컴파일 시스템을 거치는 것이다.
컴파일의 과정은 이렇다.
소스코드(hello.c)-전처리기(Pre-processor,cpp)->hello.i(텍스트 형식)-컴파일러(Compiler, cll)->hello.s(텍스트)-어셈블러(Assembler,as)->hello.o(바이너리)-링커(Linker, ld)-> hello
전처리기
가장 상위의 #으로 호출된 것에 따라 헤더 파일을 삽입.
컴파일러
어셈블리어로 전환할 수 있도록 프로그램을 포함. 기계가 일치하다면, 상위 언어여도 여기서 형태가 일치할 수도 있음.
어셈블러
기계어 단위로 변환.
재배치 가능 목적 프로그램(relocatbale..)로 만든다.
? 재배치 가능 : 기억 장소 내 임의의 어떤 부분이든 자리 잡을 수 있음. 단, 절대 주소를 배정하면 안 됨.
링커
printf등 표준 라이브러리에 있는 코드들과 통합.
실행 가능 파일로 만든다.
이해하는 이유는 두가지.
1. 성능 최적화.
2. 링크 에러 이해.
3. 보안 약점 피하기.
? 버퍼 오버플로우(buffer overflow) : 메모리 이상의 데이터 입력으로, return address를 조작하여 자신이 원하는 프로그램을 실행하도록 유도.
? return address : 원래의 프로그램으로 돌아갈 주소.
여러가지 의제가 나왔으나, 모르는 단어나 주제가 많아서 생략.
shell에 명령어를 입력할 때,
shell이 알고 있는 명령어는 그걸로, 모르는 건 실행파일로 간주하고 실행한다.
버스(buses)
전기적 배선군. 바이트 정보 전송.
단위 word(워드 라고 칭하는데 맞는지 모르겠네.)
시스템마다 변수 결정됨.
ex) 4byte(32bit), 8byte(64bit)
입출력 장치
마우스, 키보드, 디스플레이, 디스크(Disk) 등.
컨트롤러나 어댑터로 이어짐.
컨트롤러와 어댑터의 차이는 packaging.
컨트롤러는 칩셋이나 motherboard(주회로기판) 자체로 이루어진 반면, 어댑터는 주회로 기판 슬롯에 장착하는 형식.
메인 메모리(main Memory)
데이터와 프로그램을 실행 중에 모두 저장해두는 임시 저장장치.
DRAM(Dynamic Random Access Memory)로 구성.
고유주소, 즉 index를 가지고 저장해둠.
프로세서 (Processor)
대표적으로 CPU(주기억장치, Central processing Unit).
내부에 PC(program counter, 보편적인 PC의 Personal computer와는 다르다.)를 가지고 있음. 레지스터(register)중 하나.
? 레지스터 : 메인 메모리에 비해 접근이 쉬운 프로세서 내 저장장치.
메인 메모리의 기계어 instruction을 저장해둠.
CPU는 PC가 가리키는 포인터를 중심으로 메인 메모리에 있는 걸 실행, 실행하고 나면 다음으로 포인터를 이동, 그리고 실행하는 것을 반복하는 것으로 돌아감.
main에서 PC로 불러오는 것을 Load, 그 반대는 store, PC에서 처리장치인 ALU에서 실행하는 것을 operate라고 함.
명령 읽기
명령어를 입력 장치로 입력,
즉 쉘에 입력했을 떄 엔터 친 시점.
키보드 -> 입출력 중간 장치 -> CPU -> 메인 메모리
실행파일을 디스크에서 메인 메모리로 로딩
디스크 -> 메인 메모리
출력을 메모리에서 화면으로 기록
메인 메모리 -> CPU -> 디스플레이