弱いバインディング

m68kにはhardware_init_hookというシステム依存部で定義する関数があり、リセット直後にCPU依存部から呼ばれます。この関数は名前のとおりハードウェアの初期化をおこなうフック関数です。フックと言うことは、ない場合もあります。m68kのstart.Sは以下のようなコードでこの関数を呼び出します。

    /*
     *  hardware_init_hook の呼出し(0 でない場合)
     *
     *  ターゲットハードウェアに依存して必要な初期化処理がある場合
     *  は,hardware_init_hook という関数を用意する.
     */
    move.l #hardware_init_hook, %a0
    cmp.l #0, %a0
    jbeq start_1
    jsr (%a0)

「hardware_init_hookが0でない場合」は、これを呼びます。hardware_init_hookが未定義ならばリンクエラーになりそうなものです。そうならないのは、ldリンカースクリプトに次のような宣言があるためです。

PROVIDE (hardware_init_hook = 0) ;

これはhardware_init_hookに0を代入しなさいというリンカー・スクリプトの命令です。それだけなら何でもありませんが、provide命令で代入された値は、ソースコード内に実シンボルが定義されている場合、そちらの値で置き換えられます。ですから、未定義だと0、定義済みだとその値をプログラム中で使うことが出来るのです。
VisualDSP++の場合、リンカーにこのような機能はありません。しかし、アセンブリ言語にこのような機能があります。たとえば次のプログラムで、

.extern foo;
.weak bar;
_main;
    p0.L = lo(foo);
    p0.H = hi(foo);
    p1.L = lo(bar);
    p1.H = hi(bar);

fooが外部のプログラムで未定義の場合、リンカーがエラーを出力して終了します。しかし、barが未定義の場合はエラーは出力されず、プログラムにはbarの値として0が渡されることになります。これはgnu ldのprovide()と同じ動作です。
hardware_init_hookのほか、software_init_hook、software_term_hook関数がありますが、これらも同様の仕掛けで実装します。