프로그램의 구조와 실행
프로그램의 구조와 인터셉트
- 프로그램이 CPU에서 명령을 수행하려면 해당 명령을 담은 프로그램의 주소 영역이 메모리에 올라가 있어야 한다.
- 프로그램의 주소 영역
- code
- 우리가 작성한 프로그램 함수들의 코드가 CPU에서 수행할 수 있는 기계어 명령 형태로 변환되어 저장되는 부분이다.
- data
- 전역 변수 등 프로그램이 사용하는 데이터를 저장하는 부분이다.
- stack
- 함수가 호출될 때 호출된 함수의 수행을 마치고 복귀할 주소 및 데이터를 임시로 저장하는 데에 사용되는 공간이다.
- CPU가 함수를 실행하다가 다른 함수를 호출하면 다른 함수의 코드로 수행 위치를 이동하여 실행하고 수행을 마치고 다시 돌아와야 하는 복귀 주소를 스택에 저장한다.
- 인터럽트의 동작 원리도 함수 호출과 유사하다. 인터럽트 발생시 복귀주소는 각 프로그램의 주소 공간 중 스택에 저장한다.
- 인터럽트 발생시 CPU를 빼앗긴 시점의 위치는 운영체제가 관리하는 프로세스 제어블록에 저장된다. 프로세스 제어 블록에는 인터럽트가 발생한 시점에서 그 프로그램의 어느 부분까지 수행했는지를 저장하며, 인터럽트 처리 후 프로세스 제어블록에 저장된 주소를 복원시켜 원래 수행하던 일을 재개하게 된다.
- code
컴퓨터 시스템의 작동 개요
- 프로그램 카운터(Program Counter, PC)
- CPU는 매 시점 메모리의 특정 주소에 존재하는 명령을 하나씩 읽어와 그대로 실행한다.
- 이때 CPU가 수행해야할 메모리 주소를 담고 있는 레지스터를 프로그램 카운터라고 부른다.
- 즉 CPU는 매번 프로그램 카운터가 가리키는 메모리 위치의 명령을 처리하게 된다. 일반적으로 조건문이나 반복문, 함수 호출등에 의한 주소 이동이 없는 이상 프로그램 카운터는 항상 바로 다음 명령을 가리키게 되어 코드의 순차적인 수행이 이루어진다.
- 컴퓨터 시스템 구조
- CPU: 명령 수행
- 일반 명령
- 메모리에서 자료를 읽어와 CPU에서 계산하고 결과를 메모리에 쓰는 일련의 명령
- 모든 프로그램이 수행가능한 명령이다.
- 특권 명령
- 보안이 필요한 명령이다. 운영체제만 수행할 수 있도록 제한되어있다.
- CPU 내의 모드 비트(mode bit)로 명령 실행가능성을 체크한다.
- 사용자 프로그램이 특권 명령 실행이 필요한 경우 운영체제에게 특권 명령의 대행을 요청하는 시스템 콜(system call)을 실행한다.
- CPU는 인트럽트 신호가 들어왔는지 매 명령을 수행한 직후 인터럽트 라인을 확인한다. 인터럽트 발생시 CPU는 해당 인터럽트를 처리하기 위한 루틴으로 넘어가서 커널내의 인터럽트 처리 코드를 수행한다.
- 일반 명령
- 메모리
- 사용자 프로그램들과 운영체제가 같이 올라가 수행된다.
- CPU는 프로그램 카운터가 가리키는 메모리의 위치의 프로그램을 수행한다.
- 외부 장치 입출력 연산
- 입출력 장치별로 존재하는 작은 CPU와 메모리를 각각 입출력 컨트롤러와 로컬버퍼라고 부른다.
- CPU: 명령 수행
- 프로그램의 실행
- 의미
- 디스크에 존재하는 실행 파일이 메모리에 적재되어있고
- 프로그램이 CPU를 할당받고 명령을 수행하고 있는 상태를 의미한다.
- 실행 파일이 메모리에 적재 될 때 일반적으로 실행파일 전체가 올라가는게 아니라 실행하는 일부분만 메모리에 올라가고 나머지는 디스크의 스왑영역에 내려가 있다.
- 프로세스의 주소 공간은 코드, 데이터, 스택 등으로 구성된다. 각각의 프로그램마다 실제 메모리 주소와 독립적으로 이러한 주소 공간을 별도로 가지며, 프로그램마다 독자적으로 존재하는 이와 같은 주소 공간을 우리는 가상 메모리 또는 논리적 메모리라고 부른다.
- 운영체제도 하나의 프로그램이므로 운영체제 커널도 코드, 데이터, 스택 주소공간을 가지고 있다.
- 커널의 데이터 영역에는 각종 자원을 관리하기 위한 자료구조가 저장된다. 현재 수행중인 프로그램인 프로세스(process)의 상태, CPU 사용 정보, 메모리 사용 정보 등을 유지하기 위한 자료구조인 PCB를 두고 있다.
- 커널의 스택 영역은 함수호출시의 복귀 주소를 저장하기 위한 용도로 사용한다. 일반 사용자 프로그램의 스택과 달리 현재 수행중인 프로세스 마다 별도의 스택을 두어 관리한다. 모든 사용자 프로그램이 시스템 콜을 통해 커널의 함수에 접근한뒤에 다시 각자의 프로세스의 복귀주소로 돌아가야하기 때문이다.
- 유의할 점은 프로그램 내의 함수호출 시 해당 프로그램의 스택에 복귀 주소를 저장하지만, 시스템 콜이나 인터럽트 발생으로 CPU의 수행 주체가 운영체제로 바뀌는 순간에는 직전에 수행되던 프로그램의 복귀정보를 스택이 아닌 PCB에 저장한다는 점이다.
- 이때 커널 역시 함수구조로 이루어져 있으므로, 커널의 코드가 수행되는 도중에 이루어지는 함수호출은 커널스택을 사용하게 되는 것이다. 커널스택은 프로세스마다 별도로 두고 있어, 커널 내에서 이루어지는 함수호출은 직전에 CPU를 가지고 있던 프로세스의 커널 스택을 사용하게 된다.
- 의미
- 사용자 프로그램이 사용하는 함수
- 프로그램이 사용하는 함수의 종류
- 사용자 정의 함수
- 라이브러리 함수
- 커널 함수
- 시스템 콜 함수
- 인터럽트 처리 함수
- 사용자 정의 함수와 라이브러리 함수는 모두 그 프로그램의 코드 영역에 기계어 명령 형태로 존재한다. 따라서 프로그램이 실행 될 때 해당 프로세스의 주소 공간에 포함되며, 또한 함수호출 시에도 자신의 주소 공간에 있는 스택을 사용하게 된다.
- 커널함수는 운영체제 커널의 주소 공간에서 코드가 정의된다.
- 프로그램이 사용하는 함수의 종류
- 인터럽트
- CPU는 매번 프로그램 카운터가 가리키는 곳에 있는 명령을 수행하는 일 밖에 하지 않기 때문에 현재 수행 중인 프로세스로부터 CPU를 회수해 CPU가 다른 일을 수행하도록 하기 위해서는 인터럽트 매커니즘이 필요하다.
- CPU는 매번 프로그램 카운터가 가리키고 있는 지점의 명령을 하나씩 수행하고 나서, 다음 명령을 수행하기 직전에 인터럽트 라인이 세팅되었는지 체크한다.
- 체크 후 인터럽트가 발생했으면 CPU는 현재 수행하던 프로세스를 멈추고 운영체제의 인터럽트 처리루틴으로 이동해서 인터럽트 처리를 수행한다.
- 인터럽트의 처리를 마치고 나면 인터럽트가 발생하기 직전의 프로세스에게 CPU의 제어권이 다시 넘어가게 된다.
- 상대적으로 중요도가 낮은 인터럽트를 처리하는 도중에 중요도가 높은 인터럽트가 발생시 현재 처리 중이던 인터럽트 코드의 수행지점을 저장하고 우선순위가 높은 인터럽트를 처리하고 다시 이전에 수행하던 인터럽트 처리를 마저 수행한다.
- 시스템 콜
- 커널이라는 운영체제의 주소 공간에 존재하는 함수를 호출하는 것을 시스템 콜이라고 한다.
- 프로그램이 스스로 인터럽트 라인에 인터럽트를 세팅하는 명령을 통해 이루어진다.
- 인터럽트 발생시 CPU의 제어권은 운영체제로 넘어가고 특권 명령을 실행하게 된다.
- 예를 들어 입출력 명령 실행시 CPU는 입출력 명령을 내린 후 다른 프로그램으로 제어권을 이양해서 다른일을 처리하다가 입출력작업이 완료되면 디스크 컨트롤러가 CPU에게 인터럽트를 발생시킨다. CPU는 로컬버퍼로 읽어온 내용을 컴퓨터 내의 메모리로 복사한 후 최초에 입출력을 요청했던 프로세스에게 다시 CPU를 획득할 권한을 준다. 그러면 해당 프로세스는 CPU를 기다리는 큐에 삽입되고 순서를 기다려서 CPU의 제어권을 획득할 수 있다.
- 프로세스의 실행 상태
- 프로세스는 사용자 모드와 커널모드를 오가면서 명령을 수행한다.
- user mode running
- 사용자 프로그램의 주소 공간에 정의된 코드를 실행할 때
- kernel mode running
- 커널의 시스템 콜 함수를 실행할 때
댓글