teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

リンクの例を追加

2017/06/19 13:03

投稿

mit0223
mit0223

スコア3401

answer CHANGED
@@ -6,4 +6,41 @@
6
6
  > しかし、よく考えるとリンカの段階でアドレスを付けるんですよね?
7
7
  アセンブルの段階で各命令や各シンボルにアドレスを付ける作業って含まれるのでしょうか?
8
8
 
9
- 内部シンボルに関してはコンパイラが名前解決を行うので、オブジェクトになった段階で名前解決は必要ありません。アドレスがリンク時に決定するようなものであれば、リロケーション情報からリンカがアドレスを埋めます。これがいわゆる再配置処理です。
9
+ 内部シンボルに関してはコンパイラが名前解決を行うので、オブジェクトになった段階で名前解決は必要ありません。アドレスがリンク時に決定するようなものであれば、リロケーション情報からリンカがアドレスを埋めます。これがいわゆる再配置処理です。
10
+
11
+ 例を示します。
12
+ ```C
13
+ #include <stdio.h>
14
+ extern int i;
15
+ extern b();
16
+ static x = 3;
17
+
18
+ int main(){
19
+ b(); /* リンク時解決 */
20
+ i = i + x; /* iはリンク時解決、 x はコンパイル時解決 */
21
+ printf("i=%d\n", i); /* printf は実行時解決 */
22
+ }
23
+ ```
24
+ ```C
25
+ int i = 10;
26
+
27
+ void b() {
28
+ i= i+4;
29
+ }
30
+ ```
31
+
32
+ こういう2つのプログラムをコンパイルしてリンクすると、
33
+ リンカは i と b のシンボルを解決し、 printf がダイナミックリンクできるように
34
+ シンボルテーブルや PLT など(以前の質問・回答で議論したもの)を生成します。
35
+ xはコンパイル時(アセンブラで)解決されるので、リンカの仕事にはなりません。
36
+
37
+ 上記プログラムが a.c, b.c である場合、以下のようにしてコンパイル・リンクできます。
38
+ ```
39
+ cc -c a.c
40
+ cc -c b.c
41
+ cc a.o b.o
42
+ ```
43
+ 最後の行がリンカの呼び出しですが、printf はデフォルトでシェアードオブジェクトで
44
+ 提供されているため、ダイナミックリンクになります。
45
+ つまり、a.o と b.o はスタティックにリンクされますが、 printf は実行時にダイナミックに
46
+ リンクされます。私がダイナミックリンク用のリンクと呼んだのはこのような場合です。