2016-04-11 24 views
1

Ich schreibe einen JIT-Compiler (nur 64-Bit, Windows). Ich muss auf Variablen des C++ Programms zugreifen, durch Verweis (Zeiger).C++ Zeiger in 64-Bit-Anweisungen

Beispiel: eine 32-Bit-Ganzzahl aus dem Speicher zu einem 32-Bit-Register Hinzufügen, unter Verwendung dieser Anweisung:

opcode "03 /r" : ADD r32, m32. (valid in 64bit mode) 

leider dies für eine 32-Bit-Verschiebung wird gefragt, aber ich (? Nur) einen 64-Bit-Zeiger auf die C++ Variable.

Meine Frage: Gibt es einen Weg, eine 32bit Verschiebung von einem 64bit C++ Zeiger zu bekommen?

Oder wenn nicht, allgemeiner, wie würde ich C++ - Variablen adressieren?

Ich habe auch versucht, den Zeiger Wert auf Rax bewegen und indirekte Adressierung [Rax] verwenden. Was auch nicht zu funktionieren scheint.

Ich habe irgend dis-Montage (Klirren) sah, und es scheint, RIP (relative Befehlszeiger), wie

mov dword ptr [rip + test], 2358 

Welche seltsam scheint, als rip Änderungen auf jede Anweisung zu verwenden (wie Soweit ich weiß).

Alle Hinweise in die richtige Richtung würden sehr geschätzt werden.

Edit: Indirekte Adressierung durch, [Rax], funktioniert jetzt! Ich hatte einen Fehler in der C++. Immer noch kein Glück mit 32-Bit-Adressierung.

+2

Warum können Sie keine 64-Bit-Anweisung verwenden? –

+0

32-Bit-Integer- oder sogar 8-Bit-Anweisungen sind im 64-Bit-Modus perfekt gültig und nützlich. Nur die Zeiger (Speicheradresse) sind 64Bit. –

+1

Das habe ich nicht gefragt. Ich wiederhole: Warum können Sie keine 64-Bit-Anweisung verwenden? –

Antwort

0

gefunden einfach die Antwort in dem Intel Developer Handbuch Band 1 Seite 70:.

„Im Allgemeinen Verschiebungen und immediates in 64-Bit-Modus nicht auf 64 Bit erweitern Sie sind immer noch auf 32 Bit und Zeichen begrenzt Bei 64-Bit-Modus wird jedoch Unterstützung für 64-Bit-Verschiebung und unmittelbare Formen der MOV-Anweisung bereitgestellt.

Und in der Instruktion Intel-Handbuch Set Reference Seite 42:

„Im 64-Bit-Modus, RIP + disp32 die ModR/M disp32 (32-Bit-Verschiebung) Codierung wird neu definiert und nicht zu sein als nur Verschiebung. Siehe Tabelle 2-7. "

So DISP32 kann im 64-Bit-Modus nur für relativ zur Befehlszeiger Adressierung verwendet werden.

+0

Oder relativ zu einem Zeiger in einem Mehrzweckregister, wie '[rax + disp32]', wenn Sie einen Zeiger auf haben eine Struktur und möchte ein Mitglied laden. Wenn Sie auf statische Daten (z. B. globale Variablen) zugreifen, können Sie auch '[disp32]' - Adressen verwenden, da das "kleine" Codemodell garantiert, dass die Adressen im niedrigen 2GiB des virtuellen Adressraums liegen. Wenn Sie Ihren JIT-kompilierten Code in den niedrigen 2GiB setzen, können Sie die normalen 'call'- und' jmp'-Anweisungen verwenden, um anderen Code zu erreichen, was einen ziemlich großen Code-Größenvorteil gegenüber 'mov r64, imm64/call r64' darstellt. weil indirekte Sprünge lutschen. –

+0

Leider, so weit ich weiß, '[disp32]' nur (um Variablen in den niedrigen 2GB zu adressieren) existiert nicht im 64-Bit-Modus. Wie Sie aus dem obigen Zitat sehen können, wird '[disp32]' als '[RIP + disp32]' interpretiert. –

+0

Verwenden Sie in der NASM-Syntax '[abs 0x1234]', um eine absolute Kodierung zu erhalten, auch wenn die DEFAULT rel-Anweisung aktiviert ist. z.B. aus objdump: '8b 04 25 34 12 00 00 mov eax, DWORD PTR ds: 0x1234', oder' mov eax, [rel 0x1234] 'assembliert zu' 8b 05 72 11 c0 ff mov eax, DWORD PTR [rip + 0xffffffffffc01172] # 1234 <_start-0x3fee81> ' –