6

次のc++コードがあるとしましょう。

int var1;

__asm {
    mov var1, 2;
}

さて、私が知りたいのは、var1を__asmディレクティブの外側で定義したくない場合、それをその中に入れるために何をしなければならないかということです。それも可能ですか?

ありがとう

4

3 に答える 3

14

これを行うには、_declspec(naked)を使用して「naked」メソッドを作成し、通常はコンパイラーによって作成されるプロローグとエピローグを自分で作成する必要があります。

プロローグの目的は次のとおりです。

  • EBPとESPを設定する
  • ローカル変数用にスタック上のスペースを予約する
  • 関数の本体で変更する必要があるレジスタを保存します

エピローグは次のことを行う必要があります。

  • 保存したレジスタ値を復元する
  • ローカル変数用に予約されたスペースをクリーンアップします

これが標準のプロローグです

push        ebp                ; Save ebp
mov         ebp, esp           ; Set stack frame pointer
sub         esp, localbytes    ; Allocate space for locals
push        <registers>        ; Save registers

および標準エピローグ:

pop         <registers>   ; Restore registers
mov         esp, ebp      ; Restore stack pointer
pop         ebp           ; Restore ebp
ret                       ; Return from function

その後、ローカル変数はで始まり(ebp - 4)、まで下がっていき(ebp - 4 - localbytes)ます。関数パラメータはで始まり、(ebp + 8)上に向かっていきます。

于 2009-09-08T21:05:55.847 に答える
4

アセンブラでC変数を作成することは不可能です。Cコンパイラは変数(つまり、その型とアドレス)を認識している必要があります。つまり、Cコードで宣言する必要があります。

実行できるのはextern、Cの宣言を介してアセンブラーで定義されたシンボルにアクセスすることです。ただし、これらの変数は固定アドレスを持たず、ベースポインターを基準にして参照されるため、自動保存期間のある変数では機能しません。

ブロック外の変数にアクセスしたくない場合はasm、スタックを使用してアセンブラーローカルデータを格納できます。asmブロックを離れるときは、スタックポインタを以前の値に復元する必要があることに注意してください。

sub esp, 12       ; space for 3 asm-local 32bit vars
mov [esp-8], 42   ; set value of local var
[...]
push 0xdeadbeaf   ; use stack
[...]             ; !!! 42 resides now in [esp-12] !!!
add esp, 16       ; restore esp

スタックを操作するたびにローカル変数の相対アドレスを変更したくない場合(つまり、pushまたはを使用する場合pop)、スタックフレームを確立する必要があります(つまり、スタックのベースを保存し、ebpこの値に関連するローカルアドレスを指定します)cedrouの回答で説明されているように。

于 2009-09-08T21:00:45.157 に答える
3

ローカル変数は、ESPレジスタを介してコールスタックの使用可能なスペースを操作することによって割り当てられ、解放されます。

__asm
{
    add esp, 4
    mov [esp], 2;
    ...
    sub esp, 4
}

一般に、これは、代わりに呼び出し元の関数の「スタックフレーム」を確立し、ESPレジスタを直接使用する代わりに、フレーム内のオフセットを使用してローカル変数(および関数パラメーター)にアクセスすることで、より適切に処理されます。

__asm
{
    push ebp
    mov ebp, esp
    add esp, 4
    ...
    mov [ebp-4], 2;
    ...
    mov esp, ebp
    pop ebp
}
于 2009-09-08T21:07:08.310 に答える