Fascinating new switch mechanism in assembler

Dan Lewis Dan_member at pathlink.com
Sat Apr 15 01:12:50 PDT 2006


>Given:
>
>int test(int i)
>{
>    switch (i)
>    {
> case 1:
> case 2:
> case 3:
> case 4:
> case 5:
> case 6:
> case 7:
>     return i;
> default:
>     return i + 1;
>    }
>}
>
>The assembler produced is:
>
>?test@@YAHH at Z:
>  push EBX
>  mov EBX,8[ESP]
>  sub EBX,1
>  cmp EBX,6
>  ja L1A
>  jmp dword ptr FLAT:_DATA[00h][EBX*4]
>  mov EAX,8[ESP]
>  pop EBX
>  ret
>L1A:  mov EAX,8[ESP]
>  inc EAX
>  pop EBX
>  ret
>_TEXT ends
>_DATA segment
> dd offset FLAT:?test@@YAHH at Z[014h]
> dd offset FLAT:?test@@YAHH at Z[014h]
> dd offset FLAT:?test@@YAHH at Z[014h]
> dd offset FLAT:?test@@YAHH at Z[014h]
> dd offset FLAT:?test@@YAHH at Z[014h]
> dd offset FLAT:?test@@YAHH at Z[014h]
> dd offset FLAT:?test@@YAHH at Z[014h]
>_DATA ends
>

Walter - I *think* your jump gate is jumping *into* the table.  If I'm wrong,
then disregard all this...

~~~

This is bad because you're flushing the code cash twice to get where you're
going, and the jump instruction itself is being stored repeatedly.  Instead you
want to load the 'final' jump address into a register and jump to that address.
Then the table is essentially a void*[].

so:

mov eax, table[x];
jmp [eax];

dd a;
dd b;

is better than

mov eax, table[x];
jmp eax;

table:
jmp a;
jmp b;

This will roughly half the memory size.  That said, I plan to use a D switch and
trust you'll optimize it well enough.  :)  That way my code is more portable and
clean.  Thanks for showing that!

Sincerely, Dan.





More information about the Digitalmars-d mailing list