Um zu verstehen, was das Suffix .s
bedeutet, müssen Sie verstehen, wie x86-Anweisungen codiert sind. Wenn wir adc
als Beispiel nehmen, gibt es vier Hauptformen, die die Operanden nehmen können:
- Der Quelloperand ist eine unmittelbare und der Zieloperand ist der Akkumulator-Register.
- Der Quelloperand ist ein Sofortiger und der Zieloperand ist ein Register oder eine Speicherstelle.
- Der Quelloperand ist ein Register und der Zieloperand ist ein Register oder ein Speicherort.
- Der Quelloperand ist ein Register oder ein Speicherort und der Zieloperand ist ein Register.
Und natürlich gibt es Varianten von diesen für die verschiedenen Operandengrößen: 8-bit, 16-bit, 32-bit, usw.
Wenn einer Ihrer Operanden ein Register ist und die andere Ein Speicherort, es ist offensichtlich, welche der Formen 3 und 4 der Assembler verwenden sollte, aber wenn beide Operanden Register sind, ist jede Form anwendbar. Das Präfix .s
teilt dem Assembler mit, welches Formular zu verwenden ist (oder zeigt im Falle einer Disassembly, welches Formular verwendet wurde).
bei dem spezifischen Beispiel von adcb %bl,%dh
Sehen, es die beiden Wege sind kann wie folgt codiert:
10 de adcb %bl,%dh
12 f3 adcb.s %bl,%dh
Das erste Byte die Form der Instruktion bestimmt verwendet, die ich später zurückkommen würde. Das zweite Byte ist ein sogenanntes ModR/M-Byte und spezifiziert den Adressierungsmodus und die Registeroperanden, die verwendet werden. Das ModR/M-Byte kann in drei Felder aufgeteilt werden: Mod (die höchstwertigen 2 Bits), REG (die nächsten 3) und R/M (die letzten 3).
de: Mod=11, REG = 011, R/M = 110
f3: Mod=11, REG = 110, R/M = 011
Der Mod und R/M Felder zusammen, um die effektive Adresse des Standortspeichers bestimmen, ob einer der Operanden eine Speicherstelle ist, aber, wenn dieser Operand nur ein Register ist, wird das Mod-Feld auf 11 gesetzt ist, und R/M ist der Wert des Registers. Das REG-Feld repräsentiert offensichtlich nur das andere Register.
Also im de
Byte, das R/M-Feld enthält das dh
-Register, und die REG-Felder enthält das bl
-Register. Und in dem Byte f3
hält das R/M-Feld das bl
-Register und die REG-Felder enthält das dh
-Register.(8-Bit-Register werden als die Zahlen 0 bis 7 in der Reihenfolge al, cl, dl, bl, ah, ch, dh, bh codiert)
Zurück zum ersten Byte, die 10
sagt uns, die verwenden Form 3-Kodierung, wobei der Quelloperand immer ein Register ist (dh er kommt aus dem REG-Feld), und der Zieloperand ist ein Speicherort oder Register (dh er wird durch die Mod- und R/M-Felder bestimmt). Die 12
sagt uns, dass wir die Form 4-Kodierung verwenden sollen, wobei die Operanden umgekehrt sind - der Quelloperand wird durch die Mod- und R/M-Felder bestimmt und der Zieloperand kommt aus dem REG-Feld.
So wird die Position der Register im ModR/M Byte vertauscht, und das erste Byte des Befehls sagt uns, welcher Operand wo gespeichert ist.
Beachten Sie, dass '.s' Kodierung-überschreiben Suffixe wurden ersetzt durch [' {load} 'und' {store} '* Präfixe *, und auch' {vex3} ',' {disp32} 'und andere] (https://sourceware.org/binutils/docs/as/i386_002dMnemonics.html). z.B. '{load} addiere% eax,% ecx'. –