Domanda

L'articolo di Wikipedia su x86 assembly dice che "il registro IP non è possibile accedere dal programmatore direttamente ".

mezzi direttamente con le istruzioni come MOV e aggiungere.

Perché no? Qual è la ragione di questo? Quali sono le restrizioni tecniche?

È stato utile?

Soluzione

Non è possibile accedervi direttamente, perché non c'è nessun caso uso legittimo. Avere qualsiasi arbitrario cambiamento di istruzioni eip renderebbe predizione dei salti molto difficile, e probabilmente aprire tutta una serie di problemi di sicurezza.

È possibile modificare eip utilizzando jmp, call o ret. Non ci si può leggere direttamente o scrivere eip utilizzando le normali operazioni

Impostazione eip a un registro è semplice come jmp eax. È anche possibile fare push eax; ret, che spinge il valore della eax nello stack e ritorna poi (cioè pop e salti). La terza opzione è call eax che fa una chiamata all'indirizzo in eax.

La lettura può essere fatto in questo modo:

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

Altri suggerimenti

Che sarebbe stato un possibile progetto per x86. ARM non esporre il suo contatore di programma per la lettura / scrittura come R15 . Questo è insolito, però.

Permette una funzione molto compatto prologo / epilogo, insieme con la capacità di spingere o pop registri multipli con una sola istruzione: push {r5, lr} in entrata, e pop {r5, pc} al ritorno. (Popping il valore salvato del registro di collegamento nel program counter).

Tuttavia, si rende ad alta Potenza / out-of-order implementazioni ARM meno conveniente, ed è stato abbandonato per AArch64.


è possibile, ma consuma uno dei registri . 32-bit ARM ha 16 registri interi (compresi PC), quindi un numero di registro richiede 4 bit per codificare in codice macchina ARM. Altro registro è quasi sempre legato come puntatore pila, quindi ARM ha 14 generici registri interi. (LR può essere memorizzato nello stack, in modo che possa essere e viene utilizzato come registro generico all'interno dei corpi funzione).

La maggior parte x86 moderna viene ereditato dal 8086. È stato progettato con la codifica di istruzioni a lunghezza variabile abbastanza compatto, e solo 8 registri, richiedono solo 3 bit per ogni src e dst registro nel codice macchina.

In originale 8086, non erano molto polivalente, e SP-indirizzamento relativo non è possibile in modalità a 16 bit, in modo essenzialmente 2 registri (SP e BP) sono legati per roba pila. Ciò lascia soltanto 6 registri di uso alquanto-generale, e avendo uno di essi sia PC invece di impiego generale sarebbe una enorme riduzione registri disponibili, aumentando notevolmente la quantità di fuoriuscita / ricarica in tipico codice.


AMD64 aggiunto r8-R15, e il modo di indirizzamento RIP-relativa. lea rsi, [rip+whatever], e modi di indirizzamento RIP-relativa per l'accesso diretto ai dati statici e costanti, è tutto ciò che serve per il codice indipendente dalla posizione efficiente. istruzioni JMP indiretti sono del tutto sufficienti per la scrittura su RIP.

non c'è davvero nulla da guadagnare permettendo istruzioni arbitrarie da utilizzare per leggere o scrivere al PC, dal momento che si può sempre fare la stessa cosa con un registro intero e un salto indiretto. Sarebbe svantaggio quasi pura per la R15 di x86-64 di essere la stessa cosa di RIP, soprattutto per performace della dell'architettura come bersaglio compilatore. (Asm scritto a mano roba strana era già molto una cosa di nicchia non comune entro il 2000, quando AMD64 è stata progettata.)

Quindi AMD64 è davvero la prima volta che x86 potrebbe plausibilmente hanno guadagnato un contatore di programma completamente esposti come ARM, ma c'erano molte ragioni buone per non farlo.

penso che ha fatto sì che il registro IP non è possibile accedere direttamente allo stesso modo gli altri registri sono accessibili. I programmatori possono sicuramente scrivere a IP, ad esempio, mediante l'emissione di un'istruzione di salto.

jmp imposterà il registro EIP.

questo codice imposterà EIP a 00.401.000:

mov eax, 00401000
jmp eax ;set Eip to 00401000

e per ottenere EIP

call GetEIP
.
.
GetEIP:
mov eax, [esp]
ret
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top