Entwickler-Ecke

Algorithmen, Optimierung und Assembler - "Magische Konstante" $6666667


Flamefire - Mo 23.03.09 23:09
Titel: "Magische Konstante" $6666667
Ich stoße häufiger auf AssemblerCode wie diesen hier:

Quelltext
1:
2:
3:
4:
5:
6:
7:
MOV EAX,66666667  EAX=66666667
IMUL ECX  EAX=333333CB, EDX=00000065
SAR EDX,2  EDX=00000019
MOV ECX,EDX  ECX=00000019
ADD EDX,EDI  EDX=00000E59
SHR ECX,1F  ECX=00000000
ADD ECX,EDX  ECX=00000E59


Was genau macht das?
Erst eine multiplikation mit einer riesigen Konstante. Dann wird nur das Low-DWord behandelt
das wird erst duch 4 geteilt und zu einem vorherigem ergebnis addiert
danach wird noch das low-DWord durch 2^31 geteilt und das dazu addiert (praktisch also nur das höchste bit)
sehe ich das richtig?
wozu das ganze? kennt so was schon jemand? (Als ich die konstante in google eingegeben habe bin ich auf viele seiten gestoßen mit programmen, in denen die auch verwendet wurde)

Edit: Ok. lt http://blog.dkbza.org/2007/09/reverse-engineering-compiler-produced.html ist es ein simple division durch 10
zumindest die ersten 3 Zeilen
bleibt also noch die frage nach ne letzten beiden


Flamefire - So 05.04.09 18:36

ok. so wie es aussieht wäre eine delphi-entsprechung:


Delphi-Quelltext
1:
2:
3:
var inVar,outVar:Integer;
...
outVar:=Floor(inVar/10);


Auch wenn Delphi da direkt mit dem FDIV befehl compiliert
andere möglichkeit wäre:

Delphi-Quelltext
1:
2:
3:
4:
var inVar,outVar:Integer;
...
outVar:=inVar div 10;
if(inVar<0then Dec(outVar);


Was ist jetzt besser?


JayEff - So 05.04.09 18:48

user profile iconFlamefire hat folgendes geschrieben Zum zitierten Posting springen:
Was ist jetzt besser?

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function Floor(const X: Extended): Integer;
begin
  Result := Integer(Trunc(X));
  if Frac(X) < 0 then
    Dec(Result);
end;

Bedenkt man, dass die Funktion nicht arg viel anders ist, ist die Variante ohne zusätzlichen Funktionsaufruf (Floor) schneller, denke ich :)

Interessantes Detail: Manche Funktionen, auch Trunc, werden behandelt, als wären sie in der System.pas deklariert - sind es aber nicht. Pure Compilermagic *add nice stars and sparkling effects*! :party:


Flamefire - So 05.04.09 18:54

ups...da hätte ich ja mal nachgucken können...
ok danke


BenBE - So 05.04.09 19:02

Sind sie doch auch; heißen dort dann nur immer etwas anders ;-) Schau mal die Sachen mit den Unterstrichen an, die nur private deklariert sind ;-)


JayEff - So 05.04.09 19:06


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
unit System; { Predefined constants, types, procedures, }
             { and functions (such as True, Integer, or }
             { Writeln) do not have actual declarations.}
             { Instead they are built into the compiler }
             { and are treated as if they were declared }
             { at the beginning of the System unit.     }
{...}
{ Procedures and functions that need compiler magic }
{...}
procedure _TRUNC;
Aber mit der Magic (:party:) hatte ich recht! :zustimm: