Frage

In dem folgenden Assembler-Code, dass ich abgeladen aus objdump mit:

lea    0x0(%esi,%eiz,1),%esi

Was ist Register %eiz? Was bedeutet die vorhergehenden Code bedeuten?

War es hilfreich?

Lösung

Siehe Warum Does GCC LEA EIZ :

  

Offenbar %eiz ist ein Pseudo-Register, das nur auswertet auf Null zu allen Zeiten (wie r0 auf MIPS).

...

  

Schließlich fand ich eine Mailing-Liste Beitrag von binutils Guru Ian Lance Taylor, der die Antwort offenbart. Manchmal fügt GCC NOP-Anweisungen in den Code-Strom wie die richtige Ausrichtung und Sachen zu gewährleisten. Der NOP-Befehl nimmt ein Byte, so würden Sie denken, dass Sie nur so viele hinzufügen könnten je nach Bedarf. Aber nach Ian Lance Taylor, ist es schneller für den Chip ein, als viele kurzen Anweisungen langen Befehl auszuführen. Anstatt also sieben NOP-Befehle einfügen, sie stattdessen eine verwenden bizarro LEA, die sieben Bytes verwendet und ist semantisch äquivalent zu einem NOP.

Andere Tipps

(Sehr spät, um das Spiel, aber dies wie eine interessante Ergänzung scheint): Es ist nicht ein Register überhaupt, ist es eine Marotte der Intel Befehlscodierung. Wenn ein ModRM-Byte unter Verwendung von aus dem Speicher zu laden, gibt es 3 Bits für das Registerfeld zum Speichern 8 mögliche Register. Aber der Ort, an dem ESP (der Stapelzeiger) „würde“ werden, anstatt durch den Prozessor als „ein SIB-Byte folgt diese Anweisung“ (das heißt, es ist ein erweiterter Adressiermodus, kein Bezug auf ESP) interpretiert wird. Aus Gründen, die nur die Autoren bekannt ist, hat das GNU Assembler immer vertrat diese „Null wo ein Register sonst wäre“ als „% EIZ“ registrieren. Die Intel-Syntax fällt es einfach.

Andy Ross bietet viel mehr von der zugrunde liegenden Argumentation, ist aber leider falsch oder zumindest verwirrend über die technischen Details. Es ist wahr, daß eine effektive Adresse nur (%esp) kann nicht nur mit dem ModR / M-Byte als anstatt dass sie als dekodierte (%esp) codiert werden, wird es auf ein Signal verwendet, das SIB-Byte ist ebenfalls enthalten. Allerdings ist die %eiz pseudo-Register nicht immer mit einem SIB-Byte verwendet, um darzustellen, dass ein SIB-Byte verwendet wurde.

Der SIB-Byte (Scale / index / Base) drei Stücke es: der Index (ein Register wie als %eax oder %ecx dass die Skala angewandt wird), das Ausmaß (eine Potenz von zwei 1 bis 8, dass das Indexregister wird von) multipliziert, und die Basis (ein anderes Register, das auf den skalierten Index hinzugefügt wird). Dies ist, was für Anweisungen wie add %al,(%ebx,%ecx,2) (Maschinencode: 00 04 4b - Opcode, modr / m, sib (Anmerkung kein% EIZ registrieren, obwohl das SIB-Byte verwendet)) ermöglicht (oder in Intel-Syntax „, BYTE PTR [ECX hinzufügen * 2 + ebx], al ").

Allerdings %esp kann nicht als Indexregister in einem SIB-Byte verwendet werden. Anstatt diese Option zu erlauben, Intel fügt stattdessen die Möglichkeit, das Basisregister zu verwenden, wie ohne Skalierung oder Indizierung ist. Daher eindeutig zu machen zwischen dem Fall der add %al,(%ecx) (Maschinencode 00 01 - Opcode, modr / m) und add %al,(%ecx) (Maschinencode 00 04 21 - Opcode, modr / m, SIB), die alternative Syntax add %al,(%ecx,%eiz,1) wird stattdessen verwendet (oder für Intel Syntax:. add BYTE PTR [ecx+eiz*1],al)

und wie in dem Artikel erklärt, verbunden durch Sinan, diese spezifische Instruktion (lea 0x0(%esi,%eiz,1),%esi) wird lediglich als ein Multi-Byte-NOP (entspricht esi = &*esi) verwendet, so dass nur eine nop-like-Befehl anstelle von mehreren NOP ausgeführt werden soll Anweisungen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top