As a matter of interest, I've been writing some corresponding C (VC6) and Assembler (MASM) functions. Basically trying to replicate my Assembler design in C. Along the way I've been comparing my code with C's code by disassembling it. To those interested, I just created and disassembled the 'center' function, the one used to center a form(main window) on the desktop. At some point, I stoped using 'unsigned int' and started using 'int' believing (incorrectly) that it kind of did the same thing. Of course I know int is signed, but 'everyone' uses int instead of 'unsigned int' and who wants to declare them anyway? Anyway, the code:
C function:


int Center(int wDim, int sDim)
{
return (sDim / 2) - (wDim / 2);
}

Disassembled:

mov eax,dword ptr [esp+0x4]
cdq
sub eax,edx
mov ecx,eax
mov eax,dword ptr [esp+0x8]
cdq
sub eax,edx
sar ecx,1
sar eax,1
sub eax,ecx
ret

unsigned int version:

unsigned int Center(unsigned int wDim, unsigned int sDim)
{
return (sDim / 2) - (wDim / 2);
}

Disassembled:

mov eax,dword ptr [esp+0x4]
mov ecx,dword ptr [esp+0x8]
shr ecx,1
sub ecx,eax
mov eax,ecx
ret

MASM32 version:

mov eax, dword ptr [esp+8]
mov ecx, dword ptr [esp+4]
sub eax, ecx
shr eax, 1
ret

From this, I kind of deduce that at least 1 in every 5 instructions generated from C can be eliminated/optimized. VERY big generalization, but I like it :grin:
Posted on 2004-05-27 07:21:27 by SubEvil
VC6 is a compiler that is now 6 years old or so?
Try it with a newer compiler, I'm quite sure some of them figure out that they should switch the use of ecx and eax.
And some can probably even find this one:



mov eax, dword ptr [esp+8]
sub eax, dword ptr [esp+4]
shr eax, 1
ret


I deduce that at least 1 in every 4 instructions generated by SubEvil can be eliminated/optimized ;)
Posted on 2004-05-27 07:42:07 by Scali
Damn dude, I was so impressed because I thought you wrote that code :tongue:

unsigned int Center(unsigned int wDim, unsigned int sDim)

{
return (sDim - wDim) / 2;
}

Disassembled:

mov eax, DWORD PTR [esp - 8]
sub eax, DWORD PTR [esp - 4]
shr eax, 1
ret

Bessides ... I'm REALLY not good at optimizing ... yet (still learning!) :stupid:
Posted on 2004-05-27 08:47:43 by SubEvil
I tried setting sDim = 10 and wDim = 1, and from that I deduce that the 1 in 5 instructions assembler coders are better than C compilers are usually buggy :grin:
Posted on 2004-05-27 08:58:39 by Jibz
I was able to eliminate 5 of those 5 instructions in my programs. ;) Concluding that software consists of mostly empty space.
Posted on 2004-05-27 09:21:33 by bitRAKE
Yep, NULL and VOID :tongue:
Posted on 2004-05-27 10:03:00 by Homer
Sometimes (actually it happens quite often) I feel my brain consists of the same empty space :rolleyes: NULL and VOID!
Posted on 2004-05-28 01:25:02 by SubEvil
Yes, if the disassembly you show is correct, VC6 has a bug.

VC7.1 outputs the following for the routine (divide both parameters by two then subtract):



mov eax, DWORD PTR _w$[esp-4]
mov ecx, DWORD PTR _s$[esp-4]
shr eax, 1
shr ecx, 1
sub ecx, eax
mov eax, ecx
ret 0


It still doesn't switch the registers.
Posted on 2004-05-28 06:09:29 by death
Death,

What bug are you referring to?
Posted on 2004-05-28 06:59:11 by SubEvil
The rounding is off.
-(a/2) is not the same as (-a)/2;
or at least, not when you do an unsigned division/shift. Then it will round the wrong way.
Or at least, I suppose that's what Jibz and death mean.
Posted on 2004-05-28 07:30:58 by Scali
Thanks Scali, yes, it was the rounding error I was referring to. I posted a better reply on the other forum:

http://www.masmforum.com/viewtopic.php?p=21763#21757

I think what death was referring to was that in his original post, SubEvil pasted
mov      eax,dword ptr [esp+0x4]

mov ecx,dword ptr [esp+0x8]
shr ecx,1
sub ecx,eax
mov eax,ecx
ret

which is missing the line 'shr eax, 1' .. either it somehow got lost in cut-n-paste, or VC6 generates faulty code (my guess would be the first).
Posted on 2004-05-28 07:53:21 by Jibz
My appologies ... the disassembly was incorrect! Not sure why? Probably as Jibz said, copy/paste error, I did a bit of editing to make it more readable, probably edited the line completely out! :stupid:
Posted on 2004-05-28 08:24:03 by SubEvil
Remember to fix your masm32 version too ;)
Posted on 2004-05-28 08:31:26 by death
The fact remains that the compiler, even on this small algo, could have reversed the registers and effectively eliminated 1 instruction!
mov      ecx,[esp+4]

mov eax,[esp+8]
shr eax,1
shr ecx,1
sub eax,ecx
ret
Posted on 2004-05-28 08:36:06 by SubEvil
That's right, but consider that this function is likely to be inlined anyway, so I think the MOV will disappear.
Posted on 2004-05-28 08:44:33 by death
I don't know if there could be any reason for doing it that way. However if you reverse the order of the parameters for the function, Visual C++ generates the shorter code -- perhaps it loads the first parameter into eax by default?

GCC on the other hand generates the shorter version regardles of parameter ordering:

_foo:

mov edx, DWORD PTR [esp+4]
mov eax, DWORD PTR [esp+8]
shr edx
shr eax
sub eax, edx
ret
Posted on 2004-05-28 08:51:41 by Jibz
Oh, and by the way, I don't like how you say it's "C" generating the instructions. It's the specific implementation you are using, namely VC6.
Posted on 2004-05-28 09:24:26 by death
death,

Point taken and hope I'll remember it! I should say VC6 generated! My mindset should change! Since VC6 is basically the only c compiler I use, I never test output on another compiler (my fault) so my mindset generalizes that if it's true for VC6, it must be the same for all c compilers! Sorry!
Posted on 2004-05-31 04:12:43 by SubEvil
Well as I already said, VC6 is now about 6 years old, compilers have improved quite a bit since.
If you want to take a peek at the state of compilers today, you could download the evaluation version of Intel's compiler here: http://www.intel.com/software/products/compilers/cwin/eval.htm.
While VS.NET 2003 is no slouch, this compiler still manages to generate code that is 10% faster than VS.NET 2003 (and that is on my Athlon, ironically :)). I'm quite sure it is the fastest C/C++ compiler available for x86 today.
Posted on 2004-05-31 04:58:00 by Scali
VC2003 for free, http://msdn.microsoft.com/visualc/vctoolkit2003/ - you should replace your vs6 right away.
Posted on 2004-06-01 11:23:22 by f0dder