Frage

Ich kann etwas nicht verdauen. Ich lerne einen Assembler und gerade jetzt im Kapitel mit Adressierung. Ich verstehe das Konzept der Klammern für Derference, aber irgendwie kann ich den Sinn davon einfach nicht aufwecken. Um ein bisschen genauer zu sein, begann meine Verwirrung:

mov al, [L1]

Ich nehme an, L1 als Beispiel ist ein Makro, der später eine echte Adresse im Maschinencode ersetzt, oder?

Also, was diese Anweisung tut, ist: Dereferenzierung al Registrieren Sie sich (weil Sie die physische Adresse kaum ändern können) und den Wert auf den gespeicherten bei ändern L1.

Wenn bis jetzt alles in Ordnung ist:

mov [L1], al

Das würde Analogie bedeuten, es muss eine Adresse gespeichert sein (also gab es einen Sinn, dies zu tun), und Sie ändern sie an einen anderen Ort im Speicher, oder?

Wenn Sie mir nur sagen könnten, dass es in Ordnung ist, falls Sie keine Fehler sehen, können Sie es bitte ermöglichen, dass ich weiter lernen kann.

Eine letzte Sache, Nasm fügt ein paar 0xAA55 Unter meinem Code (diese Sequenz soll das Programm richtig beenden?), Warum ist es so oft da?

War es hilfreich?

Lösung

L1 ist typisch/wahrscheinlich a Etikett, mit einer bestimmten Adresse im Speicher verbunden. Der Programmierer definiert verschiedene Etiketten für seine Bequemlichkeit, und solche Beschriftungen werden verwendet, um einen bestimmten Ort im Speicher symbolisch darzustellen (L1 ist ein miese Name; Etiketten sind in der Regel auf den zugrunde liegenden Zweck des Ortes hin: beispielsweise, Pingcounter, Fehler, Login, Login und dergleichen).

Ein Etikett für 1 Byte statischer Speicher ist, wie ein C -Compiler implementiert wird char L1; bei Global Scope.


In Nasmsyntax, mov edi, L1 wird sich zu der versammeln mov eax, imm32 Form von mov, IE Die Label-Adresse wird zu einem 32-Bit-Sofort im Maschinencode. (Der Assembler kennt den endgültigen numerischen Wert nicht, aber der Linker.) Vorsicht, dass dies in der Masm -Syntax eine Last wäre und Sie brauchen würden mov edi, OFFSET L1 Um eine Label -Adresse als unmittelbar zu erhalten.

Aber mov al, [L1] Vergrößert sich zu einer anderen Anweisung, wobei die 32-Bit-Adresse in den Maschinencode als Adresse eingebettet ist. Diese Anweisung lädt 1 Byte aus der Adresse L1 und platziert sie in Al.

In der Montagesprache wird dieser indirekte Adressierungsmodus durch die Quadratklammung der Quelle oder des Zielbetriebs einer bestimmten Anweisung bestimmt. (Aber nicht beide: x86 unterstützt nur höchstens einen explizite Speicheroperanden pro Anweisung.)

mov al, [L1]

Verwendet die in L1 gespeicherte Adresse, um einen Ort im Speicher zu finden, und liest 1 Byte (= 8 Bits = die Größe des Al -Registers) an diesem Ort und lädt sie in das Al -Register.

  mov [L1], al

Tut dies umgekehrt. Insbesondere lesen Sie die in L1 gespeicherte Adresse, verwenden Sie diese Adresse, um einen bestimmten Ort im Speicher zu finden, und speichert den Inhalt des Al -Registers dort.


Vorausgesetzt, Sie verstehen die folgenden Informationen als unvollständig und in Bezug auf die neueren Prozessoren in der X86 -Familie etwas veraltet. Grundierung auf der 8086 Architektur ist wahrscheinlich sehr nützlich, um einen mit der Montagesprache für die X86 -Familie zu beginnen.
Der Vorteil des Beginns dieser "Antike einer CPU" (tatsächlich noch in Gebrauch) besteht darin, dass die grundlegenden Konzepte alle da sind, die von den neueren Registern, ausgefallenen Adressierungsmodi, Betriebsmodi und anderen Konzepten nicht belastet sind. Die größeren Größen, Merkmale und Modi des neueren CPUs führen lediglich eine kombinatorische Explosion von Optionen ein (die meisten?) Auf ihre Weise nützlich, aber im Wesentlichen irrelevant für eine Initiierung.

Andere Tipps

Es ist schwer, Ihrer Frage zu folgen, aber ich werde versuchen, zu helfen.

In der Montage ist ein Symbol nur ein Name für eine Adresse. In Ihrer Montagequelle ist L1 ein Symbol, das an anderer Stelle definiert ist, das der Assembler als Offset für den Speicher auflöst.

Wenn Sieseferencing (unter Verwendung der [] Notation), können Sie ein Register (wie in "moval, [esi]) oder eine Adresse (wie in "moval, [l1]) Dereference (wie in "moval, [Esi]) Dereference. Beide Aussagen tun dasselbe. Der einzige Unterschied besteht darin, dass die Adresse stammt.

Ich empfehle das Herunterladen der Intel CPU -Dokumentation und durch die Anweisungsreferenz überfliegen. Wenn Sie nicht überfordert sein möchten, lesen Sie von einem älteren X86 -Prozessor (z. B. 486 oder älter), diese Dokumentation ist nicht genau freundlich, aber es ist sehr nützlich, zur Hand zu haben.

Ich kenne die Besonderheiten von Nasm nicht, ich habe die Versammlung vor 15 Jahren mit Turbo Assembler gelernt, und dieses Wissen ist heute noch nützlich :)

Könnte ich auch vorschlagen, dass Sie versuchen, nach "X86 -Assembly -Tutorial" zu googeln, werden Sie eine zahlreiche relevante Dokumentation finden, die für Sie möglicherweise nützlich sein kann.

Oh und eine letzte Sache, Nasm fügt unter meinem Code eine Reihe von 0xaa55 hinzu (diese Sequenz soll das Programm richtig beenden?), Warum ist es so oft da? Vielen Dank, dass Sie es hier gelesen haben.

Ich bin mir ziemlich sicher, dass das nur dann anwendbar ist, wenn Sie einen Bootloader erstellen. Es ist die "Boot -Signatur". Angenommen, Sie schreiben diesen Code in einen Floppy (ist Ihr produzierter Maschinencode auch genau 512 Bytes?). Wenn Sie den Computer mit diesem Bootloader -Code starten möchten, wird das BIOS den Floppy betrachtet und feststellt, ob es sich um einen tatsächlichen Bootloader handelt. Da 0xAA55 Um anzuzeigen, dass es bootfähig ist.

In Ihrem Quellcode ist wie die letzte Zeile so etwas wie $(times.. db 0xAA55 oder sowas ähnliches? Wenn Sie nicht beabsichtigt, einen Bootloader zu erstellen, können Sie diese Linie effektiv entfernen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top