2

次の関数を呼び出そうとしています:

long long RtlLargeIntegerDivide(long long dividend, long long divisor, long long* pRemainder)

アセンブリ コード (NASM) で。stdcall 呼び出し規約を使用し、商を返します。仕様は次のとおりです。

入力: [EDX,EAX] (被除数)、[ECX,EBX] (除数)

出力: [EDX,EAX] (商)、[ECX,EBX] (剰余)

どうすればこれを行うことができますか?(私の主な問題は、EBP と ESP を正確に理解しているわけではなく、それらがローカル変数とどのように関係しているかということです。)

(いいえ、これは宿題ではありません。ラッパー C ランタイム ライブラリを実装しようとしています。)

ありがとうございました!

4

1 に答える 1

4

32 ビット モードでは、EBP を使用してローカル変数にアクセスする必要はまったくありません。これは、16 ビット時代からの慣例の名残りであり、とにかく今は関係ありません。

ESP はスタック ポインターです。ESP をデクリメントすることで、ローカル変数にスペースを「割り当てる」ことができます。

stdcall呼び出し規約では、引数の受け渡しにスタックが使用されます。スタックにあるときは通常の順序ですが、それを使用している場合は、PUSH逆にプッシュすることを意味します。整数の戻り値は EAX (および必要に応じて EDX) です。呼び出された関数は、スタックから引数をクリーンアップします。

したがって、次のコードはあなたが望むことをするはずです:

sub  ESP, 8; make room for remainder
push ESP   ; pass pointer to remainder as argument
push ECX
push EBX   ; pass divisor argument
push EDX
push EAX   ; pass dividend argument
call RtlLargeIntegerDivide
; quotient returned in EDX:EAX
; so just load remainder from stack
pop  EBX
pop  ECX

(速度のために、 /MOVの代わりに使用できます)PUSHPOP

于 2010-12-26T22:18:38.850 に答える