2015-04-13 14 views
7

Si consideri il seguente codice, compilato su un 32 bit Ubuntu 14.04.2 con gcc 4.8.2Che significato ha, se esiste, il byte Mod R/M per l'istruzione di salto incondizionato 0xFF?

#include <unistd.h> 

int main(){ 
    _exit(0); 
} 

Se apro questo codice in gdb e corro disas /r _exit, ricevo il seguente.

(gdb) disas /r _exit 
Dump of assembler code for function [email protected]: 
    0x080482f0 <+0>:  ff 25 0c a0 04 08  jmp *0x804a00c 
    0x080482f6 <+6>:  68 00 00 00 00 push $0x0 
    0x080482fb <+11>: e9 e0 ff ff ff jmp 0x80482e0 
End of assembler dump. 
(gdb) 

Il manuale di Intel ci dice che ff è il codice operativo per JMP, mentre gli ultimi quattro byte sono chiaramente l'indirizzo di destinazione. Dopo alcune ricerche sulla struttura delle istruzioni Intel, lo 25 sembra essere un byte Mod R/M, ma non sono riuscito a trovare il modo in cui il byte Mod R/M deve essere interpretato rispetto all'istruzione JMP.

Ho già letto su general interpretation of the Mod R/M byte, ma non capisco quale significato specifico il byte porti nell'output disas in alto.

Qual è il significato specifico di 0x25 qui e qual è l'interpretazione generale del byte Mod R/M rispetto a JMP?

risposta

9

Il significato del byte MODRM è lo stesso per opcode 0xFF come per qualsiasi altra istruzione che utilizza il byte MODRM.

Il vostro miglior riferimento per questo è lo Intel Instruction set manuals online. La sezione 2 e la pagina sulle istruzioni JMP sono quelle necessarie per interpretare correttamente i bit MODRM per questo opcode.

L'interpretazione di "0x25" è:

  • (Bit 7-6) MOD = binari 00
  • (bit 5-3) REG/Opcode = binari 100
  • (bit 2- 0) R/M = binario 101

MOD = 00 e R/M = binario 101 significano "uso disp32" (un indirizzo a 32 bit) seguendo il byte MODRM. Lo spostamento a 32 bit che segue il byte MODRM è la posizione di memoria. Puoi vedere che corrisponde al valore dell'istruzione jmp disassemblata nella tua lista di debug.

Si potrebbe essere confusi su cosa opcode 0xFF significa; non significa necessariamente "JMP".L'x86 usa spesso i bit RegRoc/Opcode MODRM per modificare il significato del byte opcode , per selezionare una particolare istruzione.

Con opcode 0xFF, il Reg/bit Opcode vengono interpretati come più opcode bit:

  • bit Reg/Opcode = binario 100 (scritta "/ 4" nel manuale Intel) seleziona il istruzione "jmp near absolute indirect". L'x86 ha i cosiddetti registri di segmento incluso CS; "jmp near" in questo caso significa "non caricare CS".
  • Reg/Opcode == 101 ("/ 5") significa "jmp far" (carica il CS) e non è usato nella pratica moderna.
  • Reg/Opcode con altri valori specifica le istruzioni che non sono JMP.
4

In realtà, questi ultimi 4 byte non sono l'indirizzo di destinazione. L'istruzione ff 25 0c a0 04 08 è un'istanza di jmp rm32 (salto assoluto indiretto), gli ultimi 4 byte sono in realtà l'indirizzo da cui verrà letto il target di salto.

Il ModRM byte 25h, come si può vedere nel this table, ha una parte/cifra di 4 (che lo rende un jmp rm32, altre istruzioni che devono opcode byte ff sono inc rm32, dec rm32, call rm32, call m16:32, jmp m16:m32, push rm32, tutto distinto dal byte ModRM). Il resto del byte ModRM 25h significa che l'operando è un indirizzo di memoria del modulo [sdword].

Problemi correlati