2017-04-22 96 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); 

我是從進入時生成的彙編代碼期待功能是這樣的:

1-推的b和a的值在堆棧:(這是完成)

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

我很驚訝,有任何代碼生成,因爲功能不做任何事情。 – ThingyWotsit

回答

3

調試器不顯示使用ebp訪問a的指令。編寫內聯彙編時允許使用相同的語法。否則原因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將符號a替換爲EBP + 8。 –