概括:
- NASM/YASM 要求
word [ecx]
当另一个操作数未隐含操作数大小时。 (否则[ecx]
is ok).
- MASM/TASM 要求
word ptr [ecx]
当另一个操作数未隐含操作数大小时。 (否则[ecx]
is ok).
他们都被对方的语法所窒息。
警告:这是一个非常奇怪的领域,没有任何 ISO 标准或易于找到的 BNF 表;我并不是穿越专有 MASM 语法雷区的专家。
如果您的情况可能没有区别,但 PTR 运算符在其他情况下可能意味着:
http://www.c-jump.com/CIS77/ASM/Instructions/I77_0250_ptr_pointer.htm
一般来说,PTR 运算符强制表达式被视为指定类型的指针:
.DATA
num DWORD 0
.CODE
mov ax, WORD PTR [num] ; Load a word-size value from a DWORD
我认为,还有汇编程序的特定要求(nasm/tasm/其他 asm),并且使用“byte ptr”更便携。
另请检查第 4.2.16 节来自印度的书和部分8.12.3(和 8.11.3“类型冲突”)在“汇编语言编程的艺术".
更新:感谢 Frank Kotler,似乎 NASM“使用 Intel 汇编语法的变体”(wiki),其中不包括 PTR 操作。
UPDATE1:有原始的"ASM86 语言参考手册"来自 Intel,1981-1983,PTR 运算符在第 4-15 页定义:
PTR操作员
语法:键入 PTR 名称
说明: PTR 运算符用于定义某种类型的内存引用。汇编器根据指令操作数的类型确定要汇编的正确指令。在某些情况下,您可以指定没有类型的操作数。这些情况涉及数字或寄存器表达式的使用。这里PTR运算符用于指定操作数的类型。以下示例说明了这种用法:
MOV WORD PTR [BX], 5 ;set word pointed to by BX = 5
INC DS:BYTE PTR 10 ;increment byte at offset 10
;from DS
此形式还可用于覆盖变量或标签的类型属性。例如,如果您希望以两个字节的形式访问已定义的字变量,则可以编写以下代码:
MOV CL, BYTE PTR AWORD ;get first byte
MOV CL, BYTE PTR AWORD + 1 ;get second byte
字段值:
类型 该字段可以具有以下值之一:BYTE、WORD、DWORD、QWORD、TBYTE、NEAR、FAR
name 该字段可以是: 1. 变量名。 2. 标签名称。 3. 地址或寄存器表达式。 4. 表示偏移量的整数。
UPDATE2:感谢斯图加特大学的bitsaver!有原版 MACRO-86 手册来自微软(1981)。第 3-7 页:
在使用前向引用时,可以使用 PTR 运算符的另一种方式来节省字节。如果将 FOO 定义为前向常量,则可以输入以下语句:
MOV [BX],FOO
您可能希望将 FOO 称为字节立即数。在这种情况下,您可以输入任一语句(它们是等效的):
MOV BYTE PTR [BX],FOO
MOV [BX],BYTE PTR FOO
这些语句告诉 MACRO-86 FOO 是一个字节立即数。生成更小的指令。
第 3-16 页:
覆盖运算符
这些运算符用于覆盖变量和标签的段、偏移、类型或距离。
指针(PTR)
<attribute> PTR <expression>
PTR 运算符会覆盖操作数的类型(BYTE、WORD、DWORD)或距离(NEAR、FAR)。
<attribute>
是新属性;新类型或新距离。
<expression>
是其属性要被覆盖的操作数。
PTR 最重要和最频繁的用途是确保 MACRO-86 理解表达式应该具有什么属性。对于 type 属性尤其如此。每当您在程序中放置前向引用时,PTR 都会明确表达式的距离或类型。这样您就可以避免相位错误。
PTR 的第二个用途是按变量定义中类型以外的类型访问数据。这种情况最常发生在结构中。如果结构定义为 WORD 但您想要以字节形式访问项目,则 PTR 是该操作的运算符。然而,更简单的方法是输入第二条语句,该语句也以字节为单位定义结构。这消除了对结构的每次引用都使用 PTR 的需要。请参阅第 4.2.1 节“内存指令”中的 LABEL 指令。
例子:
CALL WORD PTR [BX][SI]
MOV BYTE PTR ARRAY, (something)
ADD BYTE PTR FOO,9
阅读本文并查看这些文档中的一些语法定义后,我认为编写 PTR 是强制性的。的用法mov BYTE [ecx], 0
根据 MACRO-86 手册,这是不正确的。