Ich war vor kurzem auf der Suche nach einem Weg, um ein Bild mit einer ausführbaren Datei ohne Bezug auf das Bild als externe Datei zu versenden. Jetzt können Sie argumentieren, wenn es eine gute Idee im Allgemeinen ist, aber das ist eine andere Geschichte. Da ich sehr wenig Informationen über das Thema gefunden und gebraucht habe, um Informationen aus verschiedenen Quellen zusammenzustellen, schließe ich die Aufgabe mit diesem umfassenden Schreiben auf das Thema. Die hier beschriebenen Mechanismen gelten für die Einbeziehung aller Ressourcen - nicht nur der Bilder - in ein ausführbares C-Programm. Es gibt verschiedene Möglichkeiten, generische feste Daten innerhalb einer Anwendung einzubetten. Let039s beginnen mit einem grundlegenden Beispiel, das bekannt sein sollte: Jede Anwendung ist nur eine Sammlung von Datensegmenten, die in einer Datei gespeichert sind. Auf der modernen PC-Architektur besteht jede Applikations-Binärdatei aus drei Hauptsegmenten Stack. Daten und Code. Ohne in Details zu gehen, befinden sich feste Daten - wie zB konstante Textstrings im schreibgeschützten Teil des Datensegments der Applikationsbinärdatei und der C-Compiler erstellt automatisch einen Speicherbereich. Wenn du die obige Zeile mit gcc - c - o mytext. o mytext. c kompilierst und die Objektdatei mit objdump - t mytext. o durchsuchst, findest du den Datenabschnitt in der Objektdatei. Was grundsätzlich sagt: mystring039 ist ein schreibgeschütztes globales (g) Textobjekt (O) und kann bei Offset 0x00 in der Objektdatei gefunden werden. Für eine detaillierte Beschreibung aller Werte siehe man objdump. Nun wäre eine Lösung, um einfach den Code in c zu schreiben und den Compiler auf alles zu kümmern, indem du die Daten einer bestimmten Datei kodierst, kann das xxd-Tool, das mit dem Vim-Texteditor geliefert wird, verwendet werden: xxd - i binaryfile output C enthalten Datei-Stil der angegebenen Binärdatei und schreibt eine komplette statische Array-Definition benannt nach der Eingabedatei: Mit dieser Variante produziert tragbaren C-Code und nur funktioniert (TM). Im Nachhinein benötigt es mindestens das Fünffache der Originaldaten (0xNN, für jedes Original-Datenbyte) und der Quellcode muss jedes Mal aktualisiert werden, wenn sich die ursprünglichen Daten ändern. Während dieser Ansatz in einigen Fällen nützlich ist, können wir es besser machen. Der GNU-Linker kann direkt zum Erstellen von Objektdateien mit einem benutzerdefinierten. data-Bereich direkt aus jeder Eingabedatei verwendet werden. Die magischen Flags sind - r, um die Objektdatei zu verlagern und - b binär für die Verknüpfung von Dateien mit einem ungewöhnlichen Binärformat. Die daraus resultierende Objektdatei example. o kann mit jeder Anwendung verknüpft werden, einfach mit gcc selbst. z. B. Gcc - o myapp myapp. c Beispiel. o. Nun ist der letzte fehlende Link, um auf die Daten in example. o aus dem C-Code in myapp. c zuzugreifen. Schauen Sie sich die Ausgabe des Objekts an und vergleichen Sie es mit dem oben genannten Ausgang für das Mystring-Objekt. Die .. g. data ltnamegt Teil sollte eine Glocke läuten. Dieser Datenabschnitt kann aus dem C-Code einfach durch die Verwendung von: und die Länge kann aus oder einfach durch Verweisen auf die Adresse von binaryexamplejpgsize referenziert werden. Der Linker wird die externe Referenz bei der Verknüpfung der Anwendung auflösen und die Anwendung verwendet die Daten wie ein fester Blob im Quellcode. Jetzt für den kniffligen Teil: Der GNU Linker verhält sich je nach Plattform und Architektur unterschiedlich. Die für mich interessanten Implementierungen sind GNULinux, OSX und Mingw (Cross-Compiling Windows Binärdateien auf einem GNULinux Host). Der mingw-cross-compiler verhält sich fast genau wie gnu-ld mit einem kleinen Unterschied: Der Datenabschnitt enthält nicht den führenden Unterstrich: binaryexamplejpgstart vs binaryexamplejpgstart. Gut, da geht etwas von der Eleganz der Lösung, aber dieser Fall ist leicht mit einem ifdef zu behandeln. MacOSX ist aber anders. Die ld, die mit X-Code ausgeliefert wird, kommt aus llvm Version 2.7svn und unterstützt nicht die - b Eingabeformat-Funktion. Darüber hinaus können universelle ausführbare Dateien auf OSX Binärformate für verschiedene Architekturen enthalten, wobei das. Data-Format für jede Architektur unterschiedlich ist. Die Ausrichtung für die Daten kann zwischen 32bit und 64bit Architekturen abweichen und die Endianess kann sich auch unterscheiden. So muss die Erstellung des Datenabschnitts während der Kompilierung statt der Verknüpfungsstufe erfolgen. Auf OSX ld039s binäre Verknüpfungsfunktion wurde in ihre benutzerdefinierte gcc verschoben und ist über 039-sectcreate039 Option verfügbar: Um einen universellen Build für Intel-Architekturen zu erstellen, füge - arch i386 - arch x8664 zu oben Kommandozeile hinzu. Objdump ist auch ein GNU-Tool, das auf OSX nicht verfügbar ist. Sie können den Datenabschnitt mit Hilfe von otool - s DATA examplejpg pathtoexecutable überprüfen. Siehe man otool für Details dort. Aufgrund der Art der OSX-Binärdateien ist die Referenzierung des Datenabschnitts im C-Code mit einem einfachen, unsignierten Zeichen nicht möglich. Der Linker weiß nicht, welche Architektur verwendet wird und kann keine Adresse geben. Das Binärformat, das von OSX verwendet wird, muss zur Laufzeit überprüft werden, wenn die Architektur bekannt ist und die relevanten Daten nach dem Start der Applikation abbilden. Apple bietet eine API für das, was in der Mach-ogetsect. h-Header-Datei definiert ist. Wenn Sie x-Code installiert haben, können Sie die Dokumentation darüber bei man getsktbyname lesen. Das Auflösen des Segments kann nur zur Laufzeit erfolgen, nachdem der Datenabschnitt verlagert wurde und durch den Aufruf von getsectbyname () durchgeführt werden kann. Allerdings gibt es einen Trick, den Sie verwenden können, um dies implizit zu machen. Der meta-variable Abschnitt wird vom gcc-Compiler auf OSX erkannt. Es erzeugt das gleiche Ergebnis wie das Aufrufen von getsectbyname () addr. Kurz vor dem Lesen des aktuellen Codes, Informationen über osx Linker Einbauten ist nicht leicht zu kommen. Getsectbyname () öffnet tatsächlich die ausführbare Datei und durchsucht den entsprechenden Datenabschnitt, während die Anwendung läuft. Abschnitt kann oder kann nicht bereits bei Link-Zeit für eine gegebene Architektur aufgelöst werden 1). Update (Okt 2016 - Danke an Eugene Gershnik): Auf neueren Versionen von OSXmacOS, die ausführbare Dateien mit ASLR ausführen. Der Aufruf von getsectbyname muss mit getsectiondata ersetzt werden 2). Diese API ist jedoch nur ab OS 10.7 verfügbar. Lange Geschichte kurz, man kann eine Makro-Abstraktion verwenden, die x-Plattform funktioniert. Um auf die Daten und die Größe LDVAR () und LDLEN () zuzugreifen, wird für die eigentliche externe Definition des Symbols EXTLD () verwendet: Beispiel Verwendung in einem C-Programm: Als abschließende Note muss bei der Auswahl etwas gepflegt werden Die Variablenkennung. Ld wird den Dateinamen verwenden, um den Abschnittsnamen zu erzeugen. Wenn der Dateiname Zeichen enthält, die keine gültigen C-Bezeichner sind, werden sie in Unterstriche umgewandelt. z. B. Ld - r - b binary - o example. o. Imagesexample. jpg wird eine Region binaryimagesexamplejpg erstellen. Das. Sowie der Schrägstrich und der Punkt werden zu Unterstrichen verwandelt. Dies ist kein Problem auf OSX, wo die Kennung mit der Option - sectcreate angegeben werden muss. Allerdings sind die Bezeichner auf OSX auf 16 Zeichen beschränkt. Um also über die Annäherungs-x-Plattform zu verwenden, muss der Pfad zum Dateinamen, der an ld übergeben wird, lt16-Zeichen sein und der gleiche Bezeichner muss auf dem Befehl OSX-Kompilieren angegeben werden. Ein vollständiges Projekt, das diesen Ansatz verwendet, um eine JPEG-Bilddatei und eine Javascript-Textdatei zu enthalten, ist gravid. Es beschreibt auch, wie man ein x-platform Makefile zum Erstellen der Objektdateien verwendet und die entsprechenden Flags zum OSX gcc-Befehl hinzufügt. 1) Sollten Sie mehr darüber wissen oder haben Sie Hinweise auf die Dokumentation, wenden Sie sich bitte an mich. Jeder hat eine Idee, wie man statisch kompilieren jede Ressource-Datei direkt in die ausführbare Datei oder die gemeinsame Bibliothek Datei mit GCC Zum Beispiel Id wie Bilddateien, die nie ändern (Und wenn sie es tun, muss Id die Datei trotzdem ersetzen) und wünschte nicht, dass sie im Dateisystem liegen. Wenn dies möglich ist (und ich denke, es ist, weil Visual C für Windows dies auch tun kann), wie kann ich die Dateien laden, die in der eigenen Binärdatei gespeichert sind. Ist die ausführbare Parse selbst, finden Sie die Datei und extrahieren Sie die Daten aus Es ist vielleicht eine Option für GCC, die ich noch nicht gesehen habe. Mit Suchmaschinen nicht wirklich spucken die richtige Sachen. Ich brauche das, um für geteilte Bibliotheken und normale ELF-ausführbare Dateien zu arbeiten. Jede Hilfe wird geschätzt Gibt so etwas wie: Für die Kompatibilität mit anderen Code können Sie dann entweder fmemopen verwenden, um ein normales FILE-Objekt zu erhalten, oder alternativ std :: stringstream, um einen iostream zu machen. Std :: stringstream ist nicht toll für diese aber und Sie können natürlich nur einen Zeiger überall verwenden, wo Sie einen Iterator verwenden können. Wenn Sie dies mit automake vergessen, vergessen Sie nicht, BUILTSOURCES entsprechend einzustellen. Die schöne Sache, dies zu tun, ist so: Du bekommst Text aus, also kann es in der Versionskontrolle und Patches sinnvoll sein. Es ist tragbar und gut definiert auf jeder Plattform beantwortet Feb 1 11 um 16:04 Update Ich bin gewachsen, um die Kontrolle zu bevorzugen John Ripleys Montage. incbin basierte Lösung bietet und nun eine Variante dazu verwenden. Ich habe objcopy (GNU binutils) verwendet, um die Binärdaten aus einer Datei foo-data. bin in den Datenabschnitt der ausführbaren Datei zu verknüpfen: Das gibt dir eine foo-data. o Objektdatei, die du in deine ausführbare Datei verknüpfen kannst. Die C-Schnittstelle sieht so aus, wie Sie es tun können, wenn Sie Ihre Zielarchitektur mit speziellen Beschränkungen versehen haben, wo konstante und variable Daten gespeichert sind, oder Sie diese Daten im. text-Segment speichern möchten, damit sie in denselben Speichertyp passen Als Programmcode kannst du mit den objcopy-Parametern noch mehr spielen. Sie können Binärdateien in der ausführbaren Datei mit ld Linker einbetten. Zum Beispiel, wenn Sie Datei foo. bar haben, dann können Sie es in ausführbare Datei einbetten hinzufügen die folgenden Befehle zu ld Wenn Sie aufrufen ld thru gcc dann müssen Sie hinzufügen - Wl Here - Formatbinary sagt dem Linker, dass die folgende Datei ist Binär - und --formatdefault schaltet wieder auf das Standard-Eingabeformat zurück (dies ist sinnvoll, wenn Sie weitere Eingabedateien nach foo. bar angeben). Dann kannst du auf den Inhalt deiner Datei aus dem Code zugreifen: Es gibt auch das Symbol namens binaryfoobarsize. Ich denke, es ist von Typ uintptrt aber ich habe es nicht überprüft. Ich hatte vor kurzem die Notwendigkeit, eine Datei in eine ausführbare Datei einzubetten. Da ich bei der Kommandozeile mit gcc, et al und nicht mit einem ausgefallenen RAD-Tool arbeite, das alles perfekt macht, war es mir nicht sofort klar, wie man das macht. Ein bisschen auf der Suche nach dem Netz fand einen Hack, um es im Grunde auf das Ende der ausführbaren Datei zu katzen und dann zu entschlüsseln, wo es auf einer Reihe von Informationen basierte, die ich nicht wissen wollte. Scheint, wie sollte es ein besserer Weg sein. Und es ist, seine objcopy zur Rettung. Objcopy konvertiert Objektdateien oder ausführbare Dateien von einem Format in ein anderes. Eines der Formate, die es versteht, ist binär, was im Grunde jede Datei ist, die nicht in einem der anderen Formate ist, die es versteht. Also hast du wohl die Idee vorgestellt, die Datei zu konvertieren, die wir in eine Objektdatei einbetten wollen, dann kann man einfach mit dem Rest unseres Codes verknüpfen. Lasst uns sagen, wir haben einen Dateinamen data. txt, den wir in unsere ausführbare Datei einbetten wollen: Um dies in eine Objektdatei zu konvertieren, die wir mit unserem Programm verknüpfen können, verwenden wir einfach objcopy, um eine. o-Datei zu produzieren: Das sagt, dass unsere Eingabe Datei ist im Binärformat, dass unsere Ausgabedatei im Format elf32-i386 (Objektdateien auf dem x86) sein sollte. Die Option - Binary-Architecture gibt an, ob die Ausgabedatei auf einem x86 ausgeführt werden soll. Dies wird benötigt, damit ld die Datei für die Verknüpfung mit anderen Dateien für die x86 akzeptieren wird. Man würde denken, dass die Angabe des Ausgabeformats als elf32-i386 das bedeuten würde, aber das geht nicht. Nun, da wir eine Objektdatei haben, müssen wir sie nur noch einbinden, wenn wir den Linker ausführen: Wenn wir das Ergebnis ausführen, bekommen wir das Gebet für die Ausgabe: Natürlich habe ich die ganze Geschichte noch nicht erzählt Wenn objcopy die obige Konvertierung macht, fügt man der umgewandelten Objektdatei einige Linkersymbole hinzu: Nach der Verknüpfung geben diese Symbole den Anfang und das Ende der eingebetteten Datei an. Die Symbolnamen werden durch Voranstellen von Binär und Hinzufügen von Anfang oder Ende des Dateinamens gebildet. Wenn der Dateiname alle Zeichen enthält, die in einem Symbolnamen ungültig sind, werden sie in Unterstriche umgewandelt (zB data. txt wird datatxt). Wenn du bei der Verknüpfung mit diesen Symbolen ungelöste Namen bekommst, mach ein Hexdump - C auf die Objektdatei und sieh dir das Ende des Dumps für die Namen an, die objcopy gewählt haben. Der Code, um die eingebettete Datei tatsächlich zu benutzen, sollte nun vernünftigerweise offensichtlich sein: Eine wichtige und subtile Sache zu beachten ist, dass die Symbole zu den Objektdatei arent Variablen hinzugefügt werden. Sie enthalten keine Daten, sondern ihre Adresse ist ihr Wert. Ich erkläre sie als Typ char, weil es für dieses Beispiel bequem ist: die eingebetteten Daten sind Zeichendaten. Allerdings könntest du sie als irgendetwas deklarieren, da int, wenn die Daten ein Array von ganzen Zahlen sind, oder als struct foobart, wenn die Daten irgendeine Reihe von foo Bars waren. Wenn die eingebetteten Daten nicht einheitlich sind, dann ist char wahrscheinlich die bequemste: nehmen Sie ihre Adresse und werfen Sie den Zeiger auf den richtigen Typ, wie Sie die Daten durchqueren. Beantwortet Apr 1 11 bei 20: 39X86-64 Anweisung Encoding 1: Wenn ein REX-Präfix verwendet wird, werden SPL, BPL, SIL und DIL verwendet. Andernfalls werden ohne REX Präfix AH, CH, DH und BH verwendet. Legacy-Präfixe Jede Anweisung kann bis zu vier Präfixe haben. Manchmal ist ein Präfix für die Anweisung erforderlich, während es seine ursprüngliche Bedeutung verliert (d. h. ein obligatorisches Präfix). Folgende Präfixe können verwendet werden: Präfixgruppe 1 0xF0: LOCK Präfix 0xF2: REPNEREPNZ Präfix 0xF3: REP oder REPEREPZ Präfix Präfix Gruppe 2 0x2E: CS Segment Override 0x36: SS Segment Override 0x3E: DS Segment Override 0x26: ES Segment Override 0x64: FS Segment Override 0x65: GS Segment Override 0x2E: Branch nicht genommen 0x3E: Zweig genommen Präfix Gruppe 3 0x66: Operand-Size Override Präfix Präfix Gruppe 4 0x67: Adressgröße Override Präfix Wenn es zwei oder mehr Präfixe gibt Eine einzelne Gruppe, das Verhalten ist undefiniert. Einige Prozessoren ignorieren die nachfolgenden Präfixe aus derselben Gruppe oder verwenden nur das letzte für jede Gruppe angegebene Präfix. LOCK-Präfix Mit dem LOCK-Präfix werden bestimmte read-modify-write-Anweisungen atomar ausgeführt. Das LOCK-Präfix kann nur mit den folgenden Anweisungen oder einer ungültigen Opcode-Ausnahme verwendet werden: ADC, ADD, AND, BTC, BTR, BTS, CMPXCHG, CMPXCHG8B, CMPXCHG16B, DEC, INC, NEG, NOT, ODER, SBB, SUB, XADD, XCHG und XOR. REPNEREPNZ-, REP - und REPEREPZ-Präfixe Die Wiederholungspräfixe führen dazu, dass String-Handlungsanweisungen wiederholt werden. Das REP-Präfix wiederholt die zugehörige Anweisung bis zu CX-Zeiten und verringert CX bei jeder Wiederholung. Es kann mit den Anweisungen INS, LODS, MOVS, OUTS und STOS verwendet werden. REPE und REPZ sind Synonyme und wiederholen die Anweisung bis CX 0 erreicht oder wenn ZF auf 0 gesetzt ist. Es kann mit den Anweisungen CMPS, CMPSB, CMPSD, CMPSW, SCAS, SCASB, SCASD und SCASW verwendet werden. REPNE und REPNZ sind auch Synonyme und wiederholen die Anweisung bis CX 0 erreicht oder wenn ZF auf 1 gesetzt ist. Es kann mit den CMPS-, CMPSB-, CMPSD-, CMPSW-, SCAS-, SCASB-, SCASD - und SCASW-Anweisungen CS, SS, DS, ES-, FS - und GS-Segment-Override-Präfixe Segment-Overrides werden mit Anweisungen verwendet, die auf Nicht-Stack-Speicher verweisen. Das Standardsegment wird durch die Anweisung impliziert und unter Verwendung eines spezifischen Overrides erzwingt die Verwendung des spezifizierten Segments für Speicheroperanden. In 64-Bit werden die CS-, SS-, DS - und ES-Segmentüberschreibungen ignoriert. Zweig-Tennennot-Präfixe Branch-Hinweise können verwendet werden, um die Auswirkungen der Zweig-Fehlverhalten etwas zu verringern. Der Zweig ist ein guter Hinweis, während der Zweig kein Hinweis ist ein schwacher Hinweis. Die Zweig-Hinweise werden nur von Intel seit dem Pentium 4 unterstützt. Ob sie auf AMD-Architekturen verwendet werden, hat überhaupt keine (positive oder negative) Wirkung. Operand-Size - und Address-Size-Override-Präfix Die Standard-Operandengröße und die Adressgröße können mit diesem Präfix überschrieben werden. Siehe folgende Tabelle: 1: Bestimmte Anweisungen, die auf 64-Bit-Operanden verweisen (oder fixiert sind) und das REX-Präfix hierfür nicht benötigen, siehe diese Tabelle. NASM bestimmt die Operandengröße durch Betrachten der MODRM. reg oder (für ein Register) MODRM. rm Felder. Wenn sie beide 32-Bit sind, wird die Operandengröße 32-Bit. Gleich für 16-Bit und 64-Bit. Wenn sie sich unterscheiden, tritt bei der Kompilierzeit ein Fehler auf. Die Adressgröße wird bestimmt, indem man (für einen Speicheroperanden) das Feld MODRM. rm oder die SIB. base betrachtet. SIB. index und Verschiebung in dieser Reihenfolge. Wenn also SIB. base ein 16-Bit-Register (wie zB AX) verwendet, wird die Adressgröße 16-Bit. Bei Verwendung einer 32-Bit-Verschiebung wird die Verschiebung abgeschnitten. Der x86-64-Befehlssatz definiert viele Opcodes und viele Möglichkeiten, sie zu codieren, abhängig von mehreren Faktoren. Legacy-Opcodes Legacy (und x87) Opcodes bestehen aus dieser Reihenfolge: Obligatorisches Präfix Bestimmte Anweisungen (vor allem die SIMD-Befehle) benötigen ein obligatorisches Präfix (0x66, 0xF2 oder 0xF3), das wie ein normales Modifikator-Präfix aussieht. Wenn ein obligatorisches Präfix erforderlich ist, wird es mit den Modifikatorpräfixen vor dem REX-Präfix (falls vorhanden) ausgegeben. REX-Präfix Das REX-Präfix ist nur im Langmodus verfügbar. Ein REX-Präfix muss codiert werden, wenn: die 64-Bit-Operandengröße verwendet wird und die Anweisung nicht standardmäßig auf 64-Bit-Operandengröße oder mit einem der erweiterten Register (R8 bis R15, XMM8 bis XMM15, YMM8 bis YMM15, CR8 bis CR15 und DR8 bis DR15) oder unter Verwendung eines der einheitlichen Byte-Register SPL, BPL, SIL oder DIL. Ein REX-Präfix darf nicht codiert werden, wenn: eines der High-Byte-Register AH, CH, BH oder DH verwendet wird. In allen anderen Fällen wird das REX-Präfix ignoriert. Die Verwendung von mehreren REX-Präfixen ist undefiniert, obwohl die Prozessoren nur das letzte REX-Präfix verwenden. Anleitungen, die standardmäßig auf 64-Bit-Operandengröße im Langmodus eingestellt sind: Der Opcode kann 1, 2 oder 3 Bytes lang sein. Abhängig von der Opcode-Escape-Sequenz wird eine andere Opcode-Map ausgewählt. Mögliche Opcode-Sequenzen sind: Beachten Sie, dass Opcodes angeben können, dass das REG-Feld im ModRM-Byte auf einen bestimmten Wert festgelegt ist. VEXXOP-Opcodes Ein VEXXOP-Präfix muss codiert werden, wenn: der Befehl nur seinen VEXXOP-Opcode hat und kein Legacy-Opcode oder 256-Bit-YMM-Register verwendet wird oder mehr als drei Operanden verwendet werden (z. B. zerstörungsfreie Quelloperationen) oder bei Verwendung von 128-Bit-XMM Zielregister, die Bits 128-255 des entsprechenden YMM-Registers müssen gelöscht werden. Ein VEXXOP-Präfix darf nicht codiert werden, wenn: bei Verwendung von 128-Bit-XMM-Zielregistern die Bits 128-255 des entsprechenden YMM-Registers nicht geändert werden dürfen. Es gibt viele VEX - und XOP-Befehle, die alle mit dem 3-Byte-VEXXOP-Escape-Präfix codiert werden können. Die VEX - und XOP-Escape-Präfixe verwenden Felder mit folgender Semantik: 1: Im geschützten Kompatibilitätsmodus ist dies nur disp32. Aber im langen Modus ist dies RIPdisp32 (für 64-Bit-Adressen) oder EIPdisp32 (für 32-Bit-Adressen, d. h. mit Adressgrößen-Override-Präfix, siehe hier). 2: Im Langmodus, um disp32 wie im geschützten Kompatibilitätsmodus zu codieren, verwenden Sie das SIB-Byte. RIPEIP-relative Adressierung Die Adressierung in x86-64 kann relativ zum aktuellen Befehlszeiger Wert sein. Dies wird mit den RIP (64-Bit) und EIP (32-Bit) Befehlszeigerregistern angezeigt, die dem Programm nicht anderweitig ausgesetzt sind und physisch nicht existieren können. Die RIP-relative Adressierung ermöglicht es, dass Objektdateien ortsunabhängig sind. Das SIB-Byte hat folgende Felder: Dieses Feld zeigt den Skalierungsfaktor von SIB. index an, wobei s (wie in den Tabellen verwendet) gleich 2 SIB. scale ist. Das Indexregister zu verwenden. Siehe Register für die Werte, die für jedes Register verwendet werden sollen. Die REX. X, VEX. X-Feld kann dieses Feld mit 1 höchstwertigen Bit auf 4 Bits insgesamt erweitern. Das Basisregister zu verwenden. Siehe Register für die Werte, die für jedes Register verwendet werden sollen. Die REX. B, VEX. B-Feld kann dieses Feld mit 1 höchstwertigem Bit bis 4 Bits insgesamt verlängern. 3264-Bit-Adressierung Die Bedeutung des SIB-Bytes bei der Verwendung von 32- oder 64-Bit-Adressierung ist wie folgt. Das ModRM Bytes Mod Feld und das SIB Bytes Indexfeld werden vertikal verwendet, das SIB Bytes Basisfeld und REXVEXXOP. B Bit horizontal. Das s ist der Skalierungsfaktor. B. Base X. Index und Mod sind binär. 1: Kein Basisregister ist codiert. 2: Kein Indexregister ist codiert. Verschiebung Ein Verschiebungswert ist ein 1, 2, 4 oder 8 Byte Versatz, der der berechneten Adresse hinzugefügt wird. Wenn eine 8-Byte-Verschiebung verwendet wird, wird kein unmittelbarer Operand codiert. Der Verschiebungswert, falls vorhanden, folgt den oben beschriebenen ModRM - und SIB-Bytes. Wenn die ModRM - oder SIB-Tabellen angeben, dass ein Disp-Wert erforderlich ist oder ohne ModRM-Byte die Verwendung von moffset (AMD) oder moffs (Intel) in der mnemonischen Syntax des Befehls, dann sind die Verschiebungsbytes erforderlich. Einige Anweisungen erfordern einen sofortigen Wert. Die Anweisung (und die Operandengröße in der obigen Tabelle) bestimmen die Länge des unmittelbaren Wertes. Die imm8-Mnemotechnik (oder 8-Bit-Operandengröße) bedeutet einen Ein-Byte-Sofortwert, imm16 (oder 16-Bit-Operandengröße) bedeutet einen Zwei-Byte-Sofortwert, imm32 (oder 32-Bit-Operandengröße) einen Vier-Byte-Wert Und imm64 (oder 64-Bit-Operandengröße) einen 8-Byte-Wert. Wenn ein 8-Byte-Sofortwert codiert wird, kann keine Verschiebung codiert werden. Externe Referenzen
No comments:
Post a Comment