この指示は正確に何をしますか?
movzbl 0x01(%eax,%ecx), %eax
AT&T構文は、movzx
Intel命令ニーモニックをさまざまなソースサイズ(movzb
対movzw
)のさまざまなニーモニックに分割します。Intel構文では、次のようになります。
movzx eax, byte ptr [eax+ecx+1]
つまり、eax + ecx + 1でメモリからバイトをロードし、レジスタ全体にゼロ拡張します。
ところで、ほとんどのGNUツールには、Intel構文を優先するためのスイッチまたは構成オプションがあります。(objdump -Mintel
またはなどgcc -S -masm=intel
。ただし、後者はインラインasmのコンパイル時に使用される構文に影響します)。生活のためにAT&Tの組み立てを行わないのであれば、私は確かにそれを調べることをお勧めします。その他のドキュメントとガイドについては、 x86タグwikiも参照してください。
最小限の例
mov $0x01234567, %eax
mov $1, %bl
movzbl %bl, %eax
/* %eax == 0000 0001 */
mov $0x01234567, %eax
mov $-1, %bl
movzbl %bl, %eax
/* %eax == 0000 00FF */
assertions を使用して GitHub アップストリームを実行できます。
ニーモニックは次のとおりです。
他のサイズのバージョンもあります:
movzbw
:バイト(8ビット)~ワード(16ビット)movzwl
: Word (16 ビット) から Long (32 ビット)ほとんどの GAS 命令と同様に、レジスタを扱うときは最後のサイズ文字を省略できます。
movzb %bl, %eax
しかし、最後の文字の前を省略できない理由がわかりません。たとえば、次の例では失敗します。
movz %bl, %eax
mov
オペランドが forおよび Intel 構文のようにレジスターである場合、オペランドのサイズから推測してみませんか?
間違ったサイズのレジスタを使用すると、コンパイルに失敗します。
movzb %ax, %eax