전공/운영체제

메모리

러비코스믹 2025. 5. 4. 22:05

Backgroun 지식

 

1.

CPU가 Memory에 접근

1. 주소 + 읽기 요청

2. 주소 + 보낼데이터 + 쓰기 요청

 

2.

Regi <> Memory

빠름        느림 -> stall (성능저하)

>

Regi <- Cache -> Memory

 

HadrWare Address Protection

 > Process가 다른 메모리영역 침범 보호

   > Register : Base , Limit

 

OS의 privileged instruction : to loading the base and limit registers 

 

Address Binding (Mapping)

1. Disk -> Input Queue -> RAM

2. 처음주소 0x0 : 다음애들이 실행못함 

3. 주소의 변화 // Binding 과정

    a) Symbolic Address      : 변수,함수 이름

-> b) Relocatable Address : 상대적인 주소 // 기준점(시작주소) + X byte by compiler

                                                ex) main() 함수내에 int -> main + N byte

-> c) Absolute Address      : 절대적인 실제 메모리 주소 // 0xe123f  by Linker , Loader

 

Binding Timming (명령어,data)

1. Compile Time : 메모리 주소를 알고있다면 Relocatable 없이 바로 절대주소로 값 넣음 by compiler

   > Process의 위치가 달라지면 recompile해야함

   > 빠르지만 유연성X

2. Load Time :  relocatable code 

     > Load 할때 절대주소로 바뀜

3. Execution Time :  Runtime에 CPU가 접근할때 Dynamic Binding! with HW 도움(Base,Limit,MMU)

 

1. .C -> .o (compiler) 

2. Linker)  다른 .o, static lib 모아서 .exe로

3. Loader) .exe를 메모리에 적재, 동적 라이브러리(.dll, .so)를 찾아 메모리에 매핑 (Dynamic Binding 준비)  with MMU
   → 이때, 실제메모리와 Import Table/IAT 를  dynamic Linking

4. 실행

 

 

printf()

  1. 코드 작성: 개발자가 코드에 printf("Hello\n"); 를 작성합니다.
  2. 컴파일:
    • 컴파일러는 printf가 현재 파일에 정의되지 않은 **외부 심볼(External Symbol)**임을 인지합니다.
    • 이 호출 부분을 컴파일된 목적 파일(.o 또는 .obj)에 'printf라는 이름의 함수를 호출해야 함'이라는 정보와 함께 남겨둡니다. 아직 printf의 실제 주소는 모릅니다.
  3. 링크 (Link Time):
    • 링커는 다른 .o 파일들을 합치면서 printf 심볼을 해결(resolve)하려고 합니다.
    • 정적 링크(Static Linking) 경우: C 표준 라이브러리(.lib 또는 .a)에서 printf 함수의 실제 코드를 찾아서 실행 파일 안에 직접 포함시킵니다. 링커는 이 포함된 printf 코드가 실행 파일 내 가상 주소 공간의 어디에 위치할지 결정하고, 호출 부분을 그 가상 주소로 연결합니다.
    • 동적 링크(Dynamic Linking) 경우 (사용자 예시 - msvcrt.dll):
      • 링커는 printf msvcrt.dll과 같은 공유 라이브러리(DLL)에 있다는 것을 확인합니다.
      • printf 코드를 실행 파일에 포함시키지 않습니다. 대신, 실행 파일에 "나중에 실행될 때 msvcrt.dll을 로드하고, 거기서 printf 함수의 가상 주소를 찾아서 연결해야 한다"는 정보(일종의 약속 또는 자리표시자, Stub)를 남겨둡니다. 이 자리표시자 자체도 실행 파일의 가상 주소 공간 내에 위치합니다.
      • 링커/로더 매핑 (1단계): 심볼(printf)을 특정 DLL의 함수라는 정보와 연결하고, 나중에 주소가 채워질 자리표시자(Stub)를 가상 주소 공간에 배치합니다.
  4. 실행 시작 (Load Time):
    • **로더(Loader)**는 운영체제의 일부로서, 사용자가 실행 파일을 실행하면 이를 메모리에 올립니다.
    • 동적 링크 처리: 로더는 실행 파일이 필요로 하는 msvcrt.dll을 찾아서 프로세스의 가상 주소 공간에 로드합니다 (이미 다른 프로세스가 사용 중이면 메모리에 올라온 것을 공유할 수도 있습니다).
    • 로더는 로드된 msvcrt.dll 내에서 실제 printf 함수의 시작 가상 주소 (예: 0x7FFC1234 - 이 주소는 가상 주소입니다!)를 알아냅니다.
    • 링커가 남겨둔 자리표시자(Stub) 부분을 실제 printf 함수의 가상 주소 (0x7FFC1234)로 **갱신(Binding)**합니다. 이제 프로그램 코드에서 printf를 호출하면 0x7FFC1234라는 가상 주소로 점프하게 됩니다.
    • 링커/로더 매핑 (2단계): 실행 파일의 코드/데이터 및 필요한 DLL들을 프로세스의 가상 주소 공간에 배치하고, 동적 링크 심볼의 가상 주소를 확정하여 연결(Binding)을 완료합니다.
  5. 실행 중 (Runtime) - CPU & MMU:
    • CPU가 printf 호출 명령을 만납니다. CPU는 이제 로더가 알려준 가상 주소 0x7FFC1234에 있는 명령어를 실행하려고 합니다.
    • CPU는 메모리 시스템에 **가상 주소 0x7FFC1234**를 요청합니다.
    • **MMU (Memory Management Unit)**가 이 요청을 가로챕니다.
    • MMU 매핑: MMU는 운영체제가 관리하는 **페이지 테이블(Page Table)**을 참조하여, **가상 주소 0x7FFC1234**가 실제 어떤 물리 메모리 주소(Physical Address) (예: 0x1A001234)에 해당하는지를 실시간으로 변환합니다.
    • 또한, MMU는 해당 메모리 영역에 대한 접근 권한(읽기/쓰기/실행)이 있는지도 검사합니다 (메모리 보호).
    • MMU는 변환된 **물리 주소 0x1A001234**를 메모리 버스로 보냅니다.
    • 실제 물리 RAM은 0x1A001234 주소에 있는 printf 함수의 첫 번째 명령어를 CPU에게 전달합니다.
    • CPU는 이 명령어를 실행합니다. 이후 printf 함수 내의 다른 명령어 접근 시에도 계속해서 가상 주소 -> MMU -> 물리 주소 변환 과정이 반복됩니다.

>>

.c -> .o (symbol -> stub)

dynamic linking -> virtual address

-> " binding " 

 > MMU -> Physical

 

if) 실제메모리보다 크다면?

스왑 공간(swap space) / 페이지 파일 (page file)

: 당장 실제 필요한 1GB 만 올리고 나머지는 Disk 에 올림

 

>  프로그램이 디스크에 있는 주소에 접근하려 하면,

  • 페이지 폴트(Page Fault) 발생
  • OS가 디스크에서 데이터를 읽어 RAM에 올림
  • 필요 없던 페이지는 RAM에서 쫓겨나고 디스크로 내려감 (스와핑)

'전공 > 운영체제' 카테고리의 다른 글

메모리-3  (0) 2025.05.10
메모리-2  (0) 2025.05.09
8장  (0) 2025.04.15
7장  (0) 2025.04.13
6장-2  (0) 2025.04.10