Windowsセキュリティセミナー   豊田孝とBjarne Stroustrup氏との対話


C++からアセンブラーを呼び出してみる

 ここから公開されているユークリッドの最大公約数を求めるアセンブラールーチンをC++コードから呼び出すと、次のようなリンクエラーが返されます。

ライブラリの検索が終了しました。
パス 1 が終了しました。
非 SAFESEH イメージを作成しています。
EuclidStep2.obj : error LNK2019: 未解決の外部シンボル "int __cdecl euclid(int,int)" (?euclid@@YAHHH@Z) が関数 _main で参照されました。
Debug/EuclidStep2.exe : fatal error LNK1120: 外部参照 1 が未解決です。
ビルド時間 0:02
ビルドログは "file://d:\DownLoaded\euclidstep2\Debug\BuildLog.htm" に保存されました。
EuclidStep2 - エラー 2、警告 0
========== すべてリビルド: 0 正常終了、1 失敗、0 スキップ ==========


Cコードからアセンブラールーチンを呼び出すことは意外と簡単です。また、よくあることです。C++からはどうでしょうか?おそらく、これもよくあることでしょう。

 上のリンクエラーは、C++のmain関数内で参照されているアセンブラールーチン"int __cdecl euclid(int,int)"がリンカーには見えないということのようです。これはリンケージに関する問題ですが、Bjarne Stroustrup氏のいくつかの論文に目を通してもはっきりした回答は見い出せません。たとえば、この回答は同氏には珍しくハウツー情報程度の内容となっています。

おそらく、"動かし方"を熟知している人は多数に上ると思いますが、その背景を知っている人の数はそれほど多くはないでしょう。

 考えてみると、C++の世界からアセンブラーの世界はどのように見えるのでしょうか?また、アセンブラーの世界からC++の世界はどのようの見えるのでしょうか。Cはシステム記述言語ですから、アセンブラーの世界とそれほど違いがありません。C++の世界をCの世界に近づければ、アセンブラーの世界がより鮮明に見えることになります。筆者はこのように考え、C++からアセンブラーコードを呼び出すことに成功しています。

>kb /すべてのスレッド /言語の表示
スレッド 1 の呼び出し履歴 (スレッド ID: 2436 (0x984)):
 インデックス 言語       関数      
--------------------------------------------------------------------------------
*1      Asm      EuclidStep2.exe!euclid(long x=10, long y=45) 
 2      C++      EuclidStep2.exe!main(int argc=3, char * * argv=0x00383d38) 
 3      C        EuclidStep2.exe!__tmainCRTStartup() 
 4      C        EuclidStep2.exe!mainCRTStartup() 
 5               kernel32.dll!7c816fd7() 


 ご覧のように、C、C++、Asmという3つの世界が連携しながら、仕事をやり遂げようとしています。面白いですね。


前へ | 次へ



豊田孝の「IT談話館」
 WinDbgカーネルデバッガスクリプティング講座


Copyright©豊田孝 2004- 2008
本日は2008-08-20です。