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.
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? –
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
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. –