web-dev-qa-db-ja.com

MOVZBL命令はIA-32 AT&T構文で何をしますか?

まさにその指示

movzbl  0x01(%eax,%ecx),%eax

しますか?

34
user663896

AT&T構文は、 movzx Intel命令ニーモニック を異なるソースサイズ(movzb vs. movzw)の異なるニーモニックに分割します。 Intel構文では、次のとおりです。

movzx eax, byte ptr [eax+ecx+1]

つまり、eax + ecx + 1でメモリからバイトをロードし、完全にレジスタにゼロ拡張します。

ところで、ほとんどのGNUツールには、Intel構文を優先するためのスイッチまたは設定オプションがあります。(objdump -Mintelまたはgcc -S -masm=intel。ただし、後者はinline-asmのコンパイル時に使用される構文に影響します)。生活のためにAT&Tアセンブリーを行わない場合は、ぜひ検討することをお勧めします。その他のドキュメントとガイドについては、 x86 タグwikiも参照してください。

36
Igor Skochinsky

最小限の例

mov $0x01234567, %eax
mov $1, %bl
movzbl %bl, %eax
/* %eax == 0000 0001 */

mov $0x01234567, %eax
mov $-1, %bl
movzbl %bl, %eax
/* %eax == 0000 00FF */

アサーション付きのRunanble GitHubアップストリーム

ニーモニックは次のとおりです。

  • MOV
  • ゼロ拡張
  • バイト(8ビット)
  • ロング(32ビット)

他のサイズのバージョンもあります:

  • movzbw:バイト(8ビット)からワード(16ビット)
  • movzwl:ワード(16ビット)からロング(32ビット)

ほとんどのGAS命令と同様に、レジスタを処理するときに最後のサイズの文字を省略することができます。

movzb %bl, %eax

しかし、前の最後の文字を省略できない理由を理解できません。次は失敗します。

movz %bl, %eax

オペランドがmovおよびIntel構文のようにレジスターである場合、オペランドのサイズから単純に推定しないのはなぜですか?

そして、間違ったサイズのレジスタを使用すると、コンパイルに失敗します:

movzb %ax, %eax