2016-03-23 9 views
1

私はプログラムをコンパイルするためにnasmを使用しようとしています。そして、nasm構文に関して問題を抱えました。Nasm、メモリデータを1行で直接交換できますか?

invalid combination of opcode and operands.

は、だから私は、私が直接として、他のレジスタを使用せずに1行でメモリのデータのやり取りを行うことができるかどうかをお尋ねしたいと言い、

mov byte [edi],[esi] 

NASMはちょうど私にエラーを与える: は、実は私はこのコードを書いていますメディア。

+4

一般に、しかし、その特定の場合には、 'movsb'命令を使用することができます。インテルのマニュアルの第2巻を参照してください。 – Michael

+0

@マイケル私はそれを試してみるが、もう一度失敗する。これはコンパイルにnasmを使用していますか? – Liberty

+2

_「失敗しました」は十分な問題の説明ではありません。取得している_exact_エラーメッセージとは何ですか、エラーが対応する_exact_コード行は何ですか? – Michael

答えて

1

使用している命令フォーマットが「違法」です。プロセッサは、2つのメモリ位置間を移動することを理解していない。そのため、エラーが発生しています。ダイレクト・レジスタ・アドレッシング・モード(角カッコを使用)を使用すると、リストされた各レジスタ(edi、esi)に格納されているメモリ・アドレスが与えられます。

プロセッサは単純にそれを行うことはできません。ごめんなさい。あなたは、あなたがやろうとしていることをするために別の方法を見つけなければならないでしょう。

movsb命令は、esiが指すアドレスからediが指すアドレスに1バイト移動します。それはあなたが探しているものかもしれませんが、その場合のコードは単純に

movsb 

です。また、方向フラグの値に応じてesiとediをインクリメントまたはデクリメントします(これは通常はクリアなのでインクリメントされます)。

ec修飾子を使用して、ecxに格納されている値で示された回数だけ命令を繰り返すことができます。

INi ediおよびesiの値は、movsb命令によって変更されることに注意してください。 movsBを使用する場合は、1ずつインクリメントまたはデクリメントされます。

あなたはメモリ内の2つの値を交換する必要がある場合は二つのレジスタを持つ私わずかに少ない効率的な方法に応じて、他のユーザーによって指摘したように、あなたは一つの追加のレジスタでそれを行うことができます。

mov edx, [edi] 
xchg edx, [esi] 
mov [edi], edx 

これが入れ替わりますediesiの内容で指し示されるメモリアドレスの内容。それを行うための方法はありません。

+1

技術的には、より短い方法があります: 'mov edx、edi/xchg edx、[esi]/mov edi、edx'です。これは4バイトを節約しますが、より遅く実行される可能性があります。 – owacoder

+0

@owacoder、それは意味があります - 私はmovsb命令を思い出した後私の元の答えを編集しましたが、あなたの答えは私の元の答えよりも短いです。 – querist

+0

方向フラグがクリアされている場合([_CLD_](http://www.felixcloutier.com/x86/CLD.html))、転送/増分され、設定されている場合は[_STD_](http://www.felixcloutier .com/x86/STD.html))それは後ろに/減らされます –