5

ここに登録する変数を割り当てようとしていますコードは次のとおりです。

       ORG 100h

        var1 DB 10  ;
        var2 DB 20  ;

        MOV BX,var1 ; error : operands do not match: 16 bit register and 8 bit address
RET
END

ただし、4行目を次のように入れ替えると:

MOV BL, var1;

できます。私の質問は、 8 ビット変数より大きな 16 ビット レジスタに移動できないのはなぜですか?

私はすでにthisthis、およびthis OP を参照しましたが、私の質問には答えません。

ノート:

  1. emu8086アセンブラを使用しています
  2. 私はアセンブリ言語に慣れていないので、ばかげた質問でしたら申し訳ありません。
4

2 に答える 2

7

8 ビット変数をより大きな 16 ビット レジスタに移動できないのはなぜですか?

マシンコードMOV命令では、ソースオペランドとデスティネーションオペランドの両方が同じサイズである必要があるためです。これが必要になるのは、MOV命令自体がより大きなデスティネーション レジスタの残りのビットを埋める方法を指定しないためです。

さまざまなサイズの移動操作を可能にするために、Intelは 80386 CPU にMOVZXと を追加しMOVSXました。これにより、より小さなソース オペランドが可能になります (宛先は常に 32 ビット レジスタです)。-SX および -ZX サフィックスは、デスティネーション レジスタの以前に使用されなかったビットに何を入力する必要があるかを示します。

16 ビット Intel プロセッサでCBWは、符号を 8 ビットから 16 ビットに拡張する命令 (バイトをワードに変換) があります。残念ながら、これはアキュムレータ (レジスタ AL/AX) に対してのみ機能するため、次のようにする必要があります。

mov al,var1
cbw
mov bx,ax

cbw符号拡張を行います。署名されていない場合var1は、次のように簡単に実行できます。

mov bl,var1
xor bh,bh  ; equivalent to mov bh,0 but faster and only one byte opcode

または、Peter Cordesが述べているように:

xor bx,bx    ;clear the whole destination register
mov bl,var1  ;update the least significant byte of the register with the 8-bit value
于 2015-11-27T14:50:41.977 に答える
1

シンボルの宣言方法を追跡して、使用するオペランドのサイズを把握するアセンブラを使用しています。

var1は 8 ビット アドレスではなく、2 つの 8 ビット変数の最初を指す 16 ビット アドレス (セグメントをカウントしない) です。そのため、アセンブラのエラー メッセージは言葉遣いが悪く、混乱を招きます。

NASM はあなたが言ったことを実行し、16 ビットのロードを実行します。とvar1にあります。おそらく、アセンブラに 16 ビットの負荷を発行させるために、または何かを書くことができます。blvar2bhmov bx, word [var1]word ptr

(実際には、NASM は にアセンブルmov BX, var1mov r16, imm16、アドレスをレジスタに入れます。[]一貫性を保つために、メモリ参照を常に使用します。これは、Intel 構文の NASM および MASM バリアントで機能するためです。NASM はmov BX, offset var1、mov-immediate を記述するための構文をサポートしていません。形ですが。)

于 2015-11-27T14:50:24.947 に答える