PROTO および INVOKE を使用して MASM から C 関数を呼び出す

サポートが終了した KB の内容についての免責事項

この記事は、マイクロソフトがサポートを提供しなくなった製品について記述しています。 したがって、この記事は「現状のまま」で提供され、更新されることはありません。

概要

Microsoft Macro Assembler (MASM) バージョン 6.0 では、PROTO ディレクティブおよび INVOKE ディレクティブを使用することで プロシージャ呼び出しのコーディングを簡素化できる場合があります。これらのディレクティブは、パラメータを正しい順序でスタックにプッシュする、正確な外部参照を生成する、強制的に引数を適正なサイズする、関数が終了した後に (必要に応じて) スタックをクリーンアップするなど、多くの操作を処理します。


次の 2 つのサンプル プログラムは、MASM から C 関数を呼び出す方法として、PROTO ディレクトリおよび INVOKE ディレクティブを使用する場合と使用しない場合を示しています。サンプル コード 1 は、従来の手法でのコーディングを使用して C printf() 関数を呼び出します。サンプル コード 2 は、PROTO および INVOKE を使用して簡略化された同じ関数に対する呼び出しを示しています。

詳細

PROTO 定義プロシージャのプロトタイプに関数のプロトタイプの動作 C のこれは、プロトコルの構文です。
   label PROTO [distance] [langtype] [,[parameter]:tag]
PROTO ステートメントは、パラメーターの型と関数の名前付け規則を示すと数量を確認するのには、アセンブラーによって使用されます。関数の引数は、型、および必要に応じて、パラメーター名の一覧が表示されます。例えば
   myfunc PROTO C arg1:SWORD, arg2:SBYTE
関数 myfunc が 2 つの引数を受け取ることを示します。最初に符号付きワードで、2 番目は符号付きバイトです。可変個引数リストが必要な場合に、VARARG の種類を使用します。


実際は, INVOKE は関数を呼び出すコードを生成します。関数、プロシージャ、EXTERNDEF、TYPEDEF、または PROTO ステートメントのいずれかで以前を定義する必要があります。これは、呼び出しの構文です。
   INVOKE expression [,arguments]
アセンブラーには、どのような関数については、引数を指定して、呼び出し規約が知っている、ため、呼び出しステートメントに渡された引数とそれらを正しい順序でスタックにプッシュ、必要な関数名を使用して関数を呼び出すし、(必要な場合、呼び出し規約を使用して) その後、スタックをクリーンアップできます。


呼び出しによって渡される引数の PROTO ステートメントで指定された型よりも小さい場合、MASM は、型変換します。INVOKE ステートメントで一致するように PROTO ステートメントの引数が拡大変換されます。(たとえば、SBYTE から SWORD)これらの種類の変換は、80386 と 80486 の 8086 および 8088 AX と DX レジスタと EAX と EDX レジスタを使用します。これらのレジスタが効果的に上書きされるとため、注意してくださいこれらのレジスタを使用して引数を渡すようにします。


関数の言語の種類は、名前付けおよび呼び出し規約を決定します。PROTO ステートメントの言語の種類、他言語の種類を設定して、します。モデル ディレクティブについては、オプションの LANGTYPE: か (Pascal) 用のコマンド ライン スイッチ/Gc/Gd (C) をしています。ヘルプに記載されているさまざまな言語の規則の表が挿入されています。

サンプル コード 1

; Assemble options needed: /MX
.MODEL small,c ; The "c" langtype prepends
; labels with an underscore.
;-----for OS/2-------
;INCLUDELIB OS2.LIB
;INCLUDE OS2.INC
;--------------------

EXTRN _acrtused:NEAR
EXTRN printf:NEAR

.DATA
fmtlist db "%s, %d, %lu", 0Ah,0
string_1 db "signed byte and unsigned double word", 0
data_1 db -2
data_2 dd 0FFFFFFFFh

.CODE

main PROC
push word ptr data_2+2 ; push the high word of data_2
push word ptr data_2 ; push the low word of data_2
mov al,data_1
cbw ; converts data_1 to a word
push ax
mov ax,offset string_1 ; load the address of string_1
push ax ; push the address on the stack
lea ax,fmtlist ; load the address of fmtlist
push ax ; push the address on the stack
call printf ; call the C library function
add sp,0Ah ; adjust the stackpointer
main ENDP
ret
end

サンプル コード 2

; Assemble options needed: none
.MODEL small,c

;-----for OS/2--------|
;.MODEL small,c,os_os2|
;INCLUDELIB OS2.LIB <---Not needed if "os_os2" indicated. The
;INCLUDE OS2.INC | assembler knows to look for os2.lib
;---------------------| in the path set by the lib environment
; | variable.

EXTERNDEF _acrtused:WORD

printf PROTO arg1:Ptr Byte, printlist: VARARG

;The first argument is a pointer to a string. The second is a keyword
; that permits a variable number of arguments.

.STACK 100h
.DATA
fmtlist BYTE "%s, %d, %lu", 0Ah,0
string_1 BYTE "signed byte and unsigned double word", 0
data_1 SBYTE -2
data_2 DWORD 0FFFFFFFFh

.CODE
main PROC
INVOKE printf, ADDR fmtlist, ADDR string_1, data_1, data_2
main ENDP
ret
end

プロパティ

文書番号:73407 - 最終更新日: 2017/02/01 - リビジョン: 1

フィードバック