컴퓨터 구조에 대한 첫 번째 이야기
시스템 프로그래밍의 이해와 접근
시스템 프로그래밍 이란?
컴퓨터 시스템을 동작시키는 프로그램 즉, 컴퓨터를 동작시키기 위해 필요한 프로그램을 말한다.
어셈블리 언어나 C언어를 이용하여 하드웨어를 직접 컨트롤하는 개발자들을 가리켜 시스템 프로그래머라 부른다. 그러나 Windows 나 UNIX 같은 운영체제에서 제공하는 라이브러리를 사용하여 프로그램을 개발하는 개발자들도 시스템 프로그래머라 부를 수 있다.
보통 컴퓨터 시스템이라고하면 하드웨어만을 뜻하는 것이 아니다. 하드웨어가 실제 일을 하게끔 도와주는 운영체제를 포함하는 것이 보통이다.
컴퓨터 시스템의 주요 구성요소
컴퓨터 구조와 운영체제를 이해하게 되면, 시스템 프로그래밍만 가능하게 되는 것이 아니다. 언어의 문법적 요소만을 이해하고 바로 프로그래밍하는 프로그래머들보다 효율적인 프로그램을 구현하는 것이 가능해진다.
컴퓨터 하드웨어의 구성
CPU(Central Processing Unit)
우리가 흔히 말하는 "중앙처리장치"가 바로 CPU 이다. 기본적으로 CPU가 연산을 담당한다.
CPU는 컴퓨터 프로그램의 실행에 있어서 핵심적인 역할을 담당한다.
메인 메모리(Main Memory)
램(RAM) 이라는 저장장치로 구성되는 메인 메모리는 컴파일이 완료된 프로그램 코드가 올라가서 실행되는 영역이라고 정의할 수 있다.
예를 들어 아주 재미있는 게임 하나를 인터넷을 통해 내려받았다고 가정해 보자. 이 게임은 당연히 하드디스크에 저장된다. 이 게임을 실행하기 위해서 Window 탐색기를 띄운 다움, 저장된 디렉터리로 찾아 들어가서 더블클릭을 한다. 그러면 해당 프로그램은 메인 메모리로 올라가서 실행된다. 즉, 메인 메모리는 프로그램 실행을 위해 존재하는 메모리라고 생각하면 된다.
입,출력 버스(Input/Output Bus)
입.출력 버스는 컴퓨터를 구성하는 구성요소 사이에서 데이터를 주고 받기 위해 사용되는 경로이다. 주고 받는 데이터의 종류와 역할에 따라서 어드레스 버스(Address Bus) , 데이터 버스(Data Bus) , 컨트롤 버스(Control Bus) 이렇게 세 가지로 구분이 된다.
하드디스크, 메인 메모리 ,CPU 등등이 모두 버스에 연결되어 있다. 때문에 이러한 버스 시스템을 기반으로 하드디스크에 있는 데이터를 메인 메모리로, 메인 메모리에 있는 데이터를 하드디스크로 전송하는 것이 가능하고, 메인 메모리와 CPU 사이에서의 데이터 입.출력도 가능하다.
흐름
- 하드 디스크에 프로그램을 저장
- 해당 프로그램을 실행하면 운영 체제는 프로그램을 메인 메모리(RAM)로 로드한다.
- CPU는 메인 메모리에 올라간 프로세스의 명령어 및 데이터에 접근하기 위해 버스를 사용한다.
- CPU의 버스 인터페이스가 CPU와 메인 메모리 간에 데이터를 주고받는다. 이때, CPU는 메인 메모리로부터 명령어 및 데이터를 가져와서 실행한다.
- 입,출력 버스는 복잡한 원리에 의해서 구성되어 있다. 버스에는 버스가 어떻게 데이터를 주고 받는지 나름대로의 통신 규약이란게 있다 그 규약에 따라 데이터를 주고 받기 때문에 그 규약을 이해하고 그 규약에 맞춰서 데이터를 주고 받을 수 있는 장치가 필요하다 그것이 바로 버스 인터페이스이다. 즉 CPU 내부적으로는 입.출력 버스가 데이터를 어떻게 주고 받는지 그 방법을 이해하고 있는 장치가 필요한데 CPU에서는 그 장치가 버스 인터페이스이다.
- 입출력 버스에 맞물러 있는 모든 장치들에는 버스 인터페이스 장치가 존재한다.
- CPU는 버스 인터페이스를 통해 메인 메모리로부터 가져온 명령어와 데이터를 레지스터에 저장합니다.
- 버스 인터페이스로 온 명령어와 데이터를 바로 ALU나 컨트롤 유닛으로 보낼 수 없다.
- ALU는 연산 중이고 컨트롤 유닛은 앞서 들어온 명령어를 해석하고 있는 상황인데 바로 보내면 문제가 발생할 수 있다.
- 그래서 ALU나 컨트롤 유닛이 필요할때 데이터를 가져갈 수 있도록 구성하기 위해 CPU 내부에도 작은 저장장치가 등장했고 이 장치가 바로 레지스터다.
- 레지스터에 저장되어 있는 명령어가 컨트롤 유닛으로 이동하고 컨트롤 유닛이 명령어를 해석한다. 이 과정에서 ALU(산술논리 장치)로 신호(덧셈해라, 뺄셈해라 등)를 보내고 연산할 데이터까지 ALU로 이동하게끔 컨트롤 유닛이 제어한다.
- ALU는 데이터(피연산자)를 받아 적절한 연산을 수행하고, 결과를 다시 레지스터에 저장한다.
클럭 신호
컴퓨터의 모든 장치에는 클럭 신호라는게 들어가 있다. 1초에 클록 신호가 한번 발생했으면 이를 1Hz라고 한다.
시스템에는 클럭 발생기라는게 달려있다. 이 클럭 발생기가 일정한 간격으로 모든 장치에 신호를 준다. 그러면 모든 장치들은 그 신호에 맞춰서 연산을 한다. 즉 하드웨어의 동작 타이밍을 결정하는것이 클럭 신호다.
클럭을 높이면 그만큼 시스템 성능이 높아진다. 하지만 높일수록 그만큼 열이 발생하고 열이 발생하수록 시스템이 불안해진다. 그렇기 때문에 클럭을 높이는데에는 시스템이 불안해기전까지 높일 수 있는 제한이 있다.
동작 타이밍
- 클럭 발생기의 클럭
필요성
- 요소들의 동기화
위 이미지를 통해 예시를 살펴보자.
- 연산장치에는 2와3이 입력된다고 가정하자. 연산장치는 덧셈 결과를 버퍼(메모리)에 저장한다. 출력 장치는 그거를 가져다가 출력한다.
- 연산장치는 초당 10번 작업하고 출력 장치는 초당 5번 작업한다고 가정하자.
- 이때 발생하는 문제는 출력장치가 데이터를 가져가기도 전에 연산장치가 데이터를 버퍼에 저장해서 기존에 저장된 데이터를 덮어쓰는 문제가 발생할 수 있다
- 이것이 바로 클럭이 필요한 이유다. 즉 연산장치와 버퍼, 출력 장치에 동일한 클럭 신호를 줘서 문제를 해결할 수 있다. 요소요소들 마다 클럭을 발생시켜서 일을 하는게 아니라 중앙에서 클럭 신호를 일률적으로 전송을 하고 그 클럭에 맞춰서 모든 요소들이 일을 하게끔 시스템을 디자인하자 라는 것이다.
- 연산장치는 초당 10번 출력 장치는 초당 5번 클럭신호를 발생했을때 무리가 없다고 하면 중앙에서는 클럭 신호를 몇번 발생시키는게 좋냐면 5번을 발생시키는게 좋다. 초당 5번에 10번을 주면 부하가 오기때문이다. 즉 보통 시스템 요소요소에서 요구하는 가장 낮은 클럭을 기준으로 클럭신호를 제공한다. 이렇게 해서 시스템을 안정적으로 간다.
명령어
명령어는 CPU 디자인에 있어서 상당히 중요한 의미를 지닌다.
0011은 CPU가 덧셈으로 인식하겠다고 디자인 해보자 뺄셈 곱셈 등 다른 명령어들도 덧셈과 같이 디자인한다. 그럼이제 0011이 CPU에 들어가면 컨트롤 유닛에 의해서 덧셈으로 인식이 된다. 하지만 0011과 같이 이런 숫자를 조합해서 프로그램을 개발하기에는 어렵다
그래서 사람들이 쉽게 인식하기 위해 0011은 ADD로 0010은 MIN으로 이렇게 문자를 붙여준다. 이러한 명령어들을 가지고 컴퓨터 프로그래밍을 하는것을 어셈블리 프로그래밍이라 한다. 그래서 저런 어셈블리 언어를 컴퓨터가 이해하도록 이진수 코드로 바꾸는게 어셈블러이다.
전처리기에 의한 치환 작업 후 컴파일러는 프로그래밍 언어(C, C++ 등)를 어셈블리 언어로 바꿔주는게 컴파일러다.
링커는 프로그램 내에서 참조하는 함수나 라이브러리들을 하나로 묶는 작업을 말한다. 이 과정이 끝나면 실제로 실행 가능한 실행파일이 생성된다. 물론 이 실행파일은 컴퓨터가 실행해야 하는 바이너리 코드로 구성된다.
어셈블러를 통해 만들어진 바이너리와 라이브러리가 묶여서 실행파일이 만들어지고 이런 실행파일을 만드는게 링커다.
실행파일이 메모리 공간에 올라가고 난 다음 CPU에 의해서 실행되기 시작한다. 메모리 공간에 올라가는 명령어들은 CPU에 의해서 순차적으로 실행된다. 위 그림에서 보면 메모리상에 명령어 A , 명령어 B , 그리고 명령어 C가 올라가 있다. 이 명령어들은 CPU에 의해서 순차적으로 실행되는 데, 메모리상에서 실행되는 것이 아니라 CPU 내부로 하나씩 이동한 다음 실행하게 된다.
- 단계 1. Fetch : 메모리 상에 존재하는 명령어를 CPU로 가져오는 작업 위 그림에서 보면 메모리 상에 존재하는 명령어 A를 CPU로 이동시키고 있다. 읽어온 명령어는 CPU의 명령어 레지스터(Instruction Register, IR)에 저장된다.
- 단계 2. Decode: 명령어 레지스터에 가져다 놓은 명령어를 CPU가 해석하는 단계이다. 다시 말해 무슨 일을 하는 명령어인지 분석하는 단계이다.
- 단계 3. Execution : 해석된 명령어의 명령대로 CPU가 실행하는 단계이다.
결국, 프로그램의 기본 실행은 Fetch , Decode , Execution 단계를 거친다고 말할 수 있다.
Stored Program Concept(폰 노이만 아키텍처)
프로그램이라는 것은 메모리에 저장이 되어야 한다는 소리다. 프로그램이 메모리에 저장이 되어야 한다는 그런 컨셉으로 컴퓨터 구조가 디자인 되어야한다는 개념이다(폰 노이만이 얘기함)
명령어는 메모리에 저장이 되어서 CPU에 의해 1. Fetch 되고 2. Decode 되고 3. Execution 되어야 한다.
- Fetch
- 명령어는 메모리에 저장되어 있는 상태
- 명령어를 CPU로 하나씩 가져간다
- 버스 인터페이스, I/O 버스를 통해서 CPU 내부로 명령어가 이동
- Decode
- 명령어 해석
- 컨트롤 유닛에 의해 명령어가 해석 된다.
- Execution
- 해석된 결과에 따라서 실행
- 연산이라는 것은 CPU가 하는 궁극적인 일이다.
- 그래서 좀 더 범위가 크지만 ALU에 의해서 연산이 이뤄진다 라고 간결하게 생각해도 좋다
- ALU가 중심이 되어서 요소요소간 협력을 통해 연산이 진행된다.
CPU 내부 장치들을 Stored Program Concept을 기반으로 이해하기
데이터 이동의 기반이 되는 버스 시스템
데이터를 이동하는 데 있어서 사용되는 전송 경로를 버스 시스템 이라 한다.
버스 시스템은 주고 받는 데이터의 종류에 따라서 어드레스 버스(Address Bus) , 데이터 버스(Data Bus) , 컨트롤 버스(Control Bus) 이렇게 세 가지로 구분이 된다.
I/O 버스를 통해서 CPU, 키보드, 하드디스크 등등 컴퓨터 내,외부에 존재하는 주변 장치들이 연결되어 있다.
I/O 버스는 여러 장치들이 데이터를 주고받기 위한 통로의 역할을 한다.
CPU와 메인 메모리도 데이터를 주고 받기 위해 버스로 연결되어 있다.
지금 까지는 메인 메모리에 저장되어 있는 명령어들을 가져오는 연산(Fetch) 에 대해서만 언급했지만, 역으로 CPU의 레지스터에 저장되어 있는 데이터를 메인 메모리에 저장하는 일들도 발생한다. CPU에서 계산된 덧셈 결과를 메인 메뢰에 저장하는 작업 정도를 예로 들 수 있겠다.
- 데이터 버스
- 데이터를 이동하기 위해 필요한 버스이다.
- 어드레스 버스
- 주소값을 이동하기 위해 필요한 버스이다. CPU 입장에서는 몇번째에 있는 데이터를 줘 라는 요청을 보내야 해서 몇번째에 대한 주소값을 보내야 한다.
- 예를들어 CPU가 0x1024 번지에 저장되어 있는 데이터 4바이트를 읽으려고 한다. 그렇다면 메모리 영역에 주소값 0x1024를 먼저 전달해야 한다. (메모리를 단순히 저장만 하는 바보로 생각하지 말고, 주소가 전달되면 해당 주소의 데이터를 전송하는 컨트롤러가 포함되어 있는 것으로 생각하자) 이때 사용되는 것이 어드레스 버스이다. 메모리는 0x1024 번지에 존재하는 4바이트 데이터를 데이터 버스를 통해서 전달받게 된다.
- 컨트롤 버스
- 무조건 데이터를 달라고 요청 하거나 데이터를 전송할 수 있냐? 아니다
- CPU가 메모리로부터 데이터를 가져온다고만 생각하면 버스를 이해하기 어렵다. 버스는 일반적으로 양방향이다. 연산 결과를 메모리에 저장할 수 있다. 즉 데이터는 CPU → 메모리 또는 메모리 → CPU 로 흘러갈 수 있다. 그렇기 때문에 컨트롤이 필요하다.
- 누가 먼저 보낼껀지 즉 일의 순서를 정하기 위해서 컨트롤 버스가 필요하다.
- CPU가 원하는 바를 메모리에 전달할 때 사용된다. 쉽게 말해서 CPU와 메모리가 서로 특별한 신호를 주고받는 용도로 사용되는 버스이다.(컨트롤 버스를 통해서 내가 지금 주소를 보낼꺼야 라는 신호)
무엇 때문에 컨트롤 버스를 이용해서 CPU가 메모리에 사인을 전달해야 하는가? CPU는 메모리로부터 데이터를 가져오기도 하지만, 반대로 메모리에 데이터를 저장하기도 한다.
참고
https://github.com/connieya/system_programming/blob/master/chapter01/01.md
https://www.youtube.com/watch?v=GVX-m3RF-K0&list=PLVsNizTWUw7E2KrfnsyEjTqo-6uKiQoxc
'운영체제 > 뇌를 자극하는 윈도우즈 시스템 프로그래밍' 카테고리의 다른 글
뇌를 자극하는 윈도우즈 시스템 프로그래밍 6장 (0) | 2024.09.05 |
---|---|
뇌를 자극하는 윈도우즈 시스템 프로그래밍 5장 (0) | 2024.05.04 |
뇌를 자극하는 윈도우즈 시스템 프로그래밍 4장 (0) | 2024.05.04 |
뇌를 자극하는 윈도우즈 시스템 프로그래밍 3장 (0) | 2024.05.03 |
뇌를 자극하는 윈도우즈 시스템 프로그래밍 2장 (0) | 2024.05.03 |