🧑🏻🎓 : 나의 궁금증
각 프로세스에는 사용자 모드 스택과 커널 모드 스택이 있나요?
아니면 각 프로세스에는 사용자 모드 스택이 있고, 모든 프로세스가 공유하는 커널 모드 스택은 유일한가요?
🧑🏻🔬 :
kernel stack
과user stack
은cpu processing mode
에 따라 개별적으로 사용됩니다. 이 분할 상태를 통해 우리는 두 가지 모드(Kernel, User)를 쉽게 이해할 수 있습니다.
user stack
과kernel stack
이라는 두 개의 메모리 영역은 프로세스 실행 및 시스템 상호 작용 처리에 필수적인 기능을 수행합니다.
User Stack
은 User Mode
에서 실행되는 각 프로세스에 할당된 개별 메모리 영역입니다. User Mode
코드 실행에 필수적인 다양한 요소를 위한 동적 저장 공간 역할을 합니다.
지역 변수: 함수 내에서 선언된 변수와 해당 값은 사용자 스택에 저장됩니다.
함수 매개 변수: 함수 호출 전에 함수에 전달되는 인수가 사용자 스택에 push됩니다.
프레임 포인터: frame pointer
는 스택 프레임 구조를 유지하여 중첩된 함수 호출에서 지역 변수 및 함수 매개 변수를 식별할 수 있도록 합니다.
반환 주소: 함수실행이 끝나면 호출자의 위치를 나타내는 반환 주소가 User Stack
에 push 됩니다.
자동 변수: 함수 매개 변수 및 지역 변수를 포함하여 블록 범위 내에서 선언된 변수가 사용자 스택에 저장됩니다.
임시 값: 중간 결과 또는 함수 호출 간에 전달되는 값과 같은 임시 데이터가 User Stack
에 저장될 수 있습니다.
- 함수 블록: 함수 블록은
{
로 시작하고}
로 끝나는 코드 블록입니다. 함수 내에서 선언된 모든 변수는 해당 함수 블록의 범위에 속합니다.
- 조건문 블록:
if
,else
,while
과 같은 조건문 블록은()
로 묶인 코드 블록입니다. 조건문 블록 내에서 선언된 변수는 해당 블록의 범위에 속합니다.
- 반복문 블록:
for
,while
,do-while
과 같은 반복문 블록은()
로 묶인 코드 블록입니다. 반복문 블록 내에서 선언된 변수는 해당 블록의 범위에 속합니다.
Stack 작업을 하려면 Stack Pointer
가 있어야 겠죠?
Stack Pointer
에 대해 알아봅시다! 📚 👈🏻
스택 포인터: Stack Pointer
는 특수 레지스터로서 User Stack
의 현재 상단을 추적하여 스택 요소에 대한 효율적인 액세스를 허용합니다.
스택 푸시: 새로운 데이터가 스택 포인터를 감소시키고 데이터를 새 주소에 저장하여 스택의 상단에 추가됩니다.
스택 팝: 데이터가 스택 포인터 주소의 값을 읽고 스택 포인터를 증가시켜 스택의 상단에서 검색됩니다.
Kernel Stack
은 OS
에 의해 독점적으로 사용되는 권한이 부여된 메모리 영역
입니다. 커널 코드 실행과 시스템 상호 작용을 위한 작업 공간 역할을 합니다.
커널 코드 변수: 커널 함수 내에서 선언된 변수와 해당 값이 Kernel Stack
에 저장됩니다.
시스템 호출 매개 변수 및 반환 값: 시스템 호출에 전달되는 인수와 해당 반환 값이 Kernel Stack
에 저장됩니다.
커널 데이터 포인터: 프로세스 디스크립터
및 메모리 관리 정보와 같은 커널 데이터 구조에 대한 포인터가 커널 스택에 저장됩니다.
하드웨어 컨텍스트 정보: 인터럽트 발생 시점의 하드웨어 컨텍스트, CPU 레지스터, 프로그래머 카운터 등이 커널 스택에 저장됩니다.
파일 디스크립터
는 들어봤는데.. 그렇다면 FD
랑 유사한 개념인가?!
프로세스 디스크립터
에 대해 간략하게 알아봅시다!
PID (Process Identifier) : 프로세스를 식별하는 고유한 숫자입니다.
메모리 할당 정보
: 프로세스에 할당된 메모리 영역의 주소, 크기 및 사용 권한을 포함합니다.파일 디스크립터
: 프로세스가 열어둔 파일과 관련된 정보를 포함합니다.프로세스 우선순위
: 프로세스가 CPU 리소스를 얼마나 자주 사용할지 결정하는 값입니다.부모 프로세스
: 프로세스를 생성한 프로세스의 PID를 포함합니다.자식 프로세스
: 해당 프로세스를 생성한 자식 프로세스의 PID 목록을 포함합니다.프로세스 상태
: 실행 중, 대기 중, 종료된 등 프로세스의 현재 상태를 나타냅니다.PID 🥊 🆚 🤜🏻 Process Discriptor
PID는
Process Discriptor
의 고유한 식별자 역할을 하며,Kernel Stack
에 저장된 커널 데이터 포인터를 통해Process Discriptor
에 직접 접근할 수 있도록 합니다. 이를 통해 운영 체제는 프로세스를 효율적으로 관리하고 제어할 수 있습니다.
🛠️ 커널 스택 작업 🔧
- 스택 전환: 프로세스가
User Mode
에서Kernel Mode
로 전환될 때Kernel Stack Pointer
으로 전환되어User Mode
데이터에 대한 무단 액세스를 방지하고 격리합니다.
과정: 시스템 호출(syscall)이나 인터럽트가 발생하면, CPU는 현재 프로세스의 사용자 스택 포인터(esp 또는 rsp)를 저장하고, 커널 스택 포인터로 전환합니다. 이때 커널 스택은 프로세스 컨텍스트와 하드웨어 상태(레지스터 값 등)를 저장합니다.
- 인터럽트 처리: 인터럽트가 발생하면 CPU는 현재 실행 중인 코드의 상태를 저장하고
interupt handler
를 호출합니다. 이 저장 작업은 커널 스택을 통해 이루어집니다.
인터럽트 처리 과정! 📈
- 인터럽트 발생: 하드웨어 장치(예: 디스크, 네트워크 카드 등)가 CPU에 인터럽트 신호를 보냅니다.
- 현재 상태 저장: CPU는 현재 프로세스의 레지스터 값, 프로그램 카운터(PC), 플래그 레지스터 등을 커널 스택에 저장합니다. 이는 인터럽트 발생 시점의 상태를 보존하여, 인터럽트 처리 후 원래 작업을 재개할 수 있도록 합니다.
- 인터럽트 핸들러 실행: 커널은 해당 인터럽트에 대한 인터럽트 핸들러(Interrupt Service Routine, ISR)를 실행합니다. 인터럽트 핸들러는 해당 인터럽트에 대한 특정 작업을 수행합니다.
- 인터럽트 처리 완료: 인터럽트 핸들러가 작업을 완료하면, CPU는 커널 스택에 저장된 이전 상태를 복원합니다.
- 원래 작업 재개: CPU는 인터럽트가 발생하기 전의 상태로 복귀하여, 중단되었던 사용자 모드의 작업을 계속 수행합니다.
User Stack
Kernel Stack
스택 전환 과정에서 User Stack 포인터는 Kernel Stack 포인터로 전환되어 사용자 모드 데이터에 대한 무단 액세스를 방지합니다🙅🏻♂️
📊 정리정리 🧹
구분 | User Stack | Kernel Stack |
---|---|---|
사용 모드 | 사용자 모드 | 커널 모드 |
용도 | 함수 실행, 변수 저장 | 시스템 호출, 인터럽트 처리, 스택 전환 |
생명 주기 | 함수 호출마다 생성 및 해제 | 운영 체제 내내 유지 |
데이터 액세스 | 사용자 모드 데이터만 | 커널 데이터 및 사용자 모드 데이터 |