2012-02-10 20 views
23

Cosa intende la seguente riga:Cosa significa un asterisco * prima di un indirizzo nell'assembly AT & T x86-64?

... 
401147: ff 24 c5 80 26 40 00 jmpq *0x402680(,%rax,8) 
... 

Che cosa significa l'asterisco davanti l'indirizzo di memoria significa? Inoltre, cosa significa quando manca il metodo di accesso alla memoria è il primo valore di registro?

Di solito è qualcosa di simile ("% register",% rax, 8), ma in questo caso non ha il primo registro.

Qualche consiglio?

+3

lol, ma devo saperlo così posso eseguire il debug del codice c. e anche per gli esami di classe. – de1337ed

risposta

4

È un salto a un indirizzo contenuto nella memoria. L'indirizzo è memorizzato all'indirizzo rax*8+0x402680, dove rax è il valore corrente rax (quando questa istruzione viene eseguita).

14

fare le cose in sintassi Intel fa sempre cose più chiaro:

FF24C5 80264000 JMP QWORD PTR [RAX*8+402680] 
+0

Chiunque abbia votato, cura di spiegare perché? La sintassi antiintelligente è * non * un motivo ... – Necrolis

+17

Non ho fatto downvote, ma non stai esattamente spiegando cosa sta succedendo .. –

+3

@MichaelFoukarakis: oltre a ripetere il matematico in inglese, non c'è molto da aggiungere quando si utilizza la sintassi Intel. – Necrolis

14

E 'in & T sintassi assembly:

  • sorgente viene prima destinazione
  • suffissi mnemoniche indicano la dimensione degli operandi (q per quad, ecc.)
  • i registri hanno il prefisso % e valori immediati con $
  • indirizzi efficaci sono in forma DISP(BASE, INDEX, SCALE) (DISP + BASE + INDEX * SCALE)
  • salto assoluto/chiamare operandi indicati con * (al contrario di IP relativa)

Così, avere un jmpq per saltare all'indirizzo assoluto che è memorizzato in %rax * 8 + 0x402680, ed è una parola quadrupla.

+0

ma gli asterischi di fronte fanno la differenza? Capisco che quello che hai detto ha senso altrimenti. Stavo pensando che prima l'asterisco porterà i dati fuori dalla posizione di memoria 0x402680. Quindi basicamente, diventerà% rax * 8 + mem [0x402680] – de1337ed

+0

L'asterisco specifica solo che è un salto in assoluto. 'jmp' estrarrà i dati dalla posizione di memoria specificata a prescindere. –

17

In realtà questa è la tabella calcolata jmp, dove 0x402680 è l'indirizzo di tabele e rax è l'indice del puntatore a 8 byte (qword).

+3

Le tabelle di salto vengono spesso utilizzate nel codice assembly quando il codice C sta completando if-else o istruzioni switch. Permette di passare il controllo in tempo costante, invece di dover controllare molti controlli di uguaglianza individuale. – Eagle

4

Come ha scritto Necrolis, la sintassi Intel lo rende un po 'più ovvio, ma lo RTN è molto più chiaro. La linea

jmpq *0x402680(,%rax,8) 

sarebbe descritto in RTN da:

RIP <- M[0x402680 + (8 * RAX)] 

dove M è la memoria di sistema.

Come tale, possiamo scrivere la forma generale jmpq *c(r1, r2, k), dove c è una costante immediato, r1 e r2 sono registri di uso generale e k è 1 (default), 2, 4 o 8:

RIP <- M[c + r1 + (k * r2)] 
4

jmpq è solo un salto non condizionale a un determinato indirizzo. La "q" significa che abbiamo a che fare con parole quadruple (lunghe 64 bit).

*0x402680(,%rax,8): questo è un modo per scrivere un indirizzo in assembly x-86. Hai ragione nel dire che di solito c'è un registro prima della prima virgola, ma continui a seguire le stesse regole se non viene specificato alcun registro.

Il formato funziona in questo modo: D(reg1, reg2, scalingFactor) dove D sta per spostamento. Il dislocamento è fondamentalmente solo un numero intero. reg1 è il primo o il registro di base. reg2 è il secondo registro e scalingFactor è uno di 2, 4, 8 (forse anche 1, ma non ne sono sicuro). Ora puoi ottenere il tuo indirizzo aggiungendo semplicemente i valori in questo modo: Spostamento + (valore a reg1) + scalingFactor * (valore a reg2).

Non sono completamente sicuro di ciò che l'asterisco davanti all'indirizzo è per, ma la mia ipotesi è che ciò significa che il valore di spostamento è memorizzato a quell'indirizzo.

Spero che questo aiuti.

1

Minimal esempio Per maggiore chiarezza:

.data 
    # Store he address of the label in the data section. 
    symbol: .int label 
.text 
    # Jumps to label. 
    jmp *symbol 
    label: 

Senza il *, sarebbe saltare all'indirizzo del symbol nella sezione .data e segfault.

mi sento questa sintassi è un po 'incoerente, perché per la maggior parte delle istruzioni:

mov symbol, %eax 
mov label, %eax 

muove già i dati all'indirizzo symbol, e $symbol viene utilizzato per l'indirizzo. La sintassi Intel è più coerente in questo punto in quanto utilizza sempre [] per il dereferenziamento.

Il * è ovviamente un mnemonico per l'operatore di dereferenza C *ptr.

Problemi correlati