2012-12-09 58 views
16

Sự khác biệt giữa hai dòng này là gì? Những gì PTR thay đổi ở đây?x86, sự khác biệt giữa BYTE và BYTE PTR

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

Không có sự khác biệt. Người lắp ráp chỉ chấp nhận hai phương ngữ khác nhau. –

+0

+1 cho câu hỏi về lắp ráp x86. Và @AkiSuihkonen, trông giống như một câu trả lời chứ không phải là một nhận xét. –

+1

Linkas, và có rất chi tiết quan trọng còn thiếu trong câu hỏi: Chương trình lắp ráp nào được sử dụng: MASM/TASM/NASM/YAMS hoặc một cái gì đó khác. Và làm thế nào nó được sử dụng (có những lựa chọn phương ngữ trong một số người trong số họ). – osgx

Trả lời

12

Tóm tắt:

  • NASM/YASM đòi hỏi word [ecx] khi toán hạng có kích thước không được ngụ ý bởi các toán hạng khác. (Nếu không [ecx] là ok).
  • MASM/TASM yêu cầu word ptr [ecx] khi toán hạng không được ngụ ý bởi toán hạng khác. (Nếu không [ecx] là ok).

Chúng từng bị nghẹn theo cú pháp của người khác.


CẢNH BÁO: Đây là khu vực rất lạ mà không có bất kỳ tiêu chuẩn ISO nào hoặc bảng BNF dễ tìm; và tôi không phải là chuyên gia đi bộ qua các bãi mìn của cú pháp MASM độc quyền.

Nó trường hợp của bạn có thể không có sự khác biệt, nhưng PTR điều hành có thể có nghĩa là trong trường hợp khác:

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 

Tôi nghĩ, cũng có lắp ráp yêu cầu cụ thể (NASM/co thắt/asm khác) và sử dụng "byte ptr" là di động hơn.

Đồng thời kiểm tra phần 4.2.16 trong book from India và các phần 8.12.3 (và 8.11.3 "Xung đột loại") trong "Nghệ thuật lập trình ngôn ngữ lắp ráp".

CẬP NHẬT: nhờ Frank Kotler, dường như NASM "sử dụng một biến thể của cú pháp lắp ráp Intel" (wiki), không bao gồm hoạt động PTR.

UPDATE1: Có gốc "ASM86 LANGUAGE REFERENCE MANUAL" từ Intel, 1981-1983, PTR điều hành được xác định trên trang 4-15:

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: Nhờ Uni của bitaver của Stuttgart! Có original MACRO-86 manual từ Microsoft (1981).Trang 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.

Và trang 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 

Sau khi đọc và tìm một số định nghĩa cú pháp từ các tài liệu này, tôi nghĩ rằng viết PTR là bắt buộc. Việc sử dụng mov BYTE [ecx], 0 không chính xác theo hướng dẫn sử dụng MACRO-86.

+7

Nasm sẽ chặn trên 'PTR'. Masm/Tasm sẽ bị cấm mà không có nó. –

+0

@ Frank bình luận nên thực sự là câu trả lời ở đây, chứ không phải là mess này có ý định ... ;-) Nếu bạn không nhớ, đây là một câu hỏi khá phổ biến, vì vậy nó có thể là giá trị nó để quay trở lại và viết lại/định dạng lại phần lớn câu trả lời này (và bao gồm TL; DR cho độ rõ tối đa). –

+0

@Cody, Xin chào, thực ra tôi có thể hiểu bất kỳ điều gì về câu trả lời này ngay bây giờ (nó giống như sổ ghi chép cá nhân của tôi để ghi lại một số URL tới một số sách hướng dẫn bảo tàng/cổ xưa thú vị). Bạn có thể giúp chỉnh sửa nó bằng cách viết lại nó (có lẽ với chuyển đổi sang wiki)? – osgx

6

Bạn đang sử dụng một trình tạo thuận lợi, có vẻ như, trình biên dịch C của tôi hỗ trợ cho việc lắp ráp trực tuyến chắc chắn không hài lòng với nó. Cú pháp thích hợp là BYTE PTR để báo cho trình biên dịch biết rằng giá trị trong thanh ghi ECX cần được xử lý như một con trỏ. PTR. Nhưng cú pháp đó là trên chỉ định, có thể bạn đã biết rằng bạn muốn sử dụng nó làm con trỏ bằng cách đặt [dấu ngoặc vuông] quanh tên đăng ký. Sử dụng [ecx] đã làm rõ rằng bạn có nghĩa là lưu trữ số không vào địa chỉ được cung cấp bởi thanh ghi ECX.

Vì vậy, nó biết cách sử dụng thanh ghi ECX, chỉ khác điều mà nó không biết là cần phải đặt bao nhiêu byte thành 0. Lựa chọn là 1, 2 hoặc 4. Bạn đã làm rõ, 1. BYTE.

0

Trong MASM, BYTE PTR [ecx] truy cập bộ nhớ tại địa chỉ ecx. BYTE [ecx] là lỗi cú pháp ("lỗi cú pháp lắp ráp nội tuyến trong 'toán hạng đầu tiên'; tìm thấy '['").

Trong NASM hoặc YASM, BYTE [ecx] truy cập bộ nhớ tại địa chỉ ecx. BYTE PTR [ecx] là lỗi cú pháp ("lỗi: dấu phẩy, dấu hai chấm hoặc kết thúc của dòng mong đợi" trong NASM, "biểu tượng không xác định" PTR "" trong YASM).

Trong TASM, BYTE PTR [ecx] và BYTE [ecx] là tương đương - cả bộ nhớ truy cập tại địa chỉ ecx.

Tuy nhiên, trong khí lắp ráp Gnu, khi sử dụng cú pháp intel BYTE PTR [ecx] truy cập bộ nhớ tại ecx, nhưng BYTE [ecx] thực sự truy cập bộ nhớ tại địa chỉ ecx + 1. Tức là, BYTE [ecx] tương đương với BYTE PTR [ecx + 1], có vẻ không lành mạnh hoặc được ghi lại.

Gnu lắp ráp phiên bản 2.18, 2.24, hoặc 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

Trong bộ kết hợp GNU định danh BYTE, WORD, DWORD cũng giống như định nghĩa 1,2,4 'movb BYTE [ecx], 0' thực sự giống với' movb 1 [ecx], 0' là 'mov BYTE PTR [ecx + 1], 0'. 'movb WORD [ecx], 0' giống với' movb 2 [ecx], 0' hoặc 'mov BYTE PTR [ecx + 2], 0'. 'mov eax, WORD' giống với' mov eax, 2'. 'mov eax, BYTE' giống với' mov eax, 1', v.v. –

+0

Thú vị, cảm ơn bạn! "mov ecx, BYTE" là lỗi cú pháp trong NASM, MASM và TASM, nhưng không phải là khí. –

Các vấn đề liên quan