Aufruf von int main(){return 0;} mit gcc 4.1.1
-
rüdiger schrieb:
Ist vielleicht auch nicht ganz irrelevant:
xorl %eax,%eax
braucht nur zwei Bytes.movl $0x0,%eax
braucht 5.stimmt, und der Spareffekt bei 64bit ist noch größer, also
B8 0000 0000 0000 0000
vs
31C0
oder
33C0und bei xmm registern gehts glaube ich fast schon gar nicht anders.
Nobuo T schrieb:
Irgendwo verstaendlich. Die Auswahl von in mehrfacher Hinsicht verschiedenen Codes unter dem Aspekt der Lesbarkeit ist fuer Assembler, vor allem im Kontext von Effizienz, einfach indiskutabel.
nirgendwo verständlich. Aber Mist...vielleicht sollte ich doch mal über effektiveres posting nachdenken...;)
Für mich hat gutes, "effizentes Programmieren" ganz normal mit Lesbarkeit und Pflegbarkeit zu tun. Komischerweise ist "effizienter" Code oft lesbarer und einfacher zu handhaben als ineffizenter Code.
Man muss abwägen können.
Vielleicht ist die Assemblersprache trotz der so wirklich leistungsfähigen Assembler, die man heute kostenlos im Internet angeboten bekommt, aus dem Blickfeld geraten, weil der Irrglaube besteht, schneller asmcode = unleserlich, ähnlich wie man meinen könnte, gute medizin muss bitter sein oder das zur PC- Betriebssystemprogrammierung ein C/C++-Compiler praktischer ist als ein aktueller leistungsfähiger Assembler. Hängt davon ab...
-
C/C++? Kenn ich net.
-
nachtfeuer schrieb:
Für mich hat gutes, "effizentes Programmieren" ganz normal mit Lesbarkeit und Pflegbarkeit zu tun. Komischerweise ist "effizienter" Code oft lesbarer und einfacher zu handhaben als ineffizenter Code.
Man muss abwägen können.Falls du ernsthaft meinst, Lesbarkeit und Pflegbarkeit von Assemblercodes ueber die Auswahl der OpCodes herstellen zu wollen, musst du irgendwas beim Programmieren in Assembler missverstanden haben. Assembler programmiert man doch ueberhaupt erst, um fuer spezielle Anwendungen moeglichst optimierten, nicht um besonders lesbaren Code zu erhalten. Zur Erhoehung der Uebersichtlichkeit kann man dann assemblerabhaengige strukturierende Meta-Codes, Macros und vor allem Kommentare benutzen.
Fuer von sich aus besonders gut lesbaren, aesthetischen Code bedient man sich einer abstrakten Hochsprache mit gut optimierendem Compiler, bei der die Auswahl und Anordnung der Befehle im Zweifelsfall weniger kritisch ist.
-
Ich denke, vom optimierten Code sollte man sprechen, wenn man eine Version A und eine Version B zur Hand hat, die man miteinander vergleichen kann. Dann kann man sich austoben und behaupten, A wäre schneller als B oder B ist kleiner als A oder was auch immer.
Speziell bei "xor reg, reg" vs. "mov $0, %eax" (man beachte, kein movl, ein mov reicht in diesem Fall aus): Ich konnte keine Unterschiede in der Ausführungszeit feststellen, beide sind genauso schnell, die xor-Variante ist kleiner, aber das wäre ja nur für "optimize for size" wichtig. Ich bin aber natürlich keine Autorität auf diesem Gebiet, so dass jeder meine Aussage ruhig ignorieren kann.
Wegen:rüdiger schrieb:
http://www.intel.com/Assets/PDF/manual/248966.pdf Section 3.5.1.6
alles schön und gut, aber es wird nur kurz angedeutet, dass der xor-Befehl Flags-Register verändert und das auch noch partiell und das Beispiel mit der for-Schleife verwendet ein signed int als Zählvariable (keine Macro Fusion in diesem Fall, warum nicht
) - alles Kleinigkeiten, aber andererseits nennt sich das Dokument als "Optimization Manual".
Interessant ist aber noch folgendes:The Pentium 4 processor provides special support for XOR, SUB, and PXOR operations when executed within the same register. This recognizes that clearing a register does not depend on the old value of the register. ...
Man hat da in der CPU tatsächlich eine "black box" eingebaut, die aufpasst, dass wenn jemand "xor reg, reg" macht, ein Register schnell auf 0 zurücksetzt, damit es ja nicht langsamer als ein "mov $0, %eax" ist
-
Bitte um konstruktive Kritik:
http://www.henkessoft.de/C/C-Programming%20Under%20The%20Hood.htmOffensichtlich verfolgt der GCC 4.1.1 ein neues (an "x64" angelehntes) Paradigma:
00401349 mov DWORD PTR [esp+0x8],0xfffffff2 00401351 mov DWORD PTR [esp+0x4],0xfffffff4 00401359 mov DWORD PTR [esp],0x2a 00401360 call 0x401318 <doSomething>
Argumente werden nicht (wie üblich) via PUSH auf den Stack "gepushed", sondern direkt in den Stack geschrieben. Da wäre es m.E. sinnvoller, den "Verbleib" der Argumente im Stack des Callee nicht nur via [EPB + X], sondern auch via [ESP + X] aufzuzeigen. Beinahe hätte ich noch vermutet, daß der Callee den EBP-basierten Prolog/Epilog nicht mehr hat. Hmmm, aber wie man sich doch täuschen kann.
-
merker schrieb:
... Beinahe hätte ich noch vermutet, daß der Callee den EBP-basierten Prolog/Epilog nicht mehr hat. Hmmm, aber wie man sich doch täuschen kann.
Wenn ich richtig verstanden habe, was Du meinst, müsste es mit dem gcc Compiler Parameter -fomit-frame-pointer einstellbar sein...
-
-fomit-frame-pointer <--- hatte in diesem Fall keinen Einfluss, probiert es aus.
-
Hmmmm, dann war das wohl nix mit Paradigma.
"MOV [ESP+X], ..." statt "PUSH ..." soll wohl nur eine Optimierung auf Geschwindigkeit sein.
-
push und mov können nicht das gleiche (m2m)
-
Erhard Henkes schrieb:
-fomit-frame-pointer <--- hatte in diesem Fall keinen Einfluss, probiert es aus.
Das liegt daran, dass die Datei als Debug gebaut wird. Man muss als Release bauen, mit dem gcc Parameter -g0.