2017-04-22 104 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。 –