Frage zu sub und mov auf x86



  • Hi!

    Um das Innenleben meines PCs etwas besser zu verstehen beschäftige ich mich gerade mit Assemblern. Ich habe ein kleines PRogramm geschrieben was einen array füllt und einige Daten rauslöscht. In C++ nichts großartiges 😉
    Hier der Anfang vom Assembler:

    <main+0>:	push   %rbp							#legt das BP(Base Pointer-> Zeiger auf aktuellen Stackframe) Register auf den Stack
    <main+1>:	mov    %rsp,%rbp					#legt den BP in den SP(Stack Pointer -> Zeiger auf aktuelle Stackspitze)
    <main+4>:	sub    $0x198,%rsp					#SP - 0x198 (408 in dec)
    <main+11>:	mov    %edi,-0x204(%rbp)
    

    Dazu ein paar Fragen:
    - Wie darf ich die Anweisung "sub $0x198,%rsp" verstehen? Eigentlich doch $0x198 = $0x198 - SP, aber was ist $0x198? Ich kenne den Präfix "$0x" nur so, dass die nachfolgende Zahl Hexadezimal interpretiert wird, aber dann würde ich ja eigentlich in einer Konstanten speichern....
    - -0x204(%rbp) bedeutet, dass ich vom Inhalt des BP Registers 0x204 abziehe bevor dann der mov Befehl zum tragen kommt oder?
    - Für mein eigenes Verständnis:
    BP (Base Pointer) zeigt immer auf das unterste Element des aktuellen Stackframes und SP immer auf das oberste Element des Stackframes. D.h. wenn noch nichts im aktuellen Stackframe liegt zeigen BP und SP auf die gleiche Stelle oder?



  • 1. Bei AT&T-Syntax Assembler ist die Reihenfolge der Operanden gegenueber Intel-Syntax genau vertauscht. Dh. idR. steht als 1. die Quelle und 2. das Ziel.
    $ kennzeichnet AFAIR direkte Operanden.
    2. Jo. Natuerlich wird das Ergebnis dieser Subtraktion nicht in rbp gespeichert.
    3. rbp ist erstmal eigentlich einfach nur ein weiteres (Allzweck)register.
    Es adressiert normalerweise mit ss, weshalb die Verwendung zur Adressierung von Stack-Frames praktisch ist. Da passiert aber nichts automatisch. Welche Werte rbp wann wo hat haengt allein von dir als Programmierer, bzw. dem verwendeten Compiler ab. Da rbp am Anfang von Funktionen mit Stackframe idR. erstmal auf rsp gesetzt wird, hast du im Prinzip recht. Nur dass rbp dann nicht auf das "unterste" Element des Stack frames zeigt, sondern eins darunter (ich zaehle das idR. an dieser Stelle gesicherte alte rbp nicht zum eigentlichen Stack Frame).



  • Hmm gibt es irgendwo im Netz ein gescheihtes Tutorial oder Ähnliches was eine gute (und damit auch relativ vollständige) Einführung in (aktuelle) Assembler bringt?
    Also zu MIPS z.B: als "Beispiel"-Assembler findet man ja recht viel, nur wirklich umfassendes zum Intel x86 kaum. Entweder ist es veraltet oder enthält solche kleine Tricks und Kniffe wie Vertauschung von Ziel/Quelle nicht.
    Das einzige richtig gute bisher was ich gefunden habe ist: http://andremueller.gmxhome.de/
    Nur dort steht auch unter "Subtraktion" im Grundlagentutorial "sub Ziel, Quelle".
    Also schon klar, dass ich um wirklich etwas umfassendes zu haben ich wahrscheinlich etwas Geld für ein Buch ausgeben muss, aber gibt es nicht irgendwas was erstmal als gute Einführung reicht.
    So Begriffe wie direkte Operanden und so zu googlen und was genau was bedeutet ist recht mühselig bzw. fast unmöglich, da ich einige Begriffe gar nicht kenne.

    Dabei wären wir auch bei meiner nächsten Frage: Kann mir jemand bestätigen was $ nun genau bedeutet und was mit direkte Operanden (sofern es dafür das Zeichen ist) genau auf sich hat?

    EDIT: In welchem Register wird eigentlich die Subtraktion bei "mov %edi,-0x204(%rbp)" gespeichert? Die muss doch irgendwo zwischengespeichert werden.



  • Das mit "Ziel und Quelle vertauschen" ist kein Trick, sondern einfach ein Unterschied zwischen Intel- und AT&T-Syntax. Das sind einfach 2 verschiedene Assembler-"Dialekte". vgl. hier.
    Dein Tutorial verwendet offenbar die eine, dein Code die andere Syntax.
    Merke: Wenn in einem Tutorial oder Buch eine bestimmte Toolchain verwendet wird, tut man gut daran, das ebenfalls zu tun. 😃

    Veraltet oder aktuell ist zum Einstieg in Assembler IMHO erstmal egal. Bist du mit dem Prinzip eines Assemblers fit, solltest du dich ohne grosse Muehe auch in andere Assembler, Syntax und Architekturen einarbeiten koennen (zB. mit knapp gehaltenen speziellen Uebersichten, Beispielcodes oder einfach mit der Dokumentation des Assemblers, bzw. Ziel-CPU).
    Womit du also als absoluter Anfaenger einsteigst ist im Prinzip egal. Mit einem FrickelMonster wie aktuellen PC-CPU machst du dir den Einstieg nur unnoetig schwer: Wie du schon festgestellt hast, gibt es wenig uebersichtliche Einsteigerliteratur, was nicht zuletzt damit zu tun hat, das aktuelle PC-CPU einfach nicht uebersichtlich sind. 😉

    Um es kurz zu machen -
    Mein Tipp waere, du nimmst dir ein einfaches Einsteigertutorial. Am ehesten verfuegbar und umsetzbar auf PC ist wohl eins fuer x86, DOS. zB. das von Thomas Peschko - siehe diesen Beitrag oder FAQ (deins ist da auch AFAIR auch verlinkt - sollte fuer den Einstieg auch nicht schlecht sein - sobald du passende Werkzeuge benutzt).
    Falls du Probleme hast, an einen TASM zu kommen: Sollte auch mit dem NASM (link dazu steht auch in den FAQ) im TASM-Modus und einem Linker, der 16Bit-DOS-Programme erstellen kann, klappen.

    edit:

    Pille456 schrieb:

    Dabei wären wir auch bei meiner nächsten Frage: Kann mir jemand bestätigen was $ nun genau bedeutet und was mit direkte Operanden (sofern es dafür das Zeichen ist) genau auf sich hat?

    Kann dir zwar nicht sagen, was genau sich die AT&T-Leute bei diesem $ gedacht haben, aber sobald du in einem Befehl eine einzelne Konstante als Quell-Operanden verwendest, musst du ein $ vor die folgende Zahl schreiben. Solche Konstanten nennt man dann auch "immediates" oder direkte Operanden.
    ...Aehnlich wie das % vor Registern.

    Pille456 schrieb:

    In welchem Register wird eigentlich die Subtraktion bei "mov %edi,-0x204(%rbp)" gespeichert? Die muss doch irgendwo zwischengespeichert werden.

    An solche Zwischenergebnisse kommst du nicht ran.
    Darueber, wo das also so CPU-Intern evtl. zwischengespeichert, brauchst du dir nur Gedanken machen, wenn du eine x86-CPU entwerfen, nicht wenn du sie nur programmieren willst. 🙂




Anmelden zum Antworten