-
[시스템프로그래밍] Computer Memory and Program시스템프로그래밍 2023. 12. 13. 20:43
프로그램이 메모리 공간을 할당받아 메모리에 적재되면서 프로세스 인스턴스가 생성된다고 하였습니다.
그럼 메모리에 대해서 좀 더 알아볼까요?
Computer Memory : User space and Kernel space
컴퓨터 메모리는 다시 user space와 kernel space로 나뉩니다.
위에서 프로그램은 메모리 공간을 할당받아 메모리에 적재되면서 프로세스가 된다고 하였습니다.
여기서 프로그램에게 할당해 주는 메모리 공간이 user space입니다.
대부분의 시스템들이 메모리를 '페이지'들의 배열로 취급합니다.
즉, 메모리는 그냥 바이트들로 이루어진 하나의 큰 1차원 배열인데, 이를 다시 '페이지'라는 가상의 단위로 나누어서 쓰는 것이죠.
따라서 해당 메모리를 할당받은 프로세스 또한 페이지 단위로 쪼개져 메모리에 적재됩니다.
그럼 kernel은 무엇일까요? kernel은 프로세스를 생성하는 일을 담당합니다.
프로세스를 생성하는 과정을 좀 더 자세히 보면,
1) 먼저 프로세스가 가지고 있는 기계 명령어와 데이터들을 저장할 수 있는 빈 메모리 공간, 즉 빈 페이지를 찾아 프로세스에게 할당합니다.
2) 그리고 프로세스에게 할당된 메모리 정보와, 해당 프로세스가 가진 속성들을 저장하는 자료구조를 구성합니다.
3) 마지막으로 메모리 칩에 있는 일련의 비트들을 프로세스 생명주기(born, live, forked, job-running, dying)으로 변환합니다.
Computer Memory: Memory Layout of a C Program
일반적으로 메모리는 다음과 같은 구조로 이루어져 있습니다. 하나씩 보도록 하겠습니다.
1) stack: 함수가 호출될 때마다 자동으로 저장되는 변수, 즉 지역변수들이 저장되는 영역입니다.
2) Heap: malloc() 등으로 메모리를 동적으로 할당할 때 할당되는 영역입니다.
3) Initialized data segment: 초기화된 전역변수, 정적(static) 변수가 저장되는 영역입니다. text 영역과 달리 읽기 전용은 아니며, 변수값은 프로그램 실행 중에 변경될 수 있습니다. 정적(static) 변수란 선언된 범위(scope) 밖에서도 그 값을 보존하는 변수로, 새로운 범위에서 다시 초기화할 수 없습니다.
4) Unintialized data segment: bss(Block Started by Symbol) 영역이라고도 불리며, 초기화되지 않은 전역변수, 정적변수가 저장됩니다. 실행될 때 커널에 의해 0 또는 NULL로 초기화됩니다. 이 영역도 읽기, 쓰기가 모두 가능합니다.
5) Text segment: 프로그램 코드가 저장됩니다. 프로그램이 컴파일되면 기계어로 번역되어 바이너리 파일이 생성되는데, 이 이진수 기계 명령어들이 text 영역에 저장됩니다. 이 영역은 외부에 의해 쉽게 변경되지 않도록 읽기 전용이라는 속성을 가집니다. OS가 스케줄링해준 대로 프로세스가 본인 차례가 되어 CPU 권한을 받게 되면, CPU는 text 영역에 저장된 명령어들을 하나씩 가져가서 처리합니다.
size 명령어를 통해 text, data, bss segment별 메모리 크기를 알 수 있습니다. 한번 실행시켜 볼까요?
1,2,3번째 컬럼은 위에서 언급한 text, data, bss segment 크기입니다.
4번째 컬럼(dec)는 3가지 영역을 모두 합한 total size를 10진수로, 5번째 컬럼(hex)는 total size를 16진수로 나타낸 것입니다.
Shell
이렇게 프로그램과 프로세스에 대해 알아보았습니다.
그럼 사용자가 프로그램과 프로세스를 제어하고 싶으면 어떻게 해야 할까요?
이를 위해 제공되는 툴이 바로 shell입니다.
Shell은 사용자가 OS가 제공하는 기능에 접근하도록 해주는 사용자 인터페이스입니다.
인터페이스는 크게 GUI(Graphic User Interface), CLI(Command Line Interface)가 있는데,
Shell은 일반적으로 CLI를 사용합니다.
Shell은 OS와 사용자 사이 인터페이스의 역할을 담당하는 동시에, 프로세스를 관리하고 프로그램을 실행시키는 역할도 담당합니다.
리눅스와 유닉스 시스템에서 사용할 수 있는 shell들은 아주 많은데요, 대표적으로 sh, bash, tcsh, csh 등이 있습니다.
그러면 왜 이름이 'shell'이라고 붙었을까요?
shell을 한국어로 번역하면 껍데기입니다.
즉 커널 주변의 '가장 바깥쪽' 계층으로, 커널과 대화하기 위해 커널을 둘러싸고 있기 때문에 해당 이름이 붙여졌습니다.
그림을 보면 유저가 사용하는 응용 프로그램 안쪽 영역 중, shell이 가장 바깥쪽 계층인 것을 확인할 수 있습니다.
shell은 크게 3가지 주요 기능을 가집니다.
1) 프로그램 실행
2) 입출력 관리
3) 직접적인 프로그래밍 UI
하나씩 좀 더 자세히 알아보도록 하겠습니다.
Major Functionalities of Shells
1) 프로그램 실행(Program running)
Shell은 사용자가 입력한 명령어를 번역한 후, 명령어와 관련된 프로그램을 메모리에 적재한 후 프로그램을 실행합니다.
따라서 'program launcher'로 간주되기도 합니다.
2) 입출력 관리(Managing I/O)
shell은 입출력 방향 전환(redirection)을 위한 기호들(>,<,|)을 제공합니다.
일반적인 경우 입출력은 stdin, stdout으로 화면 스크린에 표시되지만, redirection을 이용해 입출력 내용을 다른 파일이나 장치 혹은 프로세스로 보낼 수 있습니다.
예를 들어 ls > text2 이렇게 명령어를 주면, 해당 디렉토리를 ls한 결과가 터미널에 뜨는 것이 아니라 text2파일에 저장되겠죠.
이른 기호들을 이용해, 사용자는 shell로 process의 입출력에 관여할 수 있습니다.
3) Programming
기본적으로 프로그래밍 언어는 변수와 제어문을 가집니다.
따로 파일을 생성하지 않고도, 다음과 같이 명령어 라인에 바로 코드를 작성해서 실행하거나
shell script 파일에 작성한 후 자동화된 방식으로 실행할 수 있습니다.
끝!
'시스템프로그래밍' 카테고리의 다른 글
[시스템프로그래밍] Wait (0) 2023.12.14 [시스템프로그래밍] Process Management (0) 2023.12.13 [시스템프로그래밍] Process (0) 2023.12.13 [시스템프로그래밍] Signals (0) 2023.12.12 [시스템프로그래밍] User Program (0) 2023.12.12