Frage

Der Wikipedia -Artikel über die X86 -Versammlung Laut "Das IP -Register kann der Programmierer nicht direkt zugegriffen werden."

Direkt bedeutet direkt mit Anweisungen wie MOV und Add.

Warum nicht? Was ist der Grund dafür? Was sind die technischen Einschränkungen?

War es hilfreich?

Lösung

Sie können nicht direkt darauf zugreifen, da es keinen legitimen Anwendungsfall gibt. Eine willkürliche Änderung des Anweisungen haben eip würde die Branchenvorhersage sehr schwierig machen und wahrscheinlich eine ganze Reihe von Sicherheitsproblemen eröffnen.

Sie können bearbeiten eip Verwendung jmp, call oder ret. Sie können einfach nicht direkt von oder schreiben eip Verwenden normaler Vorgänge

Einstellung eip zu einem Register ist so einfach wie jmp eax. Sie können es auch tun push eax; ret, was den Wert von vorantreibt eax zum Stapel und kehrt dann zurück (dh Pops und Sprünge). Die dritte Option ist call eax Welcher Anruf an die Adresse in EAX macht.

Lesen kann so erfolgen:

call get_eip
  get_eip:
pop eax ; eax now contains the address of this instruction

Andere Tipps

Das wäre ein mögliches Design für x86 gewesen. Arm tut Entdecken Sie seinen Programmzähler für Lesen/Schreiben als R15. Das ist jedoch ungewöhnlich.

Es ermöglicht einen sehr kompakten Funktionsprolog/Epilog, zusammen mit der Fähigkeit, mehrere Register mit einer einzigen Anweisung zu schieben oder zu popieren: push {r5, lr} bei der Einreise und pop {r5, pc} zurückgeben. (Stößen Sie den gespeicherten Wert des Link -Registers in den Programmzähler).

Es macht jedoch die Implementierungen von hohen und außerordentlichen Arms weniger bequem und wurde für AARGRO64 fallen gelassen.


So Es ist möglich, verbraucht aber eines der Register. 32-Bit-Arm hat 16 Ganzzahlregister (einschließlich PC), sodass eine Registrierungsnummer 4 Bits zum Enkodieren in ARM-Maschinencode benötigt. Ein weiteres Register ist fast immer als Stapelzeiger gebunden, sodass ARM 14 allgemeine Ganzzahlregister hat. (LR kann im Stapel gespeichert werden, sodass er als allgemeines Register in Funktionskörpern verwendet werden kann.)

Der größte Teil des modernen X86 wird von 8086 geerbt. Es wurde mit einer relativ kompakten Befehlskodierung der variablen Länge und nur 8 Registern entworfen, wobei nur 3 Bit für jedes SRC- und DST-Register im Maschinencode erforderlich sind.

Im ursprünglichen 8086 waren sie nicht sehr allgemein, und die SP-Relative ist im 16-Bit-Modus nicht möglich, daher sind im Wesentlichen 2 Register (SP und BP) für Stapelmaterial gebunden. Dies hinterlässt nur 6 Generalzweckregister, und wenn einer von ihnen der PC anstelle von allgemeinerzwecke ist, wäre eine enorme Verringerung der verfügbaren Register, was die Menge an Verschüttung/Nachladen im typischen Code erheblich erhöht.


AMD64 fügte R8-R15 und den RIP-Relativ-Adressmodus hinzu. lea rsi, [rip+whatever], und rip-relative Adressierungsmodi für den direkten Zugriff auf statische Daten und Konstanten sind alles, was Sie für einen effizienten positionsunabhängigen Code benötigen. Indirekte JMP -Anweisungen reichen für das Schreiben völlig aus, um zu rippen.

Es ist nicht wirklich etwas zu erwerben, indem beliebige Anweisungen zum Lesen oder Schreiben des PCs verwendet werden können, da Sie immer dasselbe mit einem Ganzzahlregister und einem indirekten Sprung tun können. Es wäre fast ein reiner Nachteil für X86-64s R15, das gleiche zu sein wie RIP, insbesondere für das Ausspiel der Architektur als Compiler-Ziel. (Handgeschriebenes ASM-seltsames Zeug war bis 2000 bereits eine ungewöhnliche Nischensache, als AMD64 entworfen wurde.)

AMD64 ist also das erste Mal, dass X86 plausibel einen voll ausgestatteten Programmzähler wie Arm gewonnen haben, aber es gab viele gute Gründe, dies nicht zu tun.

Ich denke, sie haben gemeint, dass auf das IP -Register nicht direkt auf die anderen Register zugegriffen werden kann. Programmierer können definitiv an IP schreiben, zum Beispiel, indem sie eine Sprunganweisung erteilen.

jmp wird die festlegen EIP registrieren.

Dieser Code setzt EIP auf 00401000:

mov eax, 00401000
jmp eax ;set Eip to 00401000

und zum bekommen EIP

call GetEIP
.
.
GetEIP:
mov eax, [esp]
ret
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top