Was genau die Anweisung
movzbl 0x01(%eax,%ecx),%eax
tut?
Die AT & T-Syntax unterteilt das movzx
Intel-Anweisungs-Mnemonik in verschiedene Mnemoniken für verschiedene Quellgrößen (movzb
vs. movzw
). In der Intel-Syntax ist dies:
movzx eax, byte ptr [eax+ecx+1]
d.h. ein Byte aus dem Speicher bei eax + ecx + 1 laden und bis zum vollen Register auf Null verlängern.
Übrigens haben die meisten GNU Tools jetzt einen Schalter oder eine Konfigurationsoption, um die Intel-Syntax zu bevorzugen. (Wie zum Beispiel objdump -Mintel
oder gcc -S -masm=intel
, obwohl letzteres die Syntax beeinflusst, die beim Kompilieren von inline-asm verwendet wird). Ich würde auf jeden Fall empfehlen, sich das anzuschauen, wenn Sie AT & T Assembly nicht zum Leben erwecken. Weitere Dokumente und Anleitungen finden Sie auch im x86 Tag-Wiki.
Minimales Beispiel
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 upstream mit Behauptungen .
Die Gedächtnisstütze lautet:
Es gibt auch Versionen für andere Größen:
movzbw
: Byte (8 Bit) bis Wort (16 Bit)movzwl
: Word (16 Bit) bis Long (32 Bit)Wie bei den meisten GAS-Befehlen können Sie beim Umgang mit Registern das Zeichen der letzten Größe weglassen:
movzb %bl, %eax
aber ich kann nicht verstehen, warum wir den vorletzten Buchstaben nicht weglassen können, z. Folgendes schlägt fehl:
movz %bl, %eax
Warum nicht einfach aus der Größe der Operanden ableiten, wenn es sich um Register für mov
und Intel-Syntax handelt?
Und wenn Sie Register mit der falschen Größe verwenden, kann es beispielsweise nicht kompiliert werden:
movzb %ax, %eax