test.c라는 파일을 컴파일하여 test.o라는 이름의 object module을 생성한다. 이때 오브젝트 모듈들은 여러개로 나뉘어서 저장되는데 이것들을 linker가 모두 합쳐서 load module을 만들고 다른 C library에 있는 값들을 loader가 가져와서 메모리에 load한다.
이렇게 처음부터 다 가져와서 load하는 방법도 있지만, 다른 방법도 있다.
dynamic linking을 사용하는 것이다. 필요하면 그때마다 하나씩 Load한다.
즉, 프로그램이 실행될 때 필요한 라이브러리 코드를 직접 넣지 않고 참조만 포함하다가, 실행될 때 실제 코드로 대체된다.
이러한 address binding은 세 곳에서 일어날 수 있다.
만약 메모리 위치가 컴파일 타임에 알게된다면, 절대 주소에 대한 절대 코드(absolute code with absolute addresses)가 생성이 된다.
즉, 프로그램이 컴파일 할 때 절대 주소가 결정되어 프로그램의 시작 주소가 미리 정해져 있는 것이다.
근데 만약 시작 주소가 변경되면 다시 컴파일해야만 한다.
Load time binding은 disk 에서 memory로 load할 때 binding 하는 것이다.
만약, 메모리 주소가 컴파일 타임에 알려지지 않는다면 상대 주소와 아무대나 적재 가능 코드(relocatable code with relative addresses)가 생성된다.
즉, 메모리에 로드 될 때 물리적인 주소가 결정된다.
컴파일러는 재배치 가능한 주소를 생성하며, 로더는 이를 실제 물리 주소로 변환한다.
시작 주소가 변경되어도 다시 load하기만 하면 된다.
binding은 run time이 될 때까지 딜레이된다.
cpu가 주소를 언제 생성하든지간에 binding이 확인된다.
MMU와 같은 address mapping을 위한 하드웨어 자원이 필요하다.
최근의 OS는 이 방식을 사용하고 있다.
즉, 프로그램이 실행되는 동안 주소가 바인딩되므로 실행 시간에 실제 물리적 주소로 변환되는 것이다.
주소 바인딩이 실행시간에 발생하므로 메모리 내에서 프로세스 이동이 가능하다. 따라서 스와핑, 페이지 교체 등의 메모리 관리 기법과 잘 호환된다.
logical address → physical address로 map하는 hardware이다.
relocation register의 값을 받아서 cpu에서 생성된 모든 주소와 더한다.
logical address를 다루는거지 physical address를 볼 수 있는건 절대 아니다.
execution time이 될 때까지 linking을 미룬다.
그리고 라이브러리를 필요로 하는 모든 프로세스는 메모리에 있는 복사본 하나로 충분하다.
이렇게 printf라는 라이브러리를 공통으로 사용하므로 C library 부분을 메모리에 올려두고 동일한 주소를 linking할 때 채워넣어서 사용한다.
메모리 가상화는 제한된 직접적인 실행(LDE)와 효율성과 제어성 면에서 유사한 전략이다.
메모리 가상화에서 효율성과 제어성은 하드웨어 지원에 의해 달성된다.
하드웨어는 virtual address → physical address로 변환한다.
OS는 하드웨어를 설정하기 위한 키포인트롤 포함하고 있어야 하나.
가정
void func()
int x;
...
x = x + 3; // this is the line of code we are interested in
x의 주소가 ebx 레지스터 안에 위치해있다고 가정한다.
eax
registereax
registereax
back into memoryaddress 128에서 명령어를 Fetch
명령어 execute
그다음 명령어 132에서 fetch
execute
…
주소 공간 재배치
OS는 주소가 0이 아닌 physical memory에서 프로세스를 다른 곳에 배치하기를 원한다.
시작 위치인 base register값을 받아서 mmu에서 매핑할 수 있고, bounds register를 통해 끝나는 위치를 계산할 수 있다.
프로그램이 실행을 시작할 때, OS는 실제 메모리 어디든지 프로세스를 적재해야한다고 결정한다.
모든 virtual address는 bound보다 작아야 하고 양수여야 한다.
128에 있는 명령어를 fetch하기 위해 base 값을 더해 실제 주소를 알아낸다.
address space의 크기를 나타내는 방법과
physical address의 끝을 나타내는 방법이다.
운영체제는 base and bounds 접근법을 구현하기 위해 액션을 취해야한다.
세가지 중요한 분기점(juncture)이 있다.
128번째에 mov 명령어 수행하려면 프로세스 입장에서는 128번이지만 실제 프로그램이 메모리 0번째에 저장되는 건 아니다. 예를 들어 32KB 이 위치에 시작된다고 가정하면 +32만 해주면 된다.
Stack 에 있는 값(3000)을 접근하려면 마찬가지로 base Register 값 더한 실제 메모리 주소에서 가져와야 한다.
When a Process Starts Running
프로세스를 위한 주소 공간을 마련해줘야함.
어디가 비어있는지, 어디가 쓰고 있는지 알아야함.
비어있는 공간만 따로 모아둔 걸 Free List라고 한다.
쓸거면 Free list에서 찾아서 쓰고 이 리스트에서 지우면 됨.
When a Process Is Terminated
When Context Switch Occurs