前の記事の通り、アセンブルは正常に完了するようになったのですが、今度はちゃんとリンクできません。
こんなエラーが出ます。
ld: absolute addressing (perhaps -mdynamic-no-pic) used in _x86_sse2_ConvertULY2ToBottomupRGB24.label1 from /Users/umezawa/proj/utvideo/build/utvideo.build/Release/utvideo.build/Objects-normal/i386/Convert_asm_x86.o not allowed in slidable image. Use ‘-read_only_relocs suppress’ to enable text relocs
該当箇所のコードはおおむね以下のようになっています。メモリアドレスを(レジスタからのオフセットなどではなく)絶対指定しているのがいけない、と言われているわけですね。
align 64 ; fedcba9876543210 yoff dq 00010001000100010h dq 00000000000000000h (略) _x86_sse2_ConvertULY2ToBottomupRGB24: (略) .label1: pxor xmm3, xmm3 movd xmm0, dword [ebp] punpcklbw xmm0, xmm3 psubw xmm0, oword [yoff] punpcklwd xmm0, xmm3
これを解消するには PIC (Position Independent Code) にする必要があるのですが、Windows の住人からするとそんな下らないことは(コードを書き換えるのではなく)ダイナミックローダーが解決しろよと思うわけです。Visual C++ には PIC にするコンパイラオプションは無く、DLL をロードする時に全部解決されます。x86 で PIC にすると eip レジスタを汎用レジスタにコピーするために call と pop をする珍妙なコードが出力され、これは現代的なプロセッサでは恐らく大幅にパフォーマンスダウンします。x64 だとこのあたりを解決するために RIP 相対アドレッシングが導入されたわけですが。
こんなもんに付き合うつもりは無いので、エラーメッセージで提示されている通り “-read_only_relocs suppress” をリンカオプションに付けることにします。ビルドターゲットの「情報を見る」の「ビルド」タブの中の「リンク」の下の「他のリンカフラグ」に追加します。これでリンクできるようになります。
で、できたバイナリがちゃんと実行できるかどうかですが、ちょろっと試した限りでは正常に動いています。たぶん、バイナリをメモリ上で書き換えるためにロードに時間がかかる以外は、別段の問題は発生しないのでしょう。
no comment untill now