x86,BYTE和BYTE PTR之间的区别

Lin*_*kas 19 x86 assembly

这两条线有什么区别?PTR在这里改变了什么?

;first
mov BYTE [ecx], 0  
;second
mov BYTE PTR [ecx], 0
Run Code Online (Sandbox Code Playgroud)

osg*_*sgx 14

摘要:

  • word [ecx]当其他操作数不暗示操作数大小时,NASM/YASM需要.(否则没问题[ecx]).
  • word ptr [ecx]当其他操作数不暗示操作数大小时,MASM/TASM需要.(否则没问题[ecx]).

他们每个人都扼杀了另一个人的语法.


警告:这是一个非常奇怪的区域,没有任何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
Run Code Online (Sandbox Code Playgroud)

我认为,还有汇编程序特定的要求(nasm/tasm/other asm)和"byte ptr"的使用更加便携.

另请参阅"印度书籍 "第4.2.16 节和" 汇编语言程序设计艺术 "中的第8.12.3节(和8.11.3"类型冲突").

更新:感谢Frank Kotler,似乎NASM"使用英特尔汇编语法的变体"(wiki),其中不包括PTR操作.

更新1:1981 - 1983年英特尔有原创的" ASM86语言参考手册 ",第4-15页定义了PTR操作员:

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
Run Code Online (Sandbox Code Playgroud)

此表单还可用于覆盖变量或标签的type属性.例如,如果您希望将已定义的单词变量作为两个字节访问,则可以编写以下代码:

MOV  CL, BYTE  PTR AWORD       ;get first byte
MOV  CL, BYTE  PTR AWORD + 1   ;get second byte
Run Code Online (Sandbox Code Playgroud)

字段值:

type此字段可以具有以下值之一:BYTE,WORD,DWORD,QWORD,TBYTE,NEAR,FAR

name此字段可以是:1.变量名称.2.标签名称.3.地址或寄存器表达式.4.表示偏移量的整数.

更新2:感谢斯图加特Uni of the bitaver!有微软(1981)的原始MACRO-86手册.第3-7页:

在使用前向引用时,可以使用PTR运算符以另一种方式保存自己的字节.如果您将FOO定义为前向常量,则可以输入以下语句:

MOV [BX],FOO
Run Code Online (Sandbox Code Playgroud)

您可能希望立即将FOO称为字节.在这种情况下,您可以输入任一语句(它们是等效的):

MOV BYTE PTR [BX],FOO

MOV [BX],BYTE PTR FOO
Run Code Online (Sandbox Code Playgroud)

这些语句告诉MACRO-86 FOO是一个字节立即.生成较小的指令.

和第3-16页:

覆盖运算符

这些运算符用于覆盖变量和标签的段,偏移量,类型或距离.

指针(PTR)

<attribute>  PTR  <expression>
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

阅读本文并从这些文档中查找一些语法定义后,我认为编写PTR是必需的.mov BYTE [ecx], 0根据MACRO-86手册,使用不正确.

  • Nasm将在'PTR`上扒.没有它,Masm/Tasm将会是barf. (7认同)

Han*_*ant 6

您正在使用一个允许的汇编程序,看起来,我的C编译器对内联汇编的支持肯定不满意.正确的语法是BYTE PTR告诉汇编器ECX寄存器中的值应该被视为指针.PTR.但是这个语法超出了指定范围,它已经可以告诉你,你想把它作为一个指针,你将[括号]放在寄存器名称周围.使用[ecx]已经明确表示您打算将零存储到ECX寄存器提供的地址中.

因此,它知道如何使用ECX寄存器,只它不知道的事情是需要多少字节设置为零.选择是1,2或4.你说清楚了,1.BYTE.