2010-03-30 12 views
7
0x004012d0 <main+0>: push %ebp 
0x004012d1 <main+1>: mov %esp,%ebp 
0x004012d3 <main+3>: sub $0x28,%esp 

Se l'indirizzo non è disponibile, possiamo calcolarlo da soli?Quanti byte sono le istruzioni compilate nell'assembly x86?

Voglio dire che abbiamo solo questa:

push %ebp 
mov %esp,%ebp 
sub $0x28,%esp 
+0

lo vuoi in fase di runtime? cioè 'asm_size (" mov esp, ebp ")'? –

+3

Questo genere di cose dipende dall'architettura hardware. Non si tratta di un problema di "analisi" ma di un problema di "ricerca del dizionario adatto". – billyswong

+0

In Linux puoi usare 'objdump -d file eseguibile' per vedere gli opcode, poi vedrai le dimensioni di ogni istruzione – jyz

risposta

0

Nel caso in cui si abbia il codice assembly in testo, sarà necessario utilizzare un assembly La routine per ottenere la rappresentazione binaria , e quindi la dimensione dell'istruzione (s). Ovviamente, dipende dall'hardware.

Ad esempio, qui è un 80x86 32-bit Assembler aperto source code (OllyDbg v1.10).

1

La prima istruzione è in [main + 0] e la seconda è in [main + 1] quindi la prima istruzione è 1 byte. La terza istruzione è in [main + 3], quindi la seconda istruzione è di due byte. Non puoi dire dall'elenco per quanto tempo è la terza istruzione, dal momento che non mostra l'indirizzo dell'istruzione 4..

3

Non è possibile determinare necessariamente la dimensione dell'istruzione dal codice mnemonico. Qui ci sono alcuni casi particolari:

  • se siete in un segmento a 16 bit, mov eax, 0 richiede un prefisso 0x66, mentre in un segmento a 32 bit non è così. Devi conoscere la dimensione del segmento.

  • in modalità a 32-bit o 16-bit è possibile codificare add eax, 1 sia come 0x40 (inc eax) o 0x83 0xc0 0x01 (add eax, 1). Cioè, ci sono alcuni mnemonici che possono essere codificati in più di un modo.

  • L'operando di memoria [eax] può codificare eax come base o indice. Se è l'indice, avrai un byte SIB aggiuntivo dopo MOD/RM.

  • in modalità a 64 bit è possibile utilizzare il prefisso REX 0x4x per codificare i registri r8 - r15. Tuttavia, è possibile utilizzare 0x40 come una sorta di byte REX null, che aggiungerà un altro byte alle istruzioni.

  • È possibile utilizzare le sostituzioni del segmento, anche se il segmento esplicito è uguale a quello implicito.

Esistono molti altri modi per codificare un'istruzione utilizzando più o meno byte. Un buon assemblatore dovrebbe probabilmente usare sempre quello più corto, ma certamente non è richiesto dall'architettura. La cosa buona è che se studi il volume 2 del Manuale per gli sviluppatori del software Intel IA-32, dovresti essere in grado di risolverlo da solo.

+0

Infatti, la codifica delle istruzioni, in particolare su x86/x64, è ambigua, sia nel senso che due mnemonici di assembly possono descrivere la stessa istruzione ('xchg ax, ax' e' nop'), e che potrebbe essere due opcode binari per un assembly mnemonico ('inc eax' in 32 bit - sia' 0x40' che '0xff 0xc0'). A volte sono anche deliberatamente ambigui per un motivo, come le istruzioni di 'NOP', vedi http://stackoverflow.com/questions/2123000/dummy-operations-handling-of-intel-processor/2124407#2124407 –

+0

molte vecchie istruzioni possono essere ricodificati con prefisso VEX o EVEX, quindi avranno rappresentazioni multiple con lunghezza diversa –

+0

@ LưuVĩnhPhúc: non è abbastanza preciso. Le istruzioni SSE codificate come AVX utilizzando VEX o EVEX presentano un comportamento leggermente diverso: * Hanno requisiti di abilitazione diversi. Ad esempio, VEX richiede CR4.OSXSAVE e vari bit in XCR0. * Le istruzioni AVX a 128 bit cancellano i bit superiori di YMM o ZMM, mentre le istruzioni SSE corrispondenti lasciano intatti i bit superiori –

0

Se possibile, l'assemblatore genera un elenco.Questo mostrerà il tuo codice sorgente e accanto ci sarà la rappresentazione binaria delle istruzioni e tutto ciò che devi fare è contare quanti byte ci sono e poi hai le dimensioni.

Problemi correlati