web-dev-qa-db-ja.com

MOVSXアセンブリ命令はどのように機能しますか?

次の例では、アセンブリ命令MOVSXはどのように機能しますか。

MOVSX ECX,BYTE PTR DS:[EDX]

この場合、レジスターの状態は次のとおりです。

ECX = 0000000F   
EDX = 0012FD9F 

私の考えでは、[EDX] = 9Fの最後のバイトが必要で、それをECXに移動してから、16ビット= 0000009Fに一致するように符号拡張します。ただし、実際の結果は00000016です。誰かが私がどこが間違っているのか説明してもらえますか?

11
Abundance

それは部分的に正しいです。しかしながら:

BYTE PTR DS:[EDX]EDXに保持されているアドレスにあるバイトを取得します。このバイトはECXから最下位バイトにコピーされ、残りはバイトの符号で埋められます。

予期しない結果の場合、これはメモリアドレスで10x12FD9Fバイト0x16 位置しています。


ノート:

  • セグメントオーバーライドプレフィックスDS:ここでは必要ありません。 [EDX]は自動的にDSを参照します。

1 「メモリアドレス」とは、ここでは仮想メモリまたは物理メモリを指します

8
cadaniluk

多くのIntel/AMD x86命令は「modrm」形式で利用可能です-それらには2つのオペランドがあり、一方はレジスタでなければならず、もう一方はレジスタまたはメモリ参照であり、そのアドレスはmodrmバイトによって決定されます命令のエンコーディング、および場合によってはsib(スケーリングされたインデックスバイト)などの命令の後続のバイト、および直接の定数/メモリオフセット。また、可能なセグメントプレフィックスバイト。

通常、これらは次の形式のreg、reg/mem命令です

   rsrcdst += rsrc
or
   rsrcdst += Memory[ ... addressessing mode ...]

ただし、x86アセンブリコードには、これらの命令のreg、regおよびreg、mem形式の個別のオペコード/命令ニーモニックはありません。オペランドがレジスターであるかメモリー・ロケーションであるかは、アセンブラーでアセンブリー構文によって示されます。

この場合、アセンブリコードは

MOVSX ECX、BYTE PTR DS:[EDX]

命令オペコードはMOVSXです。

宛先オペランドはレジスタECXです。

ソースオペランドは「BYTE PTR DS:[EDX]」です。これがメモリ参照であることは、いくつかのことで示されます。(1) "[EDX]"を囲む角括弧-角括弧は、Memory [... address ...]の省略形です。 (2)「DS:」接頭辞。データセグメント内にあることを示します。レジスタオペランドには、このようなセグメントプレフィックスはありません。 (3)「BYTE PTR」-「「DS:[EDX]」で指定されたメモリアドレスを取得し、それをメモリ内の8ビットバイトを参照していると解釈します」.

あなたが本当に欲しいのは

MOVSX ECX,DL

「DL」は、32ビットレジスタEDXの下位8ビットの名前です。つまりDL = EDX.bits [7:0]。残念ながら、x86アセンブラーは通常、「EDX.bits [7:0]」のような構文を受け入れません(私が書いた場合を除く)。そのため、サブレジスターの歴史的な名前を知る必要があります。

AL = EAX.bits[7:0]
AH = EAX.bits[15:8]
AX = EAX.bits[15:0]
EAX = 32 bit register that "covers" all of the above

など:BL、CL、DL、DI、...

4
Krazy Glew