Muss manches in Assembler geschrieben werden?



  • rapso schrieb:

    (sorry fuer soviel text, sollte auch kein basching sein, aber eine detailiertere, differenzierterere antwort sein als einfach auf das 'bullshit' mit 'selber' zu antworten.

    Viele Gründe sind auch korrekt, aber es gibt auch Tricks, den Compiler auf den richtigen Pfad zu weisen.

    1. kennt der compiler nicht das anwendungsgebiet
    [...]
    2. hat der compiler kein wissen ueber die daten die verwendet werden

    Dafür gibt es PGO, das sollte dein Beispiel erschlagen.
    Für hartnäckige Fälle gibt es builtin_expect und __restrict__.

    Ist zwar compilerspezifisch, aber immerhin flexibler als Assembler.

    3. generiert der compiler immer anderen code

    Kann ich kaum glauben, es ist garantiert, dass stackPt[...] kompakt im Speicher liegt. Aber selbst wenn das nicht der Fall ist, könnte man den Compiler mit std::pair<int,int>stackPt[...] zurechtweisen.

    4. compiler arbeiten nur innerhalb eines kleinen scopes und muessen das nehmen was du ihnen gibst, so wie du es gibst.

    Genau deswegen gibt es -march und -mtune, richtig gesetzt optimiert der Compiler für die gewünschte Plattform. Bestimmte SSE-Befehle können mit builtins abgerufen werden.

    Meiner Erfahrung nach gab es noch nie einen Fall, in dem es nicht möglich war, den Compiler zu zwingen, den gewünschten Assemblercode zu generieren.



  • - wenn du eine funktion aufrufst, weiss der compiler nicht, ob inlinen um den sprung zu ersparen effizienter ist, oder nicht inlinen um cache freundlicher zu sein, es kann sein dass du die zu inlinende funktion um ein paar zeilen source erweiterst und diese dann anders bewertet wird und nicht mehr geinlined wird. (unter der premisse dass man normalen code schreibt und nicht von vornhinein alles mit attributes fuer force-inline und no-inline versieht, was ja low level waere).

    Soweit wie ich weis macht mein Compiler (VS) für jede inline Funktion eine Kosten zu Nutzen Rechnung. Erscheint dem Compiler das Inlinen als nicht effizient, wird die Funktion nicht geinlined.

    Des weiteren existiert eine Compilerschalter für automatisches Inlining.



  • Sehr interessant, was ihr da so schreibt. Die Optimierungsfunktionen meines Compilers sollte ich mir glaub ich auch mal genauer anschauen.

    Geht die Umwandlung von Code eigentlich auch anders herum? Also nicht von einer Hochsprache in Assembler, sondern von Assembler in eine Hochsprache?
    Wenn das ginge, könnte man ja theoretisch den Assembler Code der SPC700 Emulation in eine Hochsprache übersetzen und dann weiterverarbeiten.



  • Das geht zwar, aber was raus kommt ist halt Maschinengenerierter Code. Variablennamen, Funktionsaufteilung etc. können nicht notwendigerweise (meistens mehr oder weniger gar nicht) wiederhergestellt werden. Kommentare natürlich erst recht nicht.

    Edit: Moment mal, du meinst ja Assembler und nicht Binärkram. Das sieht allerdings ähnlich dünn aus, wobei einige Dinge besser zu machen sind. z.B. Kann man versuchen aus Sprunglabels und definierten Konstanten Namen für Variablen abzuleiten, und Kommentare kann man natürlich auch mit nehmen. Schön wird's aber trotzdem nicht.



  • Hmmm... Das ist schade. Also wohl eher eine Notlösung, als ein Sinnvoller Ansatz. Kommt wahrscheinlich auch noch auf den Umfang des Assembler codes an.
    Ich schau mal, ob ich seine Mail Adresse finde. Dann frag ich ihn einfach mal, warum er das in Assembler und nicht in eine Sprache wie C oder C++ geschrieben hat. Denn ich meine, jemand der eine Hardware Emulation in Assembler schreiben kann, muss ja schon irgendwie Ahnung von dem Thema haben und hat vielleicht einen bestimmten Grund, warum er das so und nicht anders gemacht hat.


  • Mod

    Das mag sich vielleicht verwegen anhören, aber: Vielleicht mag er einfach Assembler? Es ist ja anscheinend ein Hobbyprojekt, wo er keine Deadline hat und das Problem so angehen kann, wie es im Spaß macht. Und manche Leute haben tatsächlich Spaß an Assembler.



  • Jupp, klingt gar nicht mal so unlogisch und auch irgendwie nachvollziehbar, da ich das Thema selber spannend finde.
    Leider nur unpraktisch für diejenigen, die das Ding verwenden und warten möchten.



  • Wenn man sich die Zeit der Entstehung anschaut, und das Zielsystem, dann erklärt das schon einiges. DSP-Emulation u.ä. brauchte damals schon eine gewisse Performance (z.B. wie die FPUemulationen noch früher), DOS war extrem assemblerfreundlich und wenn man die Hardware sowieso in und auswendig kennt, dann liegt eine hardwarenahe Emulation irgendwo näher, man hat u.a. mehr Freiheiten auf technischer Ebene, ganz abgesehen von der Tatsache, das Emulatorfreunde ganz oft elektrotechnischen oder hexkodierten Hintergrund haben. Heute ist der Hintergrund ein ganz anderer, darum gibt es z.B. auch so viele lustige in Java programmierte Emulatoren.

    Man könnte genausogut zurückfragen, warum wird heutzutage so viel und mainstreamig in Hochsprachen geschrieben (und warum in C (wie chaotisch) und nicht Pascal)?
    Die Intelplattform ist seit Jahren ziemlich die gleiche und die neueren Assembler sind recht trickreich und leistungsstark und die Assemblerprogrammierung ist ja nicht schwerer als Hochsprachenprogrammierung, sondern eher einfacher, wenn man mal von riesigen Bibliotheken, lizensierten Dokumentationen, Codierhilfsbücher usw. absieht.

    Zurückübersetzen:
    http://de.wikipedia.org/wiki/Decompiler
    Außerdem: Assemblercode kann man ziemlich gut warten, weil ja z.B. die Assemlerstruktur klar vor Augen liegt. In großen C oder anderen Hochsprachen-Programmen können viele Fehler gar nicht erst gefunden werden.
    Schwieriger wirds, wenn man extrem performant schreiben will. Da werden aber die meisten Programmiersprachcodes ziemlich unwartbar (sofern man das auf Codebasis lösen möchte und keinen weiteren, höher liegenden Ansatz (z.B. Algo) findet.

    Wurde leider aufgegeben:
    http://www.lowlevel.eu/wiki/Datei:Blue_Screen_V2OS.png



  • 8589934592 schrieb:

    hexkodierten Hintergrund

    😃
    $dff180 🕶



  • 8589934592 schrieb:

    Außerdem: Assemblercode kann man ziemlich gut warten, weil ja z.B. die Assemlerstruktur klar vor Augen liegt. In großen C oder anderen Hochsprachen-Programmen können viele Fehler gar nicht erst gefunden werden.

    The fail is strong with this one. 🙄



  • Gewisse Dinge lassen sich nur in ASM realisieren.
    Vor allem sehr hardwarenahe Sachen.

    Zum Beispiel muss das Betriebssystem in der Anfangsphase Paging (eine Form von virtuelle Speicher) aktivieren.

    mov eax, [page_directory]
     mov cr3, eax
    
     mov eax, cr0
     or eax, 0x80000000
     mov cr0, eax
    

    So etwas lässt sich in C nicht realisieren - denn dort hast du keinen direkten Zugriff auf Register.

    Außerhalb vom OS/Treiberbereich sehe ich heute aber wenig Einsatzgebiete für ASM.
    ASM zu verstehen ist gut, vor allem beim Debuggen haben mir halbwegs passable ASM Kenntnisse schon sehr geholfen.
    Dass ich aber tatsächlich in einer Firma ASM programmieren musste, ist mir noch nicht untergekommen.

    Aber weil du Audio erwähnst: Gerade DSP werden heute teilweise immer noch in ASM programmiert, um spezielle Prozessorfunktionen auszunutzen. Ansonsten fallen mir jetzt aber keine Jobbeschreibungen ein, wo ich mal was von ASM gekesen habe.



  • fsdfsdfsxxxx schrieb:

    So etwas lässt sich in C nicht realisieren - denn dort hast du keinen direkten Zugriff auf Register.

    Dafür schreibt man sich (in Assembler) kleine Hilfsfunktionen und macht den Rest dann in C(++).
    Das selbe Prinzip wie die ganze C(++) Standard-Library. In C gibt's nämlich auch keine "Befehle" um Files zu lesen/schreiben etc.



  • hustbaer schrieb:

    fsdfsdfsxxxx schrieb:

    So etwas lässt sich in C nicht realisieren - denn dort hast du keinen direkten Zugriff auf Register.

    Dafür schreibt man sich (in Assembler) kleine Hilfsfunktionen und macht den Rest dann in C(++).
    Das selbe Prinzip wie die ganze C(++) Standard-Library. In C gibt's nämlich auch keine "Befehle" um Files zu lesen/schreiben etc.

    eben - man verwendet ASM, von mir aus eben auch in Form von Inline ASM 😉

    Dateien schreiben/lesen macht sowieso das OS. Die C Funktionen wie fopen, fprintf, fclose usw... sind ohnehin nur ein Wrapper um die OS spezifischen Details. Bei Linux sind das dann die system calls wie open, close, read, write.
    Und die FILE Struktur wiederum muss sich in irgendeiner Form den file descriptor merken, welcher eine bestimmte geöffnete Datei repräsentiert.


Anmelden zum Antworten