2017-07-16 2 views
4

MASM bietet eine SEGMENT-Direktive. Die Richtlinie benötigt mehrere Parameter. Der Parameter use kann einen Wert annehmen. Es ist mir unklar, was dieser Wert bewirkt.Auswirkungen des FLAT-Operanden auf die SEGMENT-Direktive?

Die Microsoft docs es als akzeptierte Wert angeben, aber keinen Versuch machen, um es zu beschreiben:

use
USE16, USE32, FLAT

Das Buch The Art of Assembly Language Programming online es erwähnt, aber es nennt Umfang aus und empfiehlt die MASM Programmierhandbuch zu lesen:

Im MASM 6.1 Programmer's Guide von Microsoft, in dem Abschnitt, der die SEGMENT Direktive beschreibt, wird der Wert erwähnt, aber seine Auswirkungen werden nie beschrieben:

The size attribute can be USE16, USE32, or FLAT.

Was sind die Auswirkungen des FLAT Operanden an die SEGMENT Richtlinie?

+0

Kennen Sie die 16-Bit-Segmentierung? Alle wichtigen 32-Bit- und 64-Bit-Betriebssysteme verwenden ein flaches Speichermodell, anstatt unterschiedliche Basen für unterschiedliche Segmentregister zu verwenden. IDK was genau bedeutet dieses Schlüsselwort in MASM, aber vielleicht haben Sie Probleme mit dem Handbuch, wenn Sie nichts über die Segmentierung wissen? –

+0

Danke @PeterCordes. Ich kenne segmentierte und flache Speichermodelle. In MASM gibt es eine ".MODEL FLAT" -Richtlinie, um das flache Modell zu aktivieren. Ich bin mir nicht sicher, wann Sie 'FLAT' für einzelne' SEGMENT'-Anweisungen verwenden würden. – Lycan

+1

IDK entweder, aber ich hatte glücklicherweise nie Code für ein segmentiertes Speichermodell schreiben (außer Spielzeug SO Antworten), oder sogar MASM verwenden: P Jetzt bin ich auch neugierig auf diese Frage. MASM macht eine Menge "magischer" Schlüsse von Dingen, also ist es wahrscheinlich etwas seltsam. –

Antwort

4

Für die meisten Zwecke hat das Schlüsselwort FLAT, wenn es in einer Segmentrichtlinie verwendet wird, dieselbe Bedeutung wie USE32. Sowohl die USE32- als auch die FLAT-Schlüsselwörter geben an, dass das Segment größer als 64 KB sein kann und dass alle in dem Segment zusammengesetzten Anweisungen eine 32-Bit-Codierung anstelle einer 16-Bit-Codierung verwenden sollten. Der Unterschied ist, was der Assembler über das CS-Register annimmt. Normalerweise führt eine SEGMENT-Direktive zu einer impliziten ASSUME CS:xxx Direktive, wobei xxx der Name des Segments ist, aber mit FLAT ergibt sich eine implizite ASSUME CS:FLAT.

Die Anweisung ASSUME teilt dem Assembler mit, welche Segmente in welches Segmentregister geladen werden, so dass automatisch die richtigen Segmentüberschreibungen verwendet werden können, wenn dies erforderlich ist. In dem flachen Speichermodell, das von den meisten 32-Bit-Betriebssystemen verwendet wird, gibt es nur ein einziges 4-Gigabyte-Segment. Wenn dem Assembler mitgeteilt wird, dass er ein Segmentregister annehmen kann, teilt FLAT dem Assembler mit, dass auf alle im Programm definierten Segmente über dieses Segmentregister zugegriffen werden kann. Zum Beispiel sagt ASSUME DS:FLAT, dass alle Segmente über das DS-Register zugegriffen werden können. Auf der anderen Seite sagt ASSUME DS:_DATA, dass das DS-Register nur für den Zugriff auf das _DATA-Segment und nicht für ein anderes Segment verwendet werden kann.

Sie dieses Verhalten durch den Zusammenbau den folgenden Code sehen:

_DATA SEGMENT PUBLIC USE32 
var DD ? 
_DATA ENDS 

_TEXT SEGMENT PUBLIC PARA 'CODE' FLAT 

    mov eax, [zero] 
    mov [var],eax 

    ASSUME DS:FLAT 

    mov eax, [zero] 
    mov [var],eax 

    ASSUME CS:_TEXT 
    ASSUME DS:_DATA 

    mov eax, [zero] 
    mov [var],eax 

zero DD 0 

_TEXT ENDS 

    END 

Wenn Sie das resultierende Objekt-Datei zerlegen sehen Sie dies für die ersten beiden Anweisungen:

00000000: 2E A1 00 00 00 00 mov   eax,dword ptr cs:[zero] 
    00000006: 2E A3 00 00 00 00 mov   dword ptr cs:[var],eax 

Für diese beiden Anweisungen der Der Assembler muss das CS-Segment-Override (2E) verwenden, um auf zero und var zuzugreifen. Denn während der Assembler weiß, dass CS für den Zugriff auf alle Segmente verwendet werden kann, einschließlich _TEXT und _DATA, weiß er nicht, dass ein anderes Segmentregister für den Zugriff auf diese Semgents verwendet werden kann.

Hier ist der Code für die nächsten zwei Befehle erzeugt, nach der ASSUME DS:_FLAT Richtlinie:

0000000C: A1 00 00 00 00  mov   eax,dword ptr [zero] 
    00000011: A3 00 00 00 00  mov   dword ptr [var],eax 

nun der Monteur weiß, dass beide CS und DS verwendet werden können, um alle Segmente zuzugreifen.Da die Verwendung von DS für den Zugriff auf zero und var keine Segmentüberschreibung erfordert, wird DS anstelle von CS verwendet, was zu kürzeren Anweisungen führt.

schließlich die letzten beiden Anweisungen, nach den ASSUME DS:_DATA und ASSUME CS:_TEXT Richtlinien zeigen die Assemblercode generieren würde, wenn das FLAT Schlüsselwort überhaupt nicht verwendet wird:

00000016: 2E A1 00 00 00 00 mov   eax,dword ptr cs:[zero] 
    0000001C: A3 00 00 00 00  mov   dword ptr [var],eax 

In diesem Fall wird der Assembler übernimmt CS kann nur verwendet werden, um auf _TEXT zuzugreifen, und DS nur, um auf _DATA zuzugreifen. Er muss eine CS-Überschreibung verwenden, um auf zero zuzugreifen, während er nur über DS auf var zugreifen kann, was keine Segmentüberschreibung erfordert.

Hinweis, wenn Sie die Wohnung zu USE32 in der SEGMENT-Richtlinie in dem obigen Code dann erste Anweisung Beispiel ändern endet eine CS Überschreibung verwendet wird, aber der zweite Befehl erzeugt die folgenden Fehler:

error A2074:cannot access label through segment registers 

das, weil während ist Der Assembler weiß, dass er über das CS-Register auf _TEXT zugreifen kann, er kennt kein Segmentregister, das er für den Zugriff auf _DATA verwenden kann.

Wenn Sie die .MODEL FLAT Direktive zu Beginn Ihres Codes verwenden, sollten Sie sich darüber keine Sorgen machen. Dann haben USE32 und FLAT genau denselben Effekt in den Segment-Direktiven, da jedes Segmentregister als FLAT angenommen wird.

Verwandte Themen