Was ist der Unterschied zwischen diesen beiden Linien? Welche PTR ändert sich hier?
;first
mov BYTE [ecx], 0
;second
mov BYTE PTR [ecx], 0
Zusammenfassung:
Word [ecx]
, wenn die Operandengröße nicht vom anderen Operanden übernommen wird. (Ansonsten ist [ecx]
in Ordnung).Word ptr [ecx]
, wenn die Operandengröße nicht vom anderen Operanden übernommen wird. (Ansonsten ist [ecx]
in Ordnung).Sie ersticken an der Syntax des anderen.
WARNUNG: Dies ist ein sehr ungewöhnlicher Bereich ohne ISO-Standards oder leicht zu findende BNF-Tabellen. Ich bin kein Experte, wenn ich durch die Minenfelder der proprietären MASM-Syntax gehe.
In Ihrem Fall gibt es keinen Unterschied, aber der PTR-Operator kann in anderen Fällen Folgendes bedeuten:
http://www.c-jump.com/CIS77/ASM/Instructions/I77_0250_ptr_pointer.htm
Im Allgemeinen erzwingt der PTR-Operator, dass der Ausdruck als Zeiger des angegebenen Typs behandelt wird:
.DATA
num DWORD 0
.CODE
mov ax, Word PTR [num] ; Load a Word-size value from a DWORD
Ich denke, es gibt auch Assembler-spezifische Anforderungen (nasm/tasm/other asm) und die Verwendung von "byte ptr" ist tragbarer.
Siehe auch Abschnitt 4.2.16 in Buch aus Indien und Abschnitte 8.12.3 (und 8.11.3 "Typkonflikte") in "Die Kunst der Assembler-Sprachprogrammierung" .
UPDATE: Dank Frank Kotler scheint NASM "eine Variante der Intel Assembly-Syntax" (Wiki) zu verwenden, die keine PTR-Operation enthält.
UPDATE1: Es gibt Original "ASM86-SPRACHE-REFERENZHANDBUCH" von Intel, 1981-1983, PTR-Operator ist auf Seite 4-15 definiert:
PTR-Operator
Syntax: Geben Sie den PTR-Namen ein
Beschreibung: Mit dem PTR-Operator wird eine Speicherreferenz mit einem bestimmten Typ definiert. Der Assembler bestimmt die richtige Anweisung zum Assemblieren basierend auf dem Typ der Operanden für die Instruktion. In bestimmten Fällen können Sie einen Operanden angeben, der keinen Typ hat. In diesen Fällen werden numerische Ausdrücke oder Registerausdrücke verwendet. Hier wird der PTR-Operator verwendet, um den Typ des Operanden anzugeben. Die folgenden Beispiele veranschaulichen diese Verwendung:
MOV Word PTR [BX], 5 ;set Word pointed to by BX = 5
INC DS:BYTE PTR 10 ;increment byte at offset 10
;from DS
Dieses Formular kann auch verwendet werden, um das type-Attribut einer Variablen oder eines Labels zu überschreiben. Wenn Sie beispielsweise auf eine bereits definierte Word-Variable als zwei Bytes zugreifen möchten, können Sie Folgendes eingeben:
MOV CL, BYTE PTR AWORD ;get first byte
MOV CL, BYTE PTR AWORD + 1 ;get second byte
Feldwerte:
type Dieses Feld kann einen der folgenden Werte annehmen: BYTE, Word, DWORD, QWORD, TBYTE, NEAR, FAR
name Dieses Feld kann Folgendes sein: 1. Ein Variablenname. 2. Ein Labelname. 3. Eine Adresse oder ein Registerausdruck. 4. Eine Ganzzahl, die einen Versatz darstellt.
UPDATE2: Danke an die Bitsaver von Uni von Stuttgart! Es gibt originales MACRO-86-Handbuch von Microsoft (1981). Seite 3-7:
Der PTR-Operator kann auf andere Weise verwendet werden, um sich bei Verwendung von Forward-Referenzen ein Byte zu sichern. Wenn Sie FOO als Vorwärtskonstante definiert haben, können Sie die Anweisung eingeben:
MOV [BX],FOO
Möglicherweise möchten Sie FOO als ein Byte unmittelbar bezeichnen. In diesem Fall können Sie eine der folgenden Anweisungen eingeben (sie sind gleichwertig):
MOV BYTE PTR [BX],FOO
MOV [BX],BYTE PTR FOO
Diese Anweisungen teilen MACRO-86 mit, dass es sich bei FOO um ein Byte handelt. Eine kleinere Anweisung wird generiert.
Und Seite 3-16:
Operatoren überschreiben
Diese Operatoren werden verwendet, um das Segment, den Versatz, den Typ oder den Abstand von Variablen und Beschriftungen zu überschreiben.
Zeiger (PTR)
<attribute> PTR <expression>
Der PTR-Operator überschreibt den Typ (BYTE, Word, DWORD) oder die Entfernung (NEAR, FAR) eines Operanden.
<attribute>
ist das neue Attribut; der neue Typ oder die neue Entfernung.
<expression>
ist der Operand, dessen Attribut überschrieben werden soll.Die wichtigste und häufigste Verwendung von PTR ist es sicherzustellen, dass MACRO-86 versteht, welches Attribut der Ausdruck haben soll. Dies gilt insbesondere für das type-Attribut. Wenn Sie in Ihrem Programm Vorwärtsverweise setzen, macht PTR die Entfernung oder den Typ des Ausdrucks deutlich. Auf diese Weise können Sie Phasenfehler vermeiden.
Die zweite Verwendung von PTR ist der Zugriff auf Daten nach Typ, der nicht der Typ in der Variablendefinition ist. Meistens tritt dies in Strukturen auf. Wenn die Struktur als Word definiert ist, Sie jedoch als Byte auf ein Element zugreifen möchten, ist PTR der Operator dafür. Eine wesentlich einfachere Methode ist jedoch die Eingabe einer zweiten Anweisung, die die Struktur auch in Bytes definiert. Dadurch entfällt die Verwendung von PTR für jeden Verweis auf die Struktur. Weitere Informationen finden Sie in der LABEL-Direktive in Abschnitt 4.2.1, Speicherrichtlinien.
Beispiele:
CALL Word PTR [BX][SI]
MOV BYTE PTR ARRAY, (something)
ADD BYTE PTR FOO,9
Nachdem ich dies gelesen und einige Syntaxdefinitionen aus diesen Dokumenten betrachtet habe, denke ich, dass das Schreiben von PTR zwingend ist. Die Verwendung von mov BYTE [ecx], 0
ist gemäß MACRO-86-Handbuch nicht korrekt.
Sie verwenden einen permissiven Assembler, es scheint, die Unterstützung meines C-Compilers für Inline-Assembly ist damit nicht zufrieden. Die richtige Syntax ist BYTE PTR, um dem Assembler mitzuteilen, dass der Wert im ECX-Register wie ein Zeiger behandelt werden soll. PTR. Aber das ist die Syntax, die über spezifiziert ist , sie konnte bereits erkennen, dass Sie sie als Zeiger verwenden wollten, indem Sie [Klammern] um den Registernamen setzen. Durch die Verwendung von [ecx] wurde bereits klargestellt, dass Sie die Null in der vom ECX-Register angegebenen Adresse speichern wollten.
Es weiß also, wie man das ECX-Register verwendet, die einzige andere Sache, die es nicht weiß, ist, wie viele Bytes auf Null gesetzt werden müssen. Zur Auswahl stehen 1, 2 oder 4. Sie haben klar gemacht, 1. BYTE.
In MASM greift BYTE PTR [ecx] unter der Adresse ecx auf den Speicher zu. BYTE [ecx] ist ein Syntaxfehler ("Inline-Assembler-Syntaxfehler in 'erster Operand'; gefunden '['")).
In NASM oder YASM greift BYTE [ecx] auf den Speicher unter Adresse ecx zu. BYTE PTR [ecx] ist ein Syntaxfehler ("Fehler: Komma, Doppelpunkt oder Zeilenende erwartet" in NASM, "undefined Symbol" PTR "" in YASM).
In TASM sind BYTE PTR [ecx] und BYTE [ecx] gleichwertig - beide greifen auf Speicher an der Adresse ecx zu.
Im Gnu-Assembler-Gas greift BYTE PTR [ecx] bei Verwendung der Intel-Syntax jedoch auf Speicher bei ecx zu, aber BYTE [ecx] greift tatsächlich auf Speicher unter Adresse ecx + 1 zu. Das heißt, BYTE [ecx] ist gleichbedeutend mit BYTE PTR [ecx + 1], das weder als gesund noch als dokumentiert erscheint.
Gnu Assembler Version 2.18, 2.24 oder 2.26.1:
cat > foo.S << EOF
.intel_syntax noprefix
movb BYTE [ecx], 0
movb BYTE PTR [ecx], 0
.att_syntax prefix
EOF
as foo.S
objdump -dM intel a.out
0: 67 c6 41 01 00 mov BYTE PTR [ecx+0x1],0x0
5: 67 c6 01 00 mov BYTE PTR [ecx],0x0