0
votes

Disassembling the following function using VS2010

int __stdcall modulo(int a, int b)
{
    return a % b;
}

gives you:

push        ebp  
mov         ebp,esp  
mov         eax,dword ptr [ebp+8]  
cdq  
idiv        eax,dword ptr [ebp+0Ch]  
mov         eax,edx  
pop         ebp  
ret         8  

which is pretty straightforward.

Now, trying the same assembly code as inline assembly fails with error C2414: illegal number of operands, pointing to idiv.

I read Intel's manual and it says that idiv accept only 1 operand:

Divides the (signed) value in the AX, DX:AX, or EDX:EAX (dividend) by the source operand (divisor) and stores the result in the AX (AH:AL), DX:AX, or EDX:EAX registers

and sure enough, removing the extra eax compiles and the function returns the correct result.

So, what is going on here? why is VS2010 emitting erroneous code ? (btw, VS2012 emits exactly the same assembly)

1
Did you generate assembly output (by the compiler) or did you disassemble a compiled binary? - xxbbcc
What assembler are you using? - Fred Larson
@FredLarson I assume he's using the assembler that comes with VS 2010 (ml.exe). - xxbbcc
I am using the disassembly feature from within the IDE - Yuval
@Yuval See this stackoverflow.com/questions/1020498/… and generate assembly out when you compile. - xxbbcc

1 Answers

1
votes

The difference, most likely, is that the author of the disassembler intended for its output to be read by a human rather than by an assembler. Since it's a disassembly, one assumes the underlying code has already been assembled/compiled, so why worry about whether it can be re-assembled?

There are two major possibilities here:

  • The author didn't realize or didn't remember that the dividend is implicit for idiv (in which case this could be considered a bug).
  • They felt that making it explicit in the output would be helpful for a reader trying to understand the flow of the disassembly (in which case it's a feature). Without the explicit operand, it would be easy to overlook that idiv both depends on and modifies eax when scanning the disassembly.