2017-04-22 16 views
0

私はこの古典的な機能を書いた:(32ビットモードで)間違ったVisual Studioアセンブリ出力?

void ex(size_t a, size_t b) 
{ 
    size_t c; 
    c = a; 
    a = b; 
    b = c; 
} 

次のように私は、メインの内側にそれを呼び出す:

size_t a = 4; 
size_t b = 5; 
ex(a,b); 

私が入ったときに生成されたアセンブリコードから期待していた何を

スタックにBの値を1プッシュ:(行った)

mov   eax,dword ptr [b] 
push  eax 
mov   ecx,dword ptr [a] 
push  ecx 
関数は次のようなものです

2-使用スタック内の値とB:他の変数の

push  ebp 
mov   ebp, esp 
sub   esp, 4 
    c = a; 
mov   eax, dword ptr [ebp+8] 
mov   dword ptr [ebp-4], eax 

など。

しかし、これはデバッグ時に、私が見つけるものです:

push  ebp 
mov   ebp,esp 
sub   esp,0CCh // normal since it's in debug with ZI option 
push  ebx 
push  esi 
push  edi 
lea   edi,[ebp-0CCh] 
mov   ecx,33h 
mov   eax,0CCCCCCCCh 
rep stos dword ptr es:[edi] 
    size_t c; 
    c = a; 
mov   eax,dword ptr [a] 
mov   dword ptr [c],eax 

なぜそれが変数を使用して、直接の代わりに、スタックに格納された値を呼んでいますか?私は理解していません...

+0

整数を呼び出すことはできません。関数だけが呼び出されます。他の動詞を使う必要があります。 –

+0

あなたの関数は無意味なので、あなたは無意味なことが起こることを本当に期待することができます。いくつかのローカル変数を操作してから、戻り値なしで副作用なしに戻ります。私は非デバッグビルドでは、あなたの関数は何もコンパイルされないだろうと確信しています。 –

+0

funcitonは何もしないので、コードが生成されているのには驚いています。 – ThingyWotsit

答えて

3

デバッガーは、aにアクセスするためにebpを使用して命令を表示しません。インラインアセンブリを記述するときにも同じ構文が使用できます。そうでなければ、dword ptrがまだ現れる理由。

「シンボル名を表示」をクリックして右クリックして、希望の方法で簡単に取得できます。

+0

ああ、私は今それを参照してください。答えてくれてありがとう! –

1

アセンブリ出力オプション(ファイル名、プロパティ、...を右クリック)を使用すると、デバッグアセンブリの出力から期待するものが得られます。これは、使用しているVSのバージョンによって異なる場合があります。この例では、VS2005を使用しました。私はVS2015を別のシステムに持っていますが、まだ試していません。

_c$ = -8        ; size = 4 
_a$ = 8         ; size = 4 
_b$ = 12        ; size = 4 
_ex  PROC       ; COMDAT 
     push ebp 
     mov  ebp, esp 
     sub  esp, 204    ; 000000ccH 
     push ebx 
     push esi 
     push edi 
     lea  edi, DWORD PTR [ebp-204] 
     mov  ecx, 51     ; 00000033H 
     mov  eax, -858993460   ; ccccccccH 
     rep stosd      ;fill with 0cccccccch 
     mov  eax, DWORD PTR _a$[ebp] 
     mov  DWORD PTR _c$[ebp], eax 
     mov  eax, DWORD PTR _b$[ebp] 
     mov  DWORD PTR _a$[ebp], eax 
     mov  eax, DWORD PTR _c$[ebp] 
     mov  DWORD PTR _b$[ebp], eax 
     pop  edi 
     pop  esi 
     pop  ebx 
     mov  esp, ebp 
     pop  ebp 
     ret  0 
_ex  ENDP 

これは機能しませんが、スワップを動作させるためにポインタを使用する必要があります。翻訳さ

void ex(size_t *pa, size_t *pb) 
{ 
    size_t c; 
     c = *pa; 
    *pa = *pb; 
    *pb = c; 
} 

:スタックに格納

_c$ = -8        ; size = 4 
_pa$ = 8        ; size = 4 
_pb$ = 12        ; size = 4 
_ex  PROC       ; COMDAT 
     push ebp 
     mov  ebp, esp 
     sub  esp, 204    ; 000000ccH 
     push ebx 
     push esi 
     push edi 
     lea  edi, DWORD PTR [ebp-204] 
     mov  ecx, 51     ; 00000033H 
     mov  eax, -858993460   ; ccccccccH 
     rep stosd 
     mov  eax, DWORD PTR _pa$[ebp] 
     mov  ecx, DWORD PTR [eax] 
     mov  DWORD PTR _c$[ebp], ecx 
     mov  eax, DWORD PTR _pa$[ebp] 
     mov  ecx, DWORD PTR _pb$[ebp] 
     mov  edx, DWORD PTR [ecx] 
     mov  DWORD PTR [eax], edx 
     mov  eax, DWORD PTR _pb$[ebp] 
     mov  ecx, DWORD PTR _c$[ebp] 
     mov  DWORD PTR [eax], ecx 
     pop  edi 
     pop  esi 
     pop  ebx 
     mov  esp, ebp 
     pop  ebp 
     ret  0 
_ex  ENDP 
+0

洞察に感謝します。 Hans Passantが答えてくれたのは、Visual StudioでEBP + 8をシンボルaに置き換えるオプション "Show Symbol Names"が選択されていたからです。 –