MID
MID

Reputation: 554

Wrong Visual Studio assembly output?

I wrote this classic function : (in 32-bit mode)

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

I call it inside the main as follows :

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

What I was expecting from the assembly code generated when entering the function is something like this :

1-Push the values of b and a in the stack : (which was done)

mov         eax,dword ptr [b]
push        eax
mov         ecx,dword ptr [a]
push        ecx

2-Use the values of a and b in the stack :

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

and so on for the other variables.

However, this is what I find when debugging :

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  

Why is it using the variable a directly instead of calling the value stored in the stack? I don't understand...

Upvotes: 0

Views: 227

Answers (2)

rcgldr
rcgldr

Reputation: 28826

Using the assembly output option (right click on file name, properties, ...), I get what you expect from debug assembly output. This could depend on which version of VS you use. For this example, I used VS2005. I have VS2015 on a different system, but didn't try it yet.

_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

Note this doesn't work, you need to use pointers for the swap to work.

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

which gets translated into:

_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

Upvotes: 1

Hans Passant
Hans Passant

Reputation: 941635

The debugger doesn't show the instruction using ebp to access a. The same syntax is permitted when you write inline assembly. Otherwise the reason that dword ptr still appears.

It is easy to get it your preferred way, right click > untick "Show Symbol Names".

Upvotes: 3

Related Questions