bdfgdfg

컴퓨터 구조/ 프로그램의 실행과정 - (2) 본문

카테고리 없음

컴퓨터 구조/ 프로그램의 실행과정 - (2)

marmelo12 2021. 8. 9. 19:01
반응형

프로그램의 실행 과정

어셈블리 -> 어셈블러

● 전처리기에 의한 치환 작업

- #으로 시작하는 지시자

 

● 컴파일러에 의한 번역

- 윗 단계에서 변경된 소스코드는 C/C++ 언어로 구성되어서 우리가 눈으로 봐도 이해할 수 있는 내용 이 소스코드는 컴파일러에 의해서 어셈블리 코드로 번역된다.

 

● 어셈블러에 의한 바이너리 코드 생성

- 컴파일러에 의해 번역된 어셈블리 코드는 컴퓨터에 의해 실행되기에 앞서 바이너리 코드로 번역되어야 한다.

- 왜 굳이 컴파일러 -> 어셈블러 과정을 따로 나눴을까.

- 그것은 CPU를 디자인하는 설계자가 덧셈, 뺄셈 등을 여러 개의 명령어로 구성하는데 

위 그림과 같이. ADD는 0011, MIN은 0010, MUL은 0100등. 바이너리 코드로만 사용한다면 어려울 작업을 위와 같이 정의해놓은 규칙에 의해서 덧셈은 ADD 뺄셈은 MIN로 어셈블리에서 정의해서 사용하자!라고 하는 것.

 

하지만 당연히 아직은 위의 ADD, MIN은 어셈블리 언어이지 아직은 컴퓨터가 바로 이해할 수 있는 단계는 아니다. 그렇기에 어셈블리 코드를 CPU가 이해할 수 있는 바이너리 코드로 바꾸어 주는 프로그램이 필요한데, 이것이 바로 어셈블러

 

● 링커에 의한 연결과 결합

- 라이브러리와의 결합

- 프로그램 내에서 참조하는 함수나 라이브러리들을 하나로 묶는(연결시켜 주는) 작업을 한다.

- 이 과정이 끝나면 실제로 실행 가능한 실행파일이 생성된다.

 

Stored Program Concept

- 프로그램이란 것은 메모리에 저장이 되어야 하는 개념으로 컴퓨터가 설계가 되어야 한다고 말한 폰 노이만.

- 오늘날까지의 컴퓨터에 대한 개념을 만든 사람. 흔히 폰 노이만 아키텍처라고도 한다.

프로그램의 실행 과정에서 마지막 과정인 링커를 통해 실행파일이 만들어지고 나서. 

하드디스크에 저장된 실행파일을 실행하면 메모리에 올라간다.

 

단계 1. Fetch : 메모리상에 존재하는 명령어를 CPU로 가져오는 작업. 위 그림을 보면 명령어 A를 CPU로 이동시키고 있다.

 

단계 2. Decode : 가져다 놓은 명령어를 CPU가 해석하는 단 게. 위 그림에서는 명령어 A가 덧셈을 하라는 의미로 해석되어졌음을 뜻한다.

 

단계 3. Execution : 해석된 명령어의 명령대로 CPU가 실행하는 단계. 위 그림에서도 해석된 덧셈이라는 명령어를 실행..

즉 CPU에 존재하는 ALU를 통해 연산을 진행하는 것.

 

결국 프로그램의 기본 실행은 Fetch, Decode, Execution 단계를 거친다고 말할 수 있다.

 

Stored Program Concept + 컴퓨터 구조

이제 폰 노이만이 제시한 Stored Program Concept를 오늘날의 컴퓨터 구조와 비교해서 설명해보자.

실행된 프로그램이 메모리에 올라가고, 순차적으로 실행이 된다.

 

1. 명령어를 실행하기 위해 제일 먼저 하는 일이 Fetch. 어떠한 경로로 이동? -> 버스 시스템(밑에서 더 자세히 설명)

2. 명령어를 CPU안에 가져다 놓을 때 어디에 저장되는가? -> 레지스터

3. CPU안에 가져다 놓은 명령어는 Decode 단계에서 해석이 되는데 이는 CPU안에 존재하는 누구에 의해서 진행? -> 컨트롤 유닛

4. 마지막 단계인 Executin은 누구에 의해서 진행되는가? -> ALU.

 

이렇게. 폰 노미 안의 컴퓨터 구조와 오늘날의 컴퓨터 구조가 일치한다는 것을 알 수 있다.

 

데이터 이동의 기반이 되는 버스(BUS) 시스템

데이터를 이동하는 데 있어서 사용되는 전송 경로를 가리켜 버스 시스템이라 한다.

 

버스 시스템은 주고받는 데이터의 종류에 따라서 어드레스 버스, 데이터 버스, 컨트롤 버스. 총 3가지 요소로 구성된다.

위 그림을 보면 I/O 버스를 통해서 CPU, 키보드, 모니터, 하드디스크 등등 컴퓨터 내/외부에 존재하는 주변장치들이 연결되어 있음을 알 수 있다. 이렇듯 I/O 버스는 여러 장치(Device)들이 데이터를 주고받기 위한 통로의 역할을 한다.

 

CPU와 메인 메모리를 기준으로 버스 시스템에 대해서 보다 자세히 살펴본다.

 

CPU와 메인 메모리도 데이터를 주고 받기 위해서 버스로 연결되어 있다.

지금까지는 메인 메모리에 저장되어 있는 명령어들을 순차적으로 가져오는 연산(Fetch)만 언급했지만

반대로 CPU 내부에서 연산을 끝마친 데이터를 대상(레지스터에 저장된)으로 다시 메인 메모리에 저장하는 일도 발생한다.

 

그렇기에 CPU와 메모리 간에서도 각각의 버스가 존재한다.

 

1. 데이터 버스

- 데이터를 이동하기 위해 필요한 버스.

- 여기서 말하는 데이터란 명령어가 될 수도 있고, 연산에 필요한 피연산자(Operand)가 될 수도 있다.

 

2. 어드레스 버스(Address Bus)

- 주소 값을 이동하기 위해 필요한 버스.

- 예로 들어 CPU가 0x1024번지에 저장되어 있는 데이터 4바이트를 읽으려고 한다면 먼저 메모리 영역에 주소 값 0x1024를 먼저 전달해야 한다. (거기 주소에 있는 데이터를 달라고) 이때 사용되는 것이 어드레스 버스. 메모리는 0x1024번지에 존재하는 4바이트 데이터를 데이터 버스를 통해서 전달받게 된다.

 

3. 컨트롤 버스

- 컨트롤 신호 이동

- CPU가 원하는 바를 메모리에 전달할 때 사용. 쉽게 말해 CPU와 메모리가 서로 특별한 신호를 주고받는 용도로 사용되는 버스.

 

컨트롤 버스의 경우 무엇 때문에 CPU가 메모리에 신호를 전달해야 하는가? CPU는 메모리로부터 데이터를 가져오기도 하지만, 반대로 메모리에 데이터를 저장한다고도 했다.

그렇다면 이 둘 사이에는 데이터를 보낼 것인지, 받을 것인지에 대한 적절한 사인이 오고 가야 한다.

 

책에 있는 사례가 재밌고 직관적이었는데.

 

사례 1.

CPU : 데이터 보내!

메모리 : 몇 번지에 있는 데이터를 보낼까?

CPU : 0x1200번지!

메모리 : 전송!

 

사례 2.

CPU : 데이터 간다!

메모리 : 몇 번지에 저장할까?

CPU : 0x1024번지!

메모리 : 받음!

 

이렇게. 컨트롤 버스의 필요성을 위의 간단한 사례로 알 수 있다.

우선 CPU가 하고자 하는 일이 무엇인지를 메모리에게 알려주고 있다. 이러한 용도로 사용.

그리고 두 번째로 주고받은 데이터는 주소 값. 데이터가 저장된 주소 값을 알아야 적절히 송신 및 수신을 할 수 있기에.

이를 위한 버스가 어드레스 버스.

 

이제 하고자 하는 일이 무엇인지도 알았고, 주소 정보도 주고받았으니 실제로 데이터를 전송하는 일만 남았다.

이때 필요한 게 데이터 버스.

 

 

반응형
Comments