[OS] 프로그램 실행과정 / Address Binding

parkheeddong·2023년 5월 3일
0

Operating System

목록 보기
35/63
post-thumbnail

1. 프로그램 개발부터 실행까지의 과정

🔔 Source Program -> Compiler -> Object Module

개발자가 소스 프로그램을 작성하면, 컴파일러가 프로그램을 컴파일 하고 결과물로 Object Module이 생성된다.

🔔 Object Module (+System Library) -> Linking Editor -> Load Module

Linking Editor가 Object Module을 Linking을 하는데 이 때 시스템 라이브러리도 Linking 한다. 결과적으로 Load Module이 생성된다(=실행 파일)

🔔 Load Module (+System Library) -> Loader -> In-memory Binary Image

Loader가 프로그램을 메모리의 일정 공간으로 로딩한다. 이 때 Linking 되지 않은 시스템 라이브러리가 있다면, 로딩할 때 메모리에 함께 올린다.

🔔 In-memory Binary Image (+Dynamic Loaded System Library) -> Running(실행)

하드디스크 보조 장치에 있는 프로그램을 메모리로 옮기고 나면 실행(run)을 시작한다.
Loading 할 때까지도 올라기지 않은 라이브러리가 있다면, 실행(running)할 때 해당 라이브러리를 메모리에 올리게 되는데 이것을 "Dynamic Linking"이라고 한다.

-> 로더가 로딩을 할때에 운영체제가 개입된다. 커널이 메모리의 빈 공간을 확인하고, 옮기려는 실행파일을 옮길수 있는 상황인지 확인하고 가능하게 하거나 가능하지 못하게 하면서 관리한다.

2. Address binding

1) 컴파일 타임 바인딩

💭 Example

Compiler, Linker 등의 시스템 소프트웨어들이 실행파일을 만들 때, 실행파일의 주소는 주기억장치 '4000번지'부터 실행될 것이라고 지정한다.
만약 중간에 Jump 명령이 있으면 6000번지로 점프하라고도 정해준다.
따라서 메모리에도 동일하게 4000번부터 적재되며, 점프 주소도 6000번지가 된다.

✔ 컴파일러가 소스코드를 컴파일할 때부터, 해당 프로그램은 메모리의 몇번지에 들어갈지 지정한다.

✔ 컴파일러는 프로그램 시작 주소를 가정하고 컴파일하므로, absolute한 코드가 생성된다. 이 코드는 메모리의 4000번지에 들어가야만 실행이 되며, 다른 번지에 로딩되면 실행이 불가능해진다. 메모리 적재 위치를 바꾸려면, 시작 번지를 바꾼 상태로 다시 컴파일을 해야 한다.

2) 로드 타임 바인딩

💭 Example

컴파일 할때에는 프로그램 시작 주소를 0번지로 정하지만, 실제 로딩될 때에는 메모리의 임의의 주소 어디로든 갈 수 있다.
다만, 이 때 프로그램 상에서의 주소값들(Address Constant. ex) jump 주소 등)을 모두 일일이 찾아 바꾸어주어야 한다. (=Relocation 과정)
Relocation 이후에 Run을 해 주어야 한다.

(a) 실행파일(executable) : relocatable

실행 파일의 메모리 주소는 무조건 0번지부터 시작한다고 가정하고, 컴파일을 한다.

(b) after Loading

메모리에 들어갈 때에는, 0번지가 아닌 16384번지에 적재되도록 할 수 있다. (allocation address)

(c) Relocation

실행 파일에서의 Jump 360, Load 명령(메모리 1204번지에서 데이터를 가져와서 레지스터 R1에 적재하라)의 주소도 바뀌게 된다.
Jump 360의 주소 = 16384 + 240 = 16624
Jump 명령 = Jump 360 + 16384 = Jump 16744
Load R1, 1204 의 주소 = 16384 + 800 = 17184
Load 명령 = Load R1, 1204 + 16384 = Load R1, 17588

3) Run-time Binding

💭 Example

Compiling, Linking할 때에는 메모리 시작주소를 0으로 가정한다.
메모리에 들어갈 때에는, 다른 주소에 적재될 수 있다.
그러나 메모리 주소 16384 번지에 로딩되었다고 하더라도, address constant를 그대로 둔다. (jump 360, load 1204 등)
대신 런타임에서 address constant 주소값이 generation 되면, CPU의 MMU의 Relocation Register에 16384 값을 두고, address constant 메모리 주소에 접근하려고 할 때 16384를 더하여 접근하도록 한다.
즉, 런타임에 allocation address로 보정하여 하도록 한다.

✔ Compiling, Linking할 때에는 메모리 시작주소를 0으로 가정한다.

✔ 메모리에 들어갈 때에는, 다른 주소에 적재될 수 있다.

✔ 미리 allocation을 하지 않고, 실행을 하면서 address constant가 나올 때마다 allocation address로 보정한다.

🔔 MMU

MMU(Memory Management Unit) 이런 일을 자동으로 해 준다.

🔔 logical address physical address

CPU 가 1204를 generation하면, 실제 메모리 주소값은 17588이다. 이 때 1204를 logical address, 실제 주소 17588을 physical address라고 한다.

🔔 relocation register limit register

프로그램이 배치된 시작 주소를 16384를 relocation register에 두게 된다.
limit register는 프로그램의 크기값이다.(몇바이트인지)

📌 Dynamic Linking이란?!

✔ Static Linking

Linking이 이뤄질 때, 사용된 라이브러리 함수의 모듈들을 linking한다.

✔ dynamic linking

실행(running)까지 linking을 연기하고, 실행할 때 linking한다.

✔ 장점: 메모리공간의 낭비와 디스크 공간의 낭비를 줄일 수 있다

  • 실행파일을 만들때 라이브러리가 들어가지 않으므로 실행파일의 크기가 작아져서 디스크 공간이 절약된다.
  • dynamic linking 함수들은 shared memory 영역을 따로 두고 함께 공유된다. dynamic linking 함수들이 프로세스마다 중복 배치되지 않으므로 메모리 공간도 절약된다.

📌 Stub Concept

= Dynamic Linking을 수행하는 방법

실제 프로그램 코드 상에 필요한 라이브러리 함수가 dynamic linking 함수일 경우 runtime 전까지 linking되지 않는다.
따라서 코드 상에는 해당 함수 호출를 호출할 때 함수를 불러들여서 linking을 다시 하게 만드는 코드가 들어있는데, 이를 'stub'이라고 한다.
즉 dynamic linking 함수를 호출하는 부분에는 stub 코드가 있다.

0개의 댓글