./index.html ../index.html

アセンブラでdllを作る&使う

作る

test.nas

まずはALINKの場合。
エクスポートは単にexportでOKです。

section .code USE32 CLASS=CODE

..start:
  mov eax, 1
  ret 12

global _asm_add
_asm_add:

  mov ecx, [esp + 4]
  lea edx, [esp + 8]
  xor eax, eax
  
.loop:
  
  add eax, [edx]
  add edx, 4
  
  dec ecx
  jnz .loop
  
  ret

export _asm_add
...>nasmw -fobj test.nas

...>alink -dll -base 0x40000000 -oPE -subsys win test.obj exports.obj
ALINK v1.6 (C) Copyright 1998-9 Anthony A.J. Williams.
All Rights Reserved

Loading file test.obj
Loading file exports.obj
matched Externs
matched ComDefs
Generating PE file test.dll

続いてilink32の場合。
どうもnasmのexportと相性が悪いみたいで、リンカがエラーを起こすため、exportの一行を削除して、代わりに.defファイルを書きます。
(ilink32と相性ばっちりのはずのTASMならこんな苦労は要らないかも←未検証)

test.def

LIBRARY test
EXPORTS
  _asm_add
...>nasmw -fobj test.nas

...>ilink32 /Tpd test , test.dll , , , test.def
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

使う

nasmは、OMFフォーマットのときだけ、インポートライブラリに相当する.objを吐くことができます。
単に以下のように書き並べるだけです。

import 関数名 dll名
import 関数名 dll名 エクスポート名

ALINKは、ひとつの.objファイルにインポートライブラリとコードを兼ねさせることができますが、ilink32では不可能なので、別の.objに分けねばなりません。

また、こうやってインポートした関数を使うときは、ALINKではcall [関数名]のように呼ぶ必要があります。名前が、直接OSがロード時に書き変えるリンクテーブルを指すようです。
ilink32では普通にcall 関数名でOKです。名前は、dllの中へjmpするだけのスタブを指します。

この辺の仕様が異なるため、dllが絡むと、ALINKとilink32で共通に使える.objを作ることは不可能…嫌ですねえ。