再利用可能(reusable)...読み込んだプログラムを主記憶に保持し、再利用できる
再入可能(reentrant)...複数のプログラムから同時に呼び出されても正しく処理ができる
再配置可能(relocatable)...読み込む場所が実行に影響しない
再起可能(recursive)...自分自身を呼び出すことが可能
各性質を実証する
再利用可能
hello関数を呼び出して、その格納場所を確認します
void hello(){
printf("hello world\n");
}
main(){
hello();
printf("%p\n", (void*)hello);
}
出力
実行された関数は保持され、再実行しても同じ場所から読み込まれています
[gura@localhost ~]$ ./reusable
hello world
0x401136
[gura@localhost ~]$ ./reusable
hello world
0x401136
実行ファイルのシンボル情報を確認すると、ほかの変数も保持されていることが分かります
[gura@localhost ~]$ nm ./reusable
0000000000403e10 d _DYNAMIC
0000000000404000 d _GLOBAL_OFFSET_TABLE_
0000000000402000 R _IO_stdin_used
w _ITM_deregisterTMCloneTable
w _ITM_registerTMCloneTable
0000000000402100 r __FRAME_END__
0000000000402020 r __GNU_EH_FRAME_HDR
0000000000404030 D __TMC_END__
000000000040037c r __abi_tag
000000000040402c B __bss_start
0000000000404028 D __data_start
0000000000401100 t __do_global_dtors_aux
0000000000403e08 d __do_global_dtors_aux_fini_array_entry
0000000000402008 R __dso_handle
0000000000403e00 d __frame_dummy_init_array_entry
w __gmon_start__
U __libc_start_main@GLIBC_2.34
0000000000401080 T _dl_relocate_static_pie
000000000040402c D _edata
0000000000404030 B _end
0000000000401170 T _fini
0000000000401000 T _init
0000000000401050 T _start
000000000040402c b completed.0
0000000000404028 W data_start
0000000000401090 t deregister_tm_clones
0000000000401130 t frame_dummy
0000000000401136 T hello
0000000000401147 T main
U printf@GLIBC_2.2.5
U puts@GLIBC_2.2.5
00000000004010c0 t register_tm_clones
再入可能
例えば、chromeを複数のタブを開けますし、ウィンドウも複数開くことができます

再配置可能
組み込みシステムなどではプログラムのデプロイ位置を手動で設定したりしますが、
一般OSではメモリは自動管理されています。環境が用意できたら検証します
再起可能
以下のスクリプトはhelloが自信を呼び出していますが、問題なく実行することができます
void hello(int i){
i++;
printf("hello world\n");
if(i>10){
return;
}
hello(i);
}
main(0){
hello();
}
出力
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world