Assembler: Für was/aktuell? Lernen wo, wie?



  • asmQuestion schrieb:

    Außerdem was denkt ihr darüber asm von null auf zu lernen? Macht es Sinn? Und vorallem wo lernt man es gut? Gibt es verschiedene Arten?(Hatte mal kurz versucht nen asm code auszuprobieren ist jedoch nicht gegangen und mit einer anderen ide ist es gegangen)
    Also was muss ich beachten? Wo anfangen? Was muss ich wissen. Und vorallem das fast wichtigste kennt ihr onlinequellen was am Anfang gut wäre, damit ich mal reinschnuppern kann bevor ich nen Buch kauf. Aber wie bereits gesagt auch Buchempfehlungen sind gern gesehen. Schreibt einfach ma alles Grundlegende was ihr wisst damit ich mir ein bisschen ein Bild machen kann :). Danke.

    Hallo,

    ich bin von VB.NET zu Assembler gekommen. Man muss Assembler von Null auf lernen, da du auch einiges über deinen PC wissen musst.

    Vor 9 Monaten habe ich mir die Bücher von Rainer Backer und Rhode/Roming gekauft nur auf Neugier. Anschließend die ersten Zeilen geschrieben und siehe da, es geht.

    Sinn macht es auf jeden Fall. Lernen ist niemals verkehrt.
    Seit ich damit arbeit weiß ich was Zeiger sind, wie man sie nutzt 🙂 und man kann kinderleicht mit der WindowsAPI programmieren.
    Eine Fensteranwendung zu erstellen ist im Nu gemacht und die Programme sind winzig klein. An einigen Stellen kannst du sogar Windows umgehen und direkt mit deinem PC "sprechen".

    Das wichtigste für mich war noch die Einfachheit.
    Jede Zeile besteht aus einem einzigen Befehl (mit Operanden natürlich).

    Sowas wie hier:

    rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN));

    gibts da nicht...
    Man muss zwar ein paar Zeilen mehr schreiben aber es lohnt sich allemal.
    Zudem gibts dort genauso If, else, While, Loop und einiges mehr.
    Da ich nur Hobbyprogrammierer bin, bleibe ich auf jeden Fall bei Assembler.

    Worauf du achten musst ist, das du deinen Code nach jeder 5. Zeile mal auf Fehler testest. Sonst suchst du dir einen Wolf *g*

    Man lernt wirklich viel und es ist nicht so schwer wie überall behauptet wird.
    Es ist halt anders.

    Nicky



  • Hallo.
    Ich lerne schon seit einer Woche Assembler lesen und schreiben. Habe dabei natürlich auch eigene Eindrücke von der Sprache gesammelt. Nachdem ich mir diesen Beitrag durchgelesen hatte, musste ich mir ernsthaft Gedanken darum machen ob es die eine Woche überhaupt wert war und dass ich stattdessen nur das Grundprinzip in einer Stunde verstehen sollte.

    -Realist- schrieb:

    ... da man das Grundprinzip in einer Stunde verstanden hat...

    Natürlich brauchte ich anfangs einiges an Motivation. Leider hatte ich auch ein für mich nur halbwegs nachvollziehbares Tutorial, aber der Reiz für mich persönlich Assembler zu lernen war die Sache, dass man die komplette Kontrolle hat und im Groben weiß, beziehungsweise bestimmen kann, was passiert.

    Um meine Meinung mal etwas zu befestigen hier mal ein Beispiel: ~Ich hoffe es ist für euch nachvollziehbar~
    Ein ganz normaler Funktionsaufruf sieht sich in vielen Sprachen ziemlich ähnlich. Ich beschränke mich aufgrund der Übersichtlichkeit nur auf C++ und Assembler.

    int func(int ret=0) {
        return ret;
    }
    
    int main() {
        func(0);
        return 0;
    }
    

    So sieht im besten Fall ein Funktionsaufruf in C++ aus. Wenn man sich diesen Code anguckt. Wird einem klar das C++ einige seiner Pflichten als Hochsprache erfüllt hat. Man kann es schon mit minimalen Englisch Kentnissen und ein wenig Logik nachvollziehen. Dazu kann man den Code auf den ersten Blick auch recht leicht Warten. Was C++ aber für diese Vorteile aufgibt, ist die Klarheit einiger Instruktionen die zwischen einem Funktionsaufruf passieren. Und hier ist Assembler einzigartig (meines Wissens nach).
    Hier ein größtenteils äquivalentes Beispiel, im Vergleich zu dem oberen.
    (Gas Syntax)

    .section .text
    .globl _start
    _start
      pushl $0
      call func
    
      movl $1, %eax
      movl $0, %ebx
      int $0x80
    
    .type func, @function
    func:
      movl 4(%esp), %eax
      ret
    

    Wie man unschwer erkennen kann, ist es schlecht lesbar. Vielleicht bräuchte dieser Code auch mehr Wartungsarbeit als der erste. Aber, wenn man etwas Ahnung von Assembler hat, und dazu noch eine Quelle, die ein Beispiel in dieser Art für eine Erklärung der Segmentierung verwendet, dann ist es an diesem Beispiel wesentlich besser zu verstehen als in einer anderen Sprache wie C++ (Im Bezug auf Funktionen).

    Wollte man sich für längere Zeit mit der Assembler Sprache beschäftigen, sei es im Beruf, der Schule oder im Hobby, dann kann man sagen, je mehr man über Assembler liest, desto besser ist es. Egal welche Qualität die Lektüre bietet. Ich denke neben dem Lesen probiert man die Beispiele nebenbei auch aus. Läuft ein Versuch jetzt darauf hinaus das man es nicht versteht oder das Programm eine falsche Ausgabe macht, dann guckt man nach warum, probiert aus oder zieht das Internet zu Rate. Ich denke wie nachtfeuer schon gesagt hat, ist ein Selbstständiges Lernen für Assembler notwendig und wichtig. Gerade wenn man bei null Anfängt.

    nachtfeuer schrieb:

    ... Das heißt, man ist (erstmal) gezwungen, sich diesen roten Aufbauplan selbst zu erstellen, ...

    Auf Assembler bin ich nicht gekommen, weil ich unbedingt nebenbei wissen wollte wie eine CPU beziehungsweise der Computer intern funktioniert...

    HansKlaus schrieb:

    das mmn schönste an assembler ist einfach, daß du quasi nebenbei lernst, wie die cpu bzw. der computer intern funktioniert.

    ..., sondern wissen wollte was es im genaueren mit der Segmentierung (siehe: Segmentierung) auf sich hat. Ich persönlich finde, dass es sich allein dafür schon lohnt mit Assembler anzufangen. Das wie spielt dabei nach meiner Meinung erst einmal eine Nebenrolle.
    Wichtiger ist: Motivation, Durchhaltevermögen und ein wenig Selbstständiges Lernen.

    Ich hoffe alle zukünftigen Leser hilft mein Beitrag zu diesem Thema weiter.
    Grüße, xpilz



  • So.... jetzt ist Wochenende und ich bin in "Kampfstimmung" 😉 - nein - kämpfen müssen wir nicht.... Dieses Beispiel ist wirklich nur in 5 mn hingesch@#?+- Was es verdeutlichen soll, ist, dass in bestimmten Bereichen C++ absolut keine Berechtigung hat

    Nö, du verstehst das falsch. Höchstens gewisse Bibliotheken und Techniken von C++ haben in gewissen Bereichen keine Berechtigung. I/O-Streams sind da ein Paradebeispiel, die sind saulahm, und du bringst es.
    Aber weißt du was witzig ist: Bei I/O intensiven Applikationen zocken sogar die lahmen iostreams deine ASM-Lösung per Syscall ab da du kein Buffering verwendest.
    Ergebnis: Deine ASM-Lösung ist sogar lahmer als Java oä. da das Konzept stinkt.

    - Und das waren auch die Aussagen meiner vorherigen Posts. Ich denke aber, dass ich jetzt nicht am Zug bin 1000 Lines of C++ Code in Assembler umzusetzen, um zu beweisen, dass C++ im Verhältnis zu ASM von der Effizienz her keine Chance hat... Ich denke, das wird auch so jeder C++ Freak bestätigen.

    Und nächster Denkfehler: Du gehst davon aus, dass ein Assembler-Programmierer genau den Prozessor versteht. Das tun aber nur die allerwenigsten, und die sind zu großen Teilen damit beschäftigt C/C++ Compiler zu schreiben.
    Simples Beispiel: Machst du ein "mov eax, 0" und der Compiler (da er weiß dass es schneller ist) ein "xor eax, eax", dann ist der C++ Code bereits schneller.
    Und das geht in ganz andere Größenordnungen, da es sich ein C++ Compiler leisten kann, absolut unverständlichen und hochperformanten ASM-Code zu erzeugen, den kein Mensch warten wollen würde.

    Dann noch weitere Feinheiten, dass der Compiler Instruktionen perfekt anordnen kann usw

    Kleine Teile mögen in ASM performanter möglich sein als es ein Compiler hinbekommt (Vor allem wenn man spezifische CPU-Features nutzt, die der Compiler per Default nicht unterstützt, zb AMD 3DNow! oä), in der Regel ist C++ aber schneller, je nach Technik eben.



  • Ethon schrieb:

    Aber weißt du was witzig ist: Bei I/O intensiven Applikationen zocken sogar die lahmen iostreams deine ASM-Lösung per Syscall ab da du kein Buffering verwendest.
    Ergebnis: Deine ASM-Lösung ist sogar lahmer als Java oä. da das Konzept stinkt.

    Man muss halt die richtigen Funktionen verwenden - genau wie es c++, java & co machen - das hat nicht mit der Art zu tun, wie man die Funktionen Aufruft.

    Ethon schrieb:

    Simples Beispiel: Machst du ein "mov eax, 0" und der Compiler (da er weiß dass es schneller ist) ein "xor eax, eax", dann ist der C++ Code bereits schneller.

    Nö, XOR ist bestenfalls gleichschnell. XOR bringt nur etwas, wenn es darum geht Flag-Abhängigkeiten zu brechen.

    Ethon schrieb:

    in der Regel ist C++ aber schneller, je nach Technik eben.

    Hängt vom Compiler und deren Einstellungen ab. Aber grundsätzlich kann ich dem zustimmen: Meiner Erfahrung nach sind Compiler hier und da Schlagbar, im Ganzen sind sie aber dem Assembler-Programmiere deutlich überlegen.



  • Ethon schrieb:

    ...

    @Ethon: Es braucht nicht allzulange, um die Assembler Grundlagen zu verstehen, und sich bestimmte Programmiertechniken in Assembler anzueignen. Natürlich nicht in 10 Minuten oder 21 Tagen. Aber vielleicht nicht viel länger als 8 Wochen oder wenn man viel arbeitet, ein viertel oder halbes Jahr für weit fortgeschrittenere Techniken. Auf jeden Fall wird man schneller zum Asm-Profi als man in C++ guter Fortgeschrittener wird.
    Umgekehrt helfen einem die Assemblergrundlagen, bessere, stabilere Programme zu schreiben oder Disassemblings viel besser zu verstehen. Und man kann auch aus Asm heraus C-Funktionen aufrufen, wie auch umgekehrt.

    Setzt euch lieber hin, nehmt euch die Zeit, um Assembler zu lernen und zu vertiefen. Es ist keine verschwendete Zeit. Wenn dann ein tiefers, geübtes Verständnis über die Assemblerprogrammierung da ist, dann kann man nochmal kommen, und seine eigenen Urteile über Assembler hier im Asm-Forum lesen.
    Nur Mut.



  • Man muss halt die richtigen Funktionen verwenden - genau wie es c++, java & co machen - das hat nicht mit der Art zu tun, wie man die Funktionen Aufruft.

    Naja, alle kochen nur mit Wasser. 😉
    In seinem Beispiel hat er write() direkt aufgerufen. Hätte man aus C++ auch können, aber er hat als Gegenbeispiel cout verwendet.
    Um fair zu bleiben, hätte er in seinen Code Buffering, Locales etc einbauen müssen. Von daher fand ich den Vergleich schlicht unfair.

    Nö, XOR ist bestenfalls gleichschnell. XOR bringt nur etwas, wenn es darum geht Flag-Abhängigkeiten zu brechen.

    Du wirst NIEMALS ein "mov REGISTER, 0" sehen, das von einem x86 Compiler erzeugt wurde.
    Selbst wenn mov gleichschnell wäre als ein xor(was es wirklich nicht ist), ist ein xor von der Instruktionsgröße her kleiner (1 Byte vs mehrere Bytes).
    So Feinheiten, die als Mensch eher unintuitiv sind (obwohl sich das bei dem xor in Grenzen hält), aber für den Compiler ganz normal.

    Meiner Erfahrung nach sind Compiler hier und da Schlagbar

    Genau, und für das "hier und da" lohnt sich ja auch Assembler, hat schon einen Grund wieso memcpy und Konsorten in ASM geschrieben werden. 😉
    Nur nervt es mich tierisch, wenn Leute überall verbreiten wollen, dass Assembler ja soooo viel schneller sei als C etc. 😉



  • Ethon schrieb:

    Du wirst NIEMALS ein "mov REGISTER, 0" sehen, das von einem x86 Compiler erzeugt wurde.
    Selbst wenn mov gleichschnell wäre als ein xor(was es wirklich nicht ist), ist ein xor von der Instruktionsgröße her kleiner

    Die Größe ist heut zu tage nur noch in wenigen Fällen von Bedeutung. Und ganz neben bei, XOR ist grundsätzlich nicht schneller - nur in bestimmten Situation kann es Vorteile bringen es zu verwenden.
    Wenn du es nicht glaubst, kannst du es ja mal auf aktuellen Systemen testen.



  • masm schrieb:

    Die Größe ist heut zu tage nur noch in wenigen Fällen von Bedeutung.

    Ist das so? Ich würde mal behaupten, die Größe ist vor allem heutzutage immer mehr von Bedeutung. Denn die CPUs werden immer schneller, die Speicher aber nicht. Google mal nach Instruction Cache...



  • Ich habe mal auf einer CPU Takte für xor gemessen: http://www.c-plusplus.net/forum/237896-full
    Es gibt einen Geschwindigkeitsvorteil, wenn man drei mal hintereinander das eine und gleiche Register mit xor nullt, ob es Sinn macht oder nicht - sei dahingestellt. Irgendwas tut sich in der CPU... 🙂

    Irgendwo im Optimization Manual von Intel steht, dass ihre CPUs eine Art spezielle Unterstützung für xor haben. Vielleicht ein Beispiel, welchen Einfluss ein "Glaube" entwickeln kann. Der Glaube an das gute alte xor bewegt die Chiphersteller, ihre Chips zu modifizieren, damit sie in den Benchmark-Tests ja nicht langsamer abschneiden. Die Benchmark-Tests enthalten ja im guten Glauben lauter xor reg, reg... Die Modifikationen auf dem Chip brauchen mehr Chipfläche, mehr Chipfläche bedeutet mehr Geld - aber dieses Geld werden wir, die Gläubigen an xor, beim Kauf des nächsten PCs ausgeben müssen 😮



  • Das hat nichts mit irgendeinem Glauben zu tun. xor und sub auf das selbe Register haben eine andere Semantik als ein mov 0.

    Intel Optimization Manual schrieb:

    [...] Furthermore, they do not consume an issue port or an execution unit. So using zero idioms are preferable than moving 0’s into the register. [...]

    Assembly/Compiler Coding Rule 36. (M impact, ML generality) Use dependency-breaking-idiom instructions to set a register to 0, or to break a false dependence chain resulting from re-use of registers.



  • dot schrieb:

    masm schrieb:

    Die Größe ist heut zu tage nur noch in wenigen Fällen von Bedeutung.

    Ist das so? Ich würde mal behaupten, die Größe ist vor allem heutzutage immer mehr von Bedeutung. Denn die CPUs werden immer schneller, die Speicher aber nicht. Google mal nach Instruction Cache...

    Der (code-) cache ist stetig mit den CPU Generationen gewachsen und, gemäß sein Natur, auch sein Geschwindigkeit. Auser in sehr kleine Schleifen (<= 32Byte), machte meiner Erfahrung nach die Befehlsgröße keinen Unterschied mehr. Typisches Beispiel: add eax,1 und inc eax ... wenn man nicht grade für den Pentium 4 programmiert, ist reine Geschmackssache – einen Geschwindigkeitsunterscheide habe ich in (sinnvollen) Algorithmen noch nie festgestellt (genau wie bei XOR vs. MOV).



  • Intel sieht das anders. Nicht nur bei xor vs. mov, sondern auch bei inc vs add:

    Intel Optimization Manual schrieb:

    Assembly/Compiler Coding Rule 33. (M impact, H generality) INC and DEC instructions should be replaced with ADD or SUB instructions, because ADD and SUB overwrite all flags, whereas INC and DEC do not, therefore creating false dependencies on earlier instructions that set the flags.

    😉

    Ich würde mal sagen, gerade in kleinen Schleifen machts keinen Unterschied, weil der ganze Code sowieso im Cache bleibt. Interessant wird das, wenn man mal das Programm als ganzes betrachtet. Die Caches sind nicht wirklich soviel größer, eine SandyBridge CPU hat sogar einen kleineren L2-Cache als mancher Pentium 4. Und selbst wenn, der Speicher ist trotzdem nicht wirklich schneller geworden. Außerdem ist der unterste Cache normalerweise shared und muss alle Cores füttern (mittlerweile gibts da ja mehr als einen von). Und das Problem ist auch nicht der Cache, sondern alles was nicht im Cache ist 😉



  • Naja, logisch verknüpfte Operationen wie xor und co gehören natürlich zum Allerletzten, was man bei der Asm-Programmierung lernt, falls überhaupt...Und es hat vermutlich auch noch nie Leute gegeben, die Assembler direkt über den C-Compiler gelernt haben...🙄

    Muss das jetzt eigentlich sein, dass ihr euch an so einem Quark festbeißen müsst?
    mov ax,0 wird auch gerne für Anfänger geschrieben, die noch gar keine logischen-Verknüpf-Asm-Befehle kennen oder vielleicht um die Lesbarkeit des Codes hier und da zu erleichtern. Früher, in DOS-286 Zeiten, waren xor Befehle schneller, aber mit dem Pentium und stärkerer Risc-Bauform spielen ganz andere Punkte eine Rolle.

    Ethon liegt mehrfach daneben, u.a., wie oben schon erwähnt und mit der Annahme, dass heutzutage mit Asm in 286er Realmode Zeit und auf Anfängerniveau programmiert wird und dagegen mit C++ in 2011 mit Performanceoptimierern und Profilern. Viele Asm-Einführungen arbeiten mit Dos auf 286er Niveau und Realmode, einfach, weil es fundamentale Grundlagen sind, die man schnell lernt und die sich relativ einfach auf neuere Entwicklungen übertragen lassen. Das ist so ähnlich, wie wenn beim C++ Anfang nur Konsoleprogramme geschrieben werden. Daraus eine Philosophie über Assembler vs C++ zu entwickeln ist dann so ähnlich tiefschürfend, als würde man schreiben, mit Blitzbasic lassen sich tolle Spiele entwickeln, mit C++ nur Konsolezeugs.

    Es ist auch ein Irrtum, zu glauben, dass Assemblerprofis nur in Assembler programmieren und nicht wüßten, was so ein C-Compiler rausspuckt oder umgekehrt, dass gute C-Profis kein Assembler könnten oder bräuchten.



  • Naja, logisch verknüpfte Operationen wie xor und co gehören natürlich zum Allerletzten, was man bei der Asm-Programmierung lernt, falls überhaupt...Und es hat vermutlich auch noch nie Leute gegeben, die Assembler direkt über den C-Compiler gelernt haben...🙄

    Hey, xor war doch nur ein Beispiel. 😉
    Es geht mir einfach um Dinge, die als Mensch nicht direkt intuitiv wirken, gibt ja viel wüstere Dinge, die ein Compiler anstellt.

    dass heutzutage mit Asm in 286er Realmode Zeit und auf Anfängerniveau programmiert wird und dagegen mit C++ in 2011 mit Performanceoptimierern und Profilern.

    Gibt es denn optimierende Assembler? Wüsste nicht davon, mal einen gesehen zu haben.
    Und nein, so schlecht hab ich Assembler nicht dargestellt, und wenn doch, wars nicht beabsichtigt.

    Zum Rest: Ich kann durchaus Assembler, Reverse Engineering ist ein Hobby von mir. Trotzdem sehe ich mich durchaus in der Lage C++ Code zu schreiben, der ASM-Code in Sachen Performance nicht nachsteht.

    Der einzige Standpunkt, der hier von mir vertreten wird, ist dass ASM kein Muss für möglichst performanten Code ist, mehr nicht.



  • Ethon_notloggedin schrieb:

    Gibt es denn optimierende Assembler? Wüsste nicht davon, mal einen gesehen zu haben.

    Das überrascht leider nicht, denn man sieht den optimierenden Teil in aller Regel im Spiegel.

    Ethon_notloggedin schrieb:

    Zum Rest: Ich kann durchaus Assembler, Reverse Engineering ist ein Hobby von mir. Trotzdem sehe ich mich durchaus in der Lage C++ Code zu schreiben, der ASM-Code in Sachen Performance nicht nachsteht.

    Sag ich doch. Und es ist auch logisch. Du benutzt einen C++ Compiler, der etliche Effizienzevolutionen hinter sich hat, und setzt deine eigenen gegen Null tendierenden Assemblerprogrammierkenntnisse dagegen. (Also wenn dich schon xors im Compilerout überraschen...;) )

    Das einzige Heilmittel dagegen ist, mehr zu lernen und mehr zu üben. Ob nun C++, Java oder Assembler, das ist schnuppe. Aber je mehr du weißt(und abguckst) und je mehr du geübt hast, desto effektiveren Code kannst du programmieren.

    Es ist aber nicht wirklich schlimm, wenn man mal von Vorurteil zu Vorurteil hier im Asm-Forum hoppelt, das ist das normalste von der Welt 😉



  • Ich finde den Vergleich von Assembler und anderen Hoch-Sprachen ziemlich witzlos.
    Als Mensch, z.B. das Intel-Compiler-Optimizer-Team, hat man theoretisch immer die Möglichkeit die CPU besser auszunutzen als ein Optimizer, da man Sinn und Ziel vom Code kennt.
    Kein Mensch kommt aber auf die Idee für den PC (Win,Linux,...) eine Applikation in Assembler zu entwickeln.
    Anders sieht das in der Industrie aus, wenn eine selbstentwickelte Hardware, mit irgendeiner CPU/GPU/DSP,..., womöglich ohne eigenes Betriebsystem, zigtausendmal verkauft werden soll. Da macht man mal eine Abschätzung wie viel Rechenleistung gebraucht wird und kommt nach Jahren dann doch an die Grenzen, weil es ständig neue Ideen und Wünsche gibt. Da kommen durchaus Überlegungen auf mit Assembler das letzte rauszuholen, wohl dem der jemand hat, der das kann. Deshalb gehört das in der technischen Informatik auch zu den Basics.



  • @Ethon
    Aber nur ausnahmsweise und zum Trost 😉

    Siehst du, hier ist auch wieder einer, der Vorurteile über Assembler verbreitet, weil er nichts oder nur wenig weiß:

    Wurst schrieb:

    Ich finde den Vergleich von Assembler und anderen Hoch-Sprachen ziemlich witzlos.

    Verschiedene Sprachen sind für unterschiedliche Dinge gut, und je besser man den Unterschied kennt, desto sinnvoller kann man unterschiedliche Sprachen einsetzen. Aber man kann nicht alles über alle Sprachen wissen und je besser man in Sprache X ist, desto weniger (oder mehr, je nachdem) braucht man eine andere Sprache, weiß aber gleichzeitig um so besser, für welchen Einsatzzweck X nicht optimal ist.

    Wurst schrieb:

    Als Mensch, z.B. das Intel-Compiler-Optimizer-Team, hat man theoretisch immer die Möglichkeit die CPU besser auszunutzen als ein Optimizer, da man Sinn und Ziel vom Code kennt.

    Das Intel-Compiler-Optimizer-Team hat auch nicht die Weisheit mit Löffeln gefressen, wenn es z.B. um Parallelperformance geht. Bei Multicores(z.B. mehr als 16) dürfte es sogar recht schwierig und mühsam sein, die etwa Verzahnung der Befehlsketten von Hand einzustellen. Aber das Intel-Optimizer-Team hat Werkzeuge zum Optimieren, wie Profiler und Thread-Debugger und Optimierzeugs usw., die auch jeder andere nutzen kann, um seinen Code zu optimieren und schnelle Compiler und Libs, die auch jeder (zumindest zahlend) sich zu nutze machen kann. Wenn alle Welt vor Asm davonläuft, ist es natürlich um so leichter, mit Optimierungen jenseits der Algorithmenebene auf den Markt zu kommen. Übung und Know How ist der springende Punkt, nicht das Vorurteil

    Wurst schrieb:

    Kein Mensch kommt aber auf die Idee für den PC (Win,Linux,...) eine Applikation in Assembler zu entwickeln.

    Das ist auch schon wieder falsch, und das kann auch nur einer schreiben, dem die Möglichkeiten neuerer Assembler überhaupt nicht bekannt sind, geschweige denn, sie zu nutzen weiß.
    Assembler wie fasm ( http://www.flatassembler.net/ )
    oder RosAsm oder Betriebsysteme wie MenuetOS ( http://menuetos.net/ ) oder Linker wie http://www.digitalmars.com/ctg/optlink.html wurden z.B. in Assembler entwickelt. In Linux gibt es das beliebte Programm Midnight Commander (siehe dazu http://www.softpanorama.org/OFM/Paradigm/Ch04/mc.shtml).
    Das Original, der Norton Commander wurde in reinem und recht einfachem Assembler entwickelt. Der MC selbst wurde nicht in Assembler gecodet daher auch
    etwas viel Hickack, das Ding für Linux umzusetzen. Letztlich: Es ist ein ursprünglich mit Assembler entwickeltes Tool, welches sich dieser Beliebtheit(durchaus noch immer) in der Linuxwelt erfreut.

    Wurst schrieb:

    Anders sieht das in der Industrie aus, wenn eine selbstentwickelte Hardware, mit irgendeiner CPU/GPU/DSP,..., womöglich ohne eigenes Betriebsystem, zigtausendmal verkauft werden soll. Da macht man mal eine Abschätzung wie viel Rechenleistung gebraucht wird und kommt nach Jahren dann doch an die Grenzen, weil es ständig neue Ideen und Wünsche gibt. Da kommen durchaus Überlegungen auf mit Assembler das letzte rauszuholen..

    Auch viel zu allgemein und eher daneben. In der Industrie zählt vor allem, was wirtschaftlich ist, und da kommt es meist auf den Einzelfall an, was jetzt wo wie eingesetzt wird. In gewisserweise haben dort alle Sprachen ihre Berechtigung, also nicht unbedingt das passende Argument für oder gegen irgendeine Sprache.



  • Hostfreak schrieb:

    Stell Dir mal vor in einer Grossbank werden täglich - sagen wir 40 Millionen Datenbankzugriffe (und das ist eher sehr wenig) gemacht. Man kann sich dann recht leicht vorstellen, wie sich jeder unnötige Zyklus der CPU geradezu potenziert. Bei solchen Programmen, die einerseits "transaktionssicher" - andererseits bei jeder Transaktion aufgerufen werden, ist absolute Effizienz das erste Gebot. Man kann zwar mit gewissen Hochsprachen sehr effizient programmieren - C++ oder Java und sonst so überladenen Programmiersprachen haben dort aber nichts verloren...

    Ich kenne da einen der bei einer Bank genau in dem Bereich arbeitet. Laut seiner Aussage werden alle Transaktionen in Sp´s umgesetzt. Andere Programmierung erfolgt wenn dann in Java oder vergleichbar abstrahierten Sprachen. Sicherheit geht da ganz klar über Performance, zumal da diverse unterschiedliche Systeme eingesetzt werden.

    ASM würde mich informell interesieren, um damit zu arbeiten muß man glaub ich ziemlich freaky sein. Bzw man muß nicht allss können, ein kleiner Einblick reicht aber.



  • Ich würd gern ein paar Details ergänzen.

    Einmal zu OPTLINK. Es stimmt, das Ding war tatsächlich vollständig in Assembler geschrieben. Aus verschiedenen Gründen hat Walter Bright aber entschieden, OPTLINK zumindest langfristig nach C zu portieren. (Damit niemand durcheinanderkommt: Ursprünglich stammt OPTLINK im Wesentlichen von Steve Russell; benutzt wurde er dann innerhalb des C++-Compilers "Zortech C++" -> "Symantec C++" -> "DigitalMars". Dieser Compiler stammt von Walter Bright. Walter Bright beschäftigt sich also mit "fremdem", hochoptimiertem Assembler-Code, der somit natürlich ziemlich schwer zu verstehen ist.)
    Seine Bemühungen hat er hier dokumentiert: http://drdobbs.com/blogs/architecture-and-design/228701319

    Dann zum "optimierenden Assembler": Man kann das sinnlos finden (braucht hier sicherlich auch nicht diskutiert zu werden), aber interessehalber: Randall Hyde, der den HLA (High-Level Assembler) entwickelt, plant für zukünftige Versionen einen Optimierer. Hinweise und Andeutungen in diese Richtung:

    http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/HighLevelAsm/HLADoc/HLARef/HLARef_html/HLAReference.htm (HLA Reference Manual)
    "Unlike various HLL compilers, HLA does not (yet!) attempt to optimize the code that you write."

    http://homepage.mac.com/randyhyde/webster.cs.ucr.edu/HighLevelAsm/hla3/0_hla2.html (HLA v3.0 Preview and Source Code)
    "If you're interested in working on the HLA project, here are some suggestions and areas where I expect I'll need some help: ... F. Work on optimizers for HLA. ..."

    http://webster.cs.ucr.edu/AsmTools/HLA/HLADoc/HTMLDoc/hlafaq.txt (HLA FAQ)
    "17: q. MASM has a nasty habit of changing instructions behind your back. HLA also seems to have this same problem."

    Vielleicht ist diese "schlechte Angewohnheit" von MASM schon ein Zeichen für Optimierungsversuche von MASM? Und dann heißt es in der Antwort u.a.:

    "In general, I have plans of adding a data flow analyzer and an optimizer around version three of HLA. While I certainly intend to provide source level control of the optimizer, if you are offended by an assembler that plays with your source code, then HLA is not for you. On the other hand, if you would like to be able to write readable code and leave it up to the compiler to deal with instruction scheduling and peep-hole optimizations, HLA will be a big win."



  • masm schrieb:

    dot schrieb:

    masm schrieb:

    Die Größe ist heut zu tage nur noch in wenigen Fällen von Bedeutung.

    Ist das so? Ich würde mal behaupten, die Größe ist vor allem heutzutage immer mehr von Bedeutung. Denn die CPUs werden immer schneller, die Speicher aber nicht. Google mal nach Instruction Cache...

    Der (code-) cache ist stetig mit den CPU Generationen gewachsen und, gemäß sein Natur, auch sein Geschwindigkeit. Auser in sehr kleine Schleifen (<= 32Byte), machte meiner Erfahrung nach die Befehlsgröße keinen Unterschied mehr.

    Ich denke das der Cache(Code+Daten) auf 64Bit-x86 gerne noch etwas grösser sein sollte, weil im 64 Bit-Mode der Cache sich um ein vielfaches schneller füllt als im 16/32 Bit-Mode und deren kleineren Adressen und Register+Werte.

    Typisches Beispiel: add eax,1 und inc eax ... wenn man nicht grade für den Pentium 4 programmiert, ist reine Geschmackssache – einen Geschwindigkeitsunterscheide habe ich in (sinnvollen) Algorithmen noch nie festgestellt (genau wie bei XOR vs. MOV).

    Verwendet man in einem Code das EAX-Register und möchte danach das AX-Register mit einem Wert beschreiben, dann ist es sinnvoll das EAX-Register mit "xor eax,eax" zu löschen, noch bevor man ein Wert nach AX schreibt.

    ...

    Es gibt verschiedene Möglichkeiten zur Optimierung.
    Von sehr grosser Bedeutung ist es darauf zu achten, dass Speicherzugriffe nach Möglichkeit richtig ausgerichtet sind. D.h. WORD-Zugriffe sollten auf gerade Adressen erfolgen welche durch 2 teilbar sind und DWORD-Zugriffe auf Adressen die durch 4 teilbar sind usw..

    ...

    Wenn man ein Register beschreibt und unmittelbar danach auf das selbe Register ein Lesezugriff erfolgt, dann gibt es eine Verzögerung, weil sich so eine Kombination nur schlecht paralell ausführen läßt. (Der XOR-Befehl macht hier eine Ausnahme.)
    (Die Intel Core2-Architektur kann beispielsweise 4 Integer-Befehle paralell ausführen. Und das Register-renaming und das Zerlegen in Micro-Ops hat auch seine Grenzen.)
    Je nachdem wie viele Befehle gleichzeitig von der jeweiligen CPU abgearbeitet werden können und wieviele Teilstufen dabei intern von der CPU benutzt werden bis ein Befehl vollständig ausgeführt wird und welche Abhängigkeiten zwischgen den Befehlen bestehen, desto großer sollte der Abstand zwischen jenen Befehlen sein welche in einer Register-Abhängigkeit stehen.

    ...

    Anstelle von "add, eax, 1", oder "inc eax" könnte man auch ein "lea eax, [eax+1]" verwenden. Wenn noch weitere Register, oder Werte hinzuaddiert, oder ein Register mit 2,4, oder 8 multipliziert werden soll, dann bringt der einzelne LEA-Befehl noch mehr Vorteile gegenüber mehrerer anderer Befehle.

    ...

    Anstelle von einer Kombination aus push/pop-Befehlen kann man auch mov/mov-Befehle verwenden. Ein Pentium 4 verarbeitet pop/push-Befehle schneller als mov/mov-Befehle, andere CPUs verarbeiten mov/mov-Befehle schneller als push/pop-Befehle.
    Jeder der es möchte kann es auf seiner eigenen CPU gerne einmal ausprobieren und es selber messen, ob die Kombination aus push/pop, oder die Kombination aus mov/mov schneller abgearbeitet wird.
    Zu diesem Zweck hat "Frank Kotler" eine entsprechende Testroutine(für Linux und NASM) geschrieben:
    https://groups.google.com/group/alt.lang.asm/browse_thread/thread/3d4fefc9bcd80b87/de738e9275a9abc7?hl=de&lnk=gst&q=pushvsmov#de738e9275a9abc7
    Etwas abgewandelt läßt sich dieses Beispiel auch für rinige andere Codeoptimierungen verwenden.

    Neben den Anleitungen von Intel und AMD worin jeweils die Optimierung deren CPU-Modelle relativ anschaulich mit Beispielen erläutert wird habe ich auf die mal gesucht und etwas darüber gefunden:
    Assembly Optimization Tips by Mark Larson
    http://www.mark.masmcode.com/

    Dirk Wolfgang Glomp


Anmelden zum Antworten