26

これらの2つの行の違いは何ですか? ここでどのような PTR が変更されますか?

;first
mov BYTE [ecx], 0  
;second
mov BYTE PTR [ecx], 0
4

3 に答える 3

25

概要:

  • NASM/YASM はword [ecx]、operand-size が他のオペランドによって暗示されていない場合に必要です。(それ以外[ecx]は大丈夫です)。
  • MASM/TASM はword ptr [ecx]、オペランドのサイズが他のオペランドによって暗示されていない場合に必要です。(それ以外[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

アセンブラー固有の要件 (nasm/tasm/ 他の asm) もあり、「byte ptr」を使用する方が移植性が高いと思います。

また、インドの書籍のセクション4.2.16と、「 The Art of Assembly Language Programming 」のセクション 8.12.3 (および 8.11.3 "Type Conflicts")も確認してください。

更新: Frank Kotler のおかげで、NASM は PTR 操作を含まない「Intel アセンブリ構文のバリエーションを使用する」(wiki)ようです。

UPDATE1: オリジナルのASM86 LANGUAGE REFERENCE MANUALが Intel から 1981 年から 1983 年に発行されており、PTR Operator は 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

この形式は、変数またはラベルの type 属性をオーバーライドするためにも使用できます。たとえば、既に定義されている単語変数に 2 バイトとしてアクセスする場合は、次のようにコーディングできます。

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

フィールド値:

type このフィールドは、BYTE、WORD、DWORD、QWORD、TBYTE、NEAR、FAR のいずれかの値を持つことができます。

name このフィールドは次のいずれかになります。 1. 変数名。2. レーベル名。3. アドレスまたはレジスタ式。4. オフセットを表す整数。

UPDATE2: Uni of Stuttgart のビットセーバーに感謝します! Microsoft (1981) からオリジナルの MACRO-86 マニュアルがあります。ページ 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 の 2 番目の使用法は、変数定義の型以外の型でデータにアクセスすることです。ほとんどの場合、これは構造で発生します。構造体が WORD として定義されているが、項目にバイトとしてアクセスしたい場合、PTR がそのための演算子です。ただし、構造をバイト単位で定義する 2 番目のステートメントを入力する方がはるかに簡単です。これにより、構造体への参照ごとに PTR を使用する必要がなくなります。セクション 4.2.1、メモリ ディレクティブの LABEL ディレクティブを参照してください。

例:

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

 ADD BYTE PTR FOO,9

これを読み、これらのドキュメントの構文定義を調べた後、PTR を書くことは必須だと思います。mov BYTE [ecx], 0MACRO-86 マニュアルによると、 の使用法は正しくありません。

于 2012-12-09T19:38:47.273 に答える
6

あなたは寛大なアセンブラを使用しています。どうやら、私の C コンパイラのインライン アセンブリのサポートは、それに満足していないようです。適切な構文は BYTE PTR であり、ECX レジスタの値をポインタのように扱う必要があることをアセンブラに伝えます。PTR。しかし、それは過剰に指定された構文です。レジスター名を [括弧] で囲むことで、それをポインターとして使用するつもりであることがすでにわかります。[ecx] を使用すると、ECX レジスタによって提供されるアドレスにゼロを格納するつもりであることがすでに明らかになりました。

したがって、ECX レジスタの使用方法はわかっていますが、にわかっていないことは、ゼロに設定する必要があるバイト数だけです。選択肢は 1、2、または 4 です。明確にしました。1.BYTE。

于 2012-12-10T00:54:13.670 に答える