| Gerd Isenberg 2005-10-25, 6:55 pm |
| Keyser Soze schrieb:
> ------------
>
> 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.
Ok, so many unsigned short casts, but still implicitly signed modulo 8!
The empty stackframe is also not necessary. Frame pointer omission
enables getting parameter via esp - fastcall calling convention would
also be nice here.
>
> ------------
>
> 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
>
Aha - not casting 8U implies unsigned int and "dominates" the type of
the expression as unsigned.
> I'm not sure why the "xor eax,eax" is in there.
Code-generator does that for zero-exteinding a byte to a dword.
xor eax,eax
mov al, byte ptr[...]
an alternativ for recent processors is
movzx eax, byte ptr[...]
Seems compilers are not (yet?) smart enough to understand the semantic
of the trailing and eax,7.
Despite these implicte signed int semantic of unsigned short, short
types and mixing 8/16/32-bit registers like al,ah,ax,eax is a mess for
code generators (and may introduce partial register stalls) and should
be avoided for scalar variables and parameters.
A complete other story is using eax/rax etc. in 64-bit mode. This makes
perfect sense for array indices, where you have to address with
64-register, while opereating on it int-wise in 32-bit manner is (much)
shorter code and implicitly clears the upper 32 bit in the 64-bit
register. One reason to use unsigned int type as array index - signed
int implies an explicit sign extension to 64 bit, one extra
instruction.
- Gerd
|