Re: compiler generated output
- From: "Keyser Soze" <spamtrap@xxxxxxxxxx>
- Date: Tue, 25 Oct 2005 07:26:47 +0000 (UTC)
"Gerd Isenberg" <spamtrap@xxxxxxxxxx> wrote in message
news:1130173742.957934.173080@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
> Yep, modTest1 with MSVC6, speed optimization, cdq-idiv-emulation,
> modTest1(0,1) => 0xffff or (unsigned short)-1
> :
>
> mov eax, DWORD PTR _a$[esp-4]
> mov ecx, DWORD PTR _b$[esp-4]
> and eax, 65535 ; 0000ffffH
> and ecx, 65535 ; 0000ffffH
> sub eax, ecx
> and eax, -2147483641 ; 80000007H
> jns SHORT $L17139
> dec eax
> or eax, -8 ; fffffff8H
> inc eax
> $L17139:
> ret 0
>
> the same routine, but unsigned int instead of unsigned short!
> Here the diff/mod-expression is considered unsigned.
> Very interesting behaviour.
> modTest1(0,1) => 7
>
>
> mov eax, DWORD PTR _a$[esp-4]
> mov ecx, DWORD PTR _b$[esp-4]
> sub eax, ecx
> and eax, 7
> ret 0
>
> To get the same "signed" behaviour, an explicit cast is necessary:
>
> unsigned int modTest1(unsigned int a, unsigned int b)
> {
> return ( (int) (a - b) % 8 );
> }
>
> mov eax, DWORD PTR _a$[esp-4]
> mov ecx, DWORD PTR _b$[esp-4]
> sub eax, ecx
> and eax, -2147483641 ; 80000007H
> jns SHORT $L17140
> dec eax
> or eax, -8 ; fffffff8H
> inc eax
> $L17140:
> ret 0
>
> The unsigned short or unsigned char difference, "dominated" by the
> implicit signed int divisor 8 is therefore considered signed, while it
> remains unsigned with an unsigned int difference. Is that explicitly
> defined behaviour by some current C(++)-standard - or compiler
> implementation depending?
>
> - Gerd
>
------------
unsigned short modTest(unsigned short a, unsigned short b)
{
return (unsigned short)( (unsigned short)( (unsigned short)(a - b) ) %
(unsigned short)(8U) );
}
00401000 push ebp
00401001 mov ebp,esp
00401003 mov eax,dword ptr [ebp+8]
00401006 sub eax,dword ptr [ebp+0Ch]
00401009 and eax,0FFFFh
0040100E and eax,80000007h
00401013 jns 0040101A
00401015 dec eax
00401016 or eax,0F8h
00401019 inc eax
0040101A pop ebp
0040101B ret
This is one of my personal favorites with VC6.
It's just got to do that promotion to signed integer.
------------
unsigned short modTest(unsigned short a, unsigned short b)
{
return (unsigned short)( (unsigned short)( (unsigned int)(a - b) ) % 8U );
}
00401000 push ebp
00401001 mov ebp,esp
00401003 mov cl,byte ptr [ebp+0Ch]
00401006 xor eax,eax
00401008 mov al,byte ptr [ebp+8]
0040100B sub al,cl
0040100D and eax,7
00401010 pop ebp
00401011 ret
I'm not sure why the "xor eax,eax" is in there.
------------
Optomiziations set to: Maximum speed
Code Generation set to: Pentium Pro
.
- Follow-Ups:
- Re: compiler generated output
- From: Gerd Isenberg
- Re: compiler generated output
- References:
- Re: compiler generated output
- From: Skarmander
- Re: compiler generated output
- From: Gerd Isenberg
- Re: compiler generated output
- Prev by Date: Re: improve strlen
- Next by Date: Re: Self-modifying code on SMP operating systems
- Previous by thread: Re: compiler generated output
- Next by thread: Re: compiler generated output
- Index(es):
Relevant Pages
|