- 정수로 해석:
예를 들어 0x7F라는 바이트 시퀀스는 정수로 해석될 때 127이라는 값이 될 수 있습니다. - 부동 소수점 숫자로 해석:
같은 바이트 시퀀스인 0x7F가 부동 소수점으로 해석될 때는 다른 값을 가질 수 있습니다. - 문자열로 해석:
바이트 시퀀스 0x7F는 삭제(DEL, Delete)문자에 해당합니다. 즉, 해당 시퀀스는 화면에 보이지 않는 특수한 제어 문자로 나타내게 됩니다. - 명령어로 해석:
같은 바이트 시퀀스가 CPU 아키텍처의 머신 코드 명령어로 해석될 수도 있습니다.
예를 들어, x86 아키텍처에서 0x7F는 특정한 명령어를 나타낼 수 있습니다.
x86 아키텍처에서 0x7F는 JG (Jump if Greater) 명령어로 해석됩니다. 이 명령어는 조건부 점프 명령으로, 이전의 비교 결과가 "크다"면 지정된 메모리 주소로 점프합니다.
서론
컴퓨터 시스템은 애플리케이션 프로그램을 실행하기 위해 함께 작동하는 하드웨어와 시스템 소프트웨어로 구성됩니다.
시스템의 구체적인 구현은 시간이 지남에 따라 변화하지만, 그 기본적인 개념은 변하지 않습니다.
모든 컴퓨터 시스템은 비슷한 기능을 수행하는 유사한 하드웨어와 소프트웨어 구성 요소를 가지고 있습니다.
이 책은 이 구성 요소들이 어떻게 작동하는지, 그리고 그것들이 프로그램의 정확성과 성능에 어떻게 영향을 미치는지 이해함으로써 자신의 프로그래밍 기술을 향상시키고자 하는 프로그래머들을 위해 쓰였습니다.
저는 현재 이 책을 정리하고자, 저의 정리 내용과, 해당 책의 내용들을 공유하기 위해서, 이 글을 적습니다.
그럼 Section 1.1 부터 차근차근 보도록 하겠습니다.
1. A Tour of Computer Systems
1.1 Information Is Bits + Context
Section 1.1 정보는 비트와 문맥이다
우리의 hello 프로그램은 프로그래머가 편집기를 사용하여 소스 프로그램(또는 소스 파일)으로 작성하고, 이를 hello.c라는 텍스트 파일로 저장함으로써 시작됩니다.

소스 프로그램은 0 또는 1의 값을 가진 비트들이 8비트 덩어리로 조직되어 있으며, 이 덩어리들을 바이트(bytes)라고 부릅니다.
각 바이트는 프로그램 내의 어떤 텍스트 문자를 나타냅니다.
대부분의 컴퓨터 시스템은 ASCII 표준을 사용하여 각 문자를 고유한 바이트 크기의 정수 값으로 표현합니다.
예를 들어, 그림 1.2는 hello.c 프로그램의 ASCII 표현을 보여줍니다.

hello.c 프로그램은 바이트의 연속으로써 파일에 저장됩니다.
각 바이트는 어떤 문자에 해당하는 정수 값을 가집니다.
예를 들어, 첫 번째 바이트는 정수 값 35를 가진다면, 이는 문자 ‘#’에 해당합니다.
두 번째 바이트는 정수 값 105를 가진다면, 이는 문자 ‘i’에 해당하고, 그 후에도 계속해서 문자가 정수 값으로 변환되어 저장됩니다.
각 텍스트 라인은 보이지 않는 개행 문자 ‘\n’로 끝나며, 이는 정수 값 10으로 표현됩니다.
hello.c와 같이 ASCII 문자로만 구성된 파일은 텍스트 파일로 알려져 있습니다.
그 외의 파일들은 이진 파일로 알려져 있습니다.
hello.c의 표현은 기본적인 아이디어를 보여줍니다:
- 시스템 내의 모든 정보는 디스크 파일, 메모리에 저장된 프로그램, 메모리에 저장된 사용자 데이터, 네트워크를 통해 전송되는 데이터를 포함하여 모두 비트들의 집합으로 표현된다.
서로 다른 데이터 객체들을 구분짓는 유일한 것은 우리가 그것들을 어떤 문맥(context)에서 보는가입니다.
예를 들어, 같은 바이트 시퀀스라도 다른 문맥에서 보면 정수, 부동 소수점 숫자, 문자열, 또는 머신 명령어로 해석될 수 있습니다.
문맥의 예시
프로그래머로서, 우리는 숫자의 기계적 표현을 이해해야 합니다. 왜냐하면 그것들은 정수와 실수가 서로 동일하지 않기 때문입니다.
기계적 표현은 유한한 근사값이며, 이들은 예상치 못한 방식으로 동작할 수 있습니다.
이 기본적인 아이디어는 2장에서 자세히 다뤄집니다.
부록
Origins of the C programming language
[ C 프로그래밍 언어의 기원 ]
C는 1970년대 초반, 벨 연구소(Bell Laboratories)의 Dennis Ritchie에 의해 1969년부터 1973년까지 개발되었습니다.
미국 국가 표준 협회(ANSI)는 1989년에 ANSI C 표준을 제정하였고, 이후 이 표준화 작업은 국제 표준화 기구(ISO)의 책임 하에 이루어졌습니다.
이 표준들은 C 언어와 C 표준 라이브러리로 알려진 라이브러리 함수 세트를 정의합니다.Kernighan과 Ritchie는 그들의 고전적인 책에서 ANSI C를 설명하고 있으며, 이 책은 애정 어린 이름인 ‘K&R’으로 잘 알려져 있습니다.
Ritchie는 C를 ‘기묘하고 결점이 있지만, 엄청난 성공을 거둔 언어’라고 말합니다. 그렇다면 왜 이렇게 성공했을까요?
- C는 유닉스 운영 체제와 밀접하게 연관되어 있습니다. C는 처음부터 유닉스를 위한 시스템 프로그래밍 언어로 개발되었습니다.
- 유닉스 커널(운영 체제의 핵심 부분)과 모든 지원 도구 및 라이브러리는 C로 작성되었습니다.
- 1970년대 후반과 1980년대 초반, 유닉스가 대학에서 인기를 끌면서 많은 사람들이 C를 접하게 되었고, 그들은 C 언어를 좋아하게 되었습니다.
- 유닉스가 거의 전적으로 C로 작성되었기 때문에, 새로운 하드웨어로 쉽게 이식될 수 있었고, 이로 인해 C와 유닉스는 더 많은 사용자층을 확보하게 되었습니다.
- C는 작고 단순한 언어입니다. 언어 설계는 위원회가 아니라 한 사람에 의해 주도되었기 때문에, 깔끔하고 일관된 설계가 이루어졌으며, 불필요한 요소는 거의 없었습니다.
- K&R 책은 261페이지에 전체 언어와 표준 라이브러리를 설명하며, 다양한 예제와 연습 문제를 제공합니다.
- C의 단순함 덕분에 배우기 쉽고, 다양한 컴퓨터 시스템에 이식하는 것도 상대적으로 간단했습니다.
- C는 실용적인 목적을 위해 설계되었습니다. 특히 유닉스 운영 체제를 구현하기 위해 개발되었습니다.
- 이후 다른 사람들은 C 언어가 그들이 원하는 프로그램을 작성하는 데 방해가 되지 않는다는 것을 발견했습니다.
C는 시스템 수준 프로그래밍에서 선택되는 언어이며, 애플리케이션 수준 프로그램에서도 엄청난 사용자 기반을 가지고 있습니다. 하지만 모든 프로그래머와 모든 상황에 완벽하지는 않습니다. C 포인터는 혼란과 프로그래밍 오류의 일반적인 원인이 됩니다. C는 또한 클래스, 객체, 그리고 예외 처리와 같은 유용한 추상화에 대한 명시적인 지원이 부족합니다. C++와 Java와 같은 새로운 언어들은 애플리케이션 수준 프로그램에서 이러한 문제들을 해결합니다.
정리
시스템 내의 모든 정보는 비트로 표현됩니다. 이 비트들은 텍스트 파일, 프로그램, 메모리 데이터, 네트워크 데이터 등 다양한 형태로 저장됩니다. 중요한 점은, 같은 바이트 시퀀스라도 문맥에 따라 그 의미가 달라질 수 있다는 것입니다. 예를 들어, 같은 바이트가 정수, 부동 소수점 숫자, 문자열, 또는 머신 명령어로 해석될 수 있습니다.
프로그래머는 숫자의 기계적 표현을 이해해야 합니다. 왜냐하면 숫자는 실제 정수나 실수와 동일하지 않기 때문에, 컴퓨터에서 숫자는 유한한 근사값으로 처리되고 예상치 못한 방식으로 동작할 수 있기 때문입니다. 이 내용은 2장에서 더 자세히 설명됩니다.