2012-12-09 128 views
16

這兩行有什麼區別? PTR有哪些變化?x86,BYTE和BYTE的區別PTR

;first 
mov BYTE [ecx], 0 
;second 
mov BYTE PTR [ecx], 0 
+9

有沒有區別。彙編程序只接受兩種不同的方言。 –

+0

對於x86彙編上的問題+1。和@AkiSuihkonen,看起來像一個答案,而不是一個評論。 –

+1

Linkas,並且在這個問題中缺少非常重要的細節:使用什麼彙編程序:MASM/TASM/NASM/YAMS或其他。以及它是如何使用的(在其中一些語言中有方言選項)。 – osgx

回答

12

總結:

  • NASM/YASM要求word [ecx]當操作數大小不是由另一個操作數暗示。 (否則[ecx]是好的)。
  • 當操作數大小不被其他操作數隱含時,MASM/TASM需要word ptr [ecx]。 (否則[ecx]是好的)。

他們每個都扼住對方的語法。


警告:這是非常奇怪的區域,沒有任何ISO標準或易於查找的BNF表;而且我不是走過專有MASM語法雷區的專家。

它的情況下,有可能是沒有什麼區別,但PTR操作員可以在其他情況下意味着:

http://www.c-jump.com/CIS77/ASM/Instructions/I77_0250_ptr_pointer.htm

In general, PTR operator forces expression to be treated as a pointer of specified type:

.DATA 
num DWORD 0 

.CODE 
mov  ax, WORD PTR [num] ; Load a word-size value from a DWORD 

我認爲,也有彙編器的特殊要求(NASM/tasm/other asm)和「byte ptr」的使用更便於攜帶。

在「的彙編語言編程藝術」另外,還要檢查節4.2.16在book from India和部分8.12.3(8.11.3和「衝突型」)。

更新:感謝Frank Kotler,似乎NASM「使用英特爾彙編語法的變體」(wiki),它不包括PTR操作。

UPDATE1:

PTR Operator

Syntax: type PTR name

Description: The PTR operator is used to define a memory reference with a certain type. The assembler determines the correct instruction to assemble based on the type of the operands to the instruction. There are certain instances where you may specify an operand that has no type. These cases involve the use of numeric or register expressions. Here the PTR operator is used to specify the type of the operand. The following examples illustrate this use:

MOV WORD PTR [BX], 5  ;set word pointed to by BX = 5 
INC DS:BYTE PTR 10   ;increment byte at offset 10 
           ;from DS 

This form can also be used to override the type attribute of a variable or label. If, for example, you wished to access an already defined word variable as two bytes, you could code the following:

MOV CL, BYTE PTR AWORD  ;get first byte 
MOV CL, BYTE PTR AWORD + 1 ;get second byte 

Field Values:

type This field can have one of the following values: BYTE, WORD, DWORD, QWORD, TBYTE, NEAR, FAR

name This field can be: 1. A variable name. 2. A label name. 3. An address or register expression. 4. An integer that represents an offset.

UPDATE2:由於有來自英特爾,1981-1983原始"ASM86 LANGUAGE REFERENCE MANUAL",PTR操作員是第4-15頁的定義斯圖加特的比特幣大學!有微軟公司的original MACRO-86 manual(1981)。第3-7頁:

The PTR operator can be used another way to save yourself a byte when using forward references. If you defined FOO as a forward constant, you might enter the statement:

MOV [BX],FOO 

You may want to refer to FOO as a byte immediate. In this case, you could enter either of the statements (they are equivalent):

MOV BYTE PTR [BX],FOO 

MOV [BX],BYTE PTR FOO 

These statements tell MACRO-86 that FOO is a byte immediate. A smaller instruction is generated.

和頁面3-16:

Override operators

These operators are used to override the segment, offset, type, or distance of variables and labels.

Pointer (PTR)

<attribute> PTR <expression> 

The PTR operator overrides the type (BYTE, WORD, DWORD) or the distance (NEAR, FAR) of an operand.

<attribute> is the new attribute; the new type or new distance.

<expression> is the operand whose attribute is to be overridden.

The most important and frequent use for PTR is to assure that MACRO-86 understands what attribute the expression is supposed to have. This is especially true for the type attribute. Whenever you place forward references in your program, PTR will make clear the distance or type of the expression. This way you can avoid phase errors.

The second use of PTR is to access data by type other than the type in the variable definition. Most often this occurs in structures. If the structure is defined as WORD but you want to access an item as a byte, PTR is the operator for this. However, a much easier method is to enter a second statement that defines the structure in bytes, too. This eliminates the need to use PTR for every reference to the structure. Refer to the LABEL directive in Section 4.2.1, Memory Directives.

Examples:

CALL WORD PTR [BX][SI] 
MOV BYTE PTR ARRAY, (something) 

ADD BYTE PTR FOO,9 

閱讀完本文後,從這些文檔看一些語法定義,我認爲寫PTR是強制性的。根據MACRO-86手冊,mov BYTE [ecx], 0的使用不正確。

+7

Nasm將在'PTR'上bar bar。 Masm/Tasm將會沒有它。 –

+0

@弗蘭克的評論應該真的是這裏的答案,而不是這個善意的混亂...... ;-)如果你不介意,這是一個相當常見的問題,所以它可能值得回去重寫/重新格式化這個答案的很大一部分(並且包括一個TL;最大清晰度的DR)。 –

+0

@Cody,嗨,其實我現在可以理解這個答案的任何內容(它更像我的個人筆記本,記錄一些有趣的古代/博物館手冊的URL)。你可以幫助編輯它,重寫它(可能轉換爲wiki)? – osgx

6

您使用的是寬容的彙編程序,看起來,我的C編譯器對內聯彙編的支持肯定是不滿意的。正確的語法是BYTE PTR告訴彙編器,ECX寄存器中的值應該像指針一樣對待。 PTR。但是,這是超過指定的的語法,它可能已經告訴你,你打算通過將[括號]放在寄存器名稱周圍作爲指針使用它。使用[ecx]已經明確指出,您的意思是將零存儲到ECX寄存器提供的地址中。

所以它知道如何使用ECX寄存器,只有其他的東西它不知道有多少字節需要設置爲零。選擇是1,2或4.你已經明確了,1. BYTE。

0

在MASM中,BYTE PTR [ecx]訪問地址爲ecx的存儲器。 BYTE [ecx]是語法錯誤(「第一個操作數中的內聯彙編語法錯誤;找到'['」)。

在NASM或YASM中,BYTE [ecx]訪問地址爲ecx的內存。 BYTE PTR [ecx]是語法錯誤(在NASM中爲「錯誤:逗號,冒號或行結束符」,YASM中的未定義符號「PTR」)。

在TASM中,BYTE PTR [ecx]和BYTE [ecx]是等效的 - 兩個訪問存儲器都在地址ecx處。但是,在Gnu彙編語氣中,當使用intel語法時,BYTE PTR [ecx]在ecx訪問內存,但BYTE [ecx]實際訪問地址爲ecx + 1的內存。也就是說,BYTE [ecx]相當於BYTE PTR [ecx + 1],它看起來既不健全也不記錄。

GNU彙編版本2.18,2.24,或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 
+1

在GNU彙編器中,標識符BYTE,WORD,DWORD是也像定義1,2,4'movb BYTE [ecx],0'實際上與'movb 1 [ecx],0'一樣,它是'mov BYTE PTR [ecx + 1],0'。 'movb WORD [ecx],0'與'movb 2 [ecx],0'或'mov BYTE PTR [ecx + 2],0'相同。 'mov eax,WORD'與'mov eax,2'相同。 'mov eax,BYTE'和'mov eax,1'等一樣。 –

+0

有趣,謝謝! 「mov ecx,BYTE」是NASM,MASM和TASM中的語法錯誤,但不是氣。 –