masm で Invoke ディレクティブを使用すると、CPU レジスタを自動的に保存できますか?
3 に答える
そこに投稿した例を見てください:アセンブリ言語での選択ソート
ターゲット PROC の USES ディレクティブが探しているものです。
USES EAX ESI EDI は、PROC の開始時にこれらのレジスタを自動的に保存し、終了時にそれらを復元します (複数の RET ポイントがあり、複数の RET ポイントを持つことが推奨されていない場合でも)。IOW では、PROC エントリ時に PUSH が生成され、すべての RET の前に一貫して一致する (逆順の) POP が生成されます。これはアセンブリであるため、変更して保存したいレジスターを完全に制御し、責任を負うという考え方です。
また、他の場所で提案されたこととは反対に、stdcall を宣言しても、MASM では何も自動的に保存されません。呼び出し元 (INVOKE 用に生成されたコード) または呼び出し先 (PROC で生成されたコード) がパラメーターを POP するかどうかを決定するだけです。
「stdcall」呼び出し規約は、関数が eax、edx、ecx 以外のレジスタを台無しにしないことを保証します。edx と ecx を保存する場合は、マクロを記述します。
タグがmasm32であるため、Windows x86を想定しています。
完全に可能なのは、API 呼び出しに必要なすべての引数をプッシュしてから、目的の関数を呼び出すことです。私が言いたいのは、Windows のアセンブリでプログラミングを行う場合、レジスタを使用して API を「呼び出す」必要はなく、引数をプッシュしてから API を呼び出す (または呼び出す) 必要があるということです。
たとえば、次のようになります。
push 0
push DWORD PTR SS:[EBP+8]
push 0
push 0
push 80000000h
push 80000000h
push 80000000h
push 80000000h
push 0CF0000h
push offset AppName
push offset ClassName
push 0h
call CreateWindowExA
これとまったく同じです (実際には、パラメーターの値が異なるだけです)。
invoke CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
hInst,NULL
それがあなたの質問の意味ですか?