2010-09-14 12 views
9

Il codice seguente mostra solo una finestra di messaggio sullo schermo.
Gli indirizzi sono fissi per agevolare:Definizione di byte in GCC Assieme in linea in Dev-C++ (. Ascii in sintassi AT & T su Windows)

int main() 
{ 
    asm("xorl %eax, %eax  \n" 
     "xorl %ebx, %ebx  \n" 
     "xorl %ecx, %ecx  \n" 
     "xorl %edx, %edx  \n" 
     "pushl %ecx    \n" //$0x0 
     "pushl $0x20206c6c  \n" //" ll" 
     "pushl $0x642e3233  \n" //"d.23" 
     "pushl $0x72657375  \n" //"resu" 
     "movl %esp, %ecx  \n" //store "user32.dll" address in %ecx 
     "movl $0x7c801d7b, %ebx \n" //store address of LoadLibraryA in %ebx 
     "pushl %ecx    \n" 
     "call *%ebx    \n" 
     "movl $0xef30675e, %ecx \n" 
     "addl $0x11111111, %ecx \n" 
     "pushl %ecx    \n" 
     "pushl $0x42656761  \n" 
     "pushl $0x7373654d  \n" 
     "movl %esp, %ecx  \n" 
     "pushl %ecx    \n" 
     "pushl %eax    \n" 
     "movl $0x7c80ae40, %ebx \n" 
     "call *%ebx    \n" 
     "movl %esp, %ecx  \n" 
     "xorl %edx, %edx  \n" 
     "pushl %edx    \n" 
     "pushl %ecx    \n" 
     "pushl %ecx    \n" 
     "pushl %edx    \n" 
     "call *%eax    \n" 
     "xorl %eax, %eax  \n" 
     "pushl %eax    \n" 
     "movl $0x7c81cb12, %eax \n" 
     "call *%eax    \n" 
    ); 
} 

(io non ha commentato tutto il codice perché la mia domanda non è veramente il codice)

La mia domanda è: C'è un modo per scrivere il stringa "user32.dll" in assembly inline senza spingere manualmente nello stack? Voglio dire come questo in NASM: db 'Hello'

so che in AT & sintassi T ho potuto fare .ascii 'Hello' o .string 'Hello' ma come circa in linea gcc?

Si prega di notare che sto usando Dev-C++ su Windows XP SP3

Grazie!

risposta

9

Sì, facendo uso delle direttive assembler all'interno dell'assemblatore in linea. Il trucco sta nel mettere la stringa nel posto giusto (la sezione dei dati), che puoi fare cambiando usando .section .data e poi tornando indietro con .section .text.

È necessario fornire un'etichetta ai dati in modo che sia possibile fare riferimento ad essa; Raccomanderei di utilizzare la sintassi dell'etichetta locale qui (dove l'etichetta è un numero, ad esempio 1: e la si fa riferimento come 1b per la prima etichetta 1: all'indietro o 1f per la prima etichetta 1: in avanti - vedere lo GNU assembler documentation per ulteriori dettagli) .

Ti piace questa:

int main(void) 
{ 
    asm(".section .data  \n" 
     "1: .asciz \"Hello\" \n" 
     ".section .text  \n" 
     "pushl $1b   \n" 
     "call _puts   \n" 
     "add $4, %esp  \n" 
    ); 
    return 0; 
} 

non ho un sistema Windows a portata di mano per testare questo, ma si compila OK e sembra che dovrebbe fare la cosa giusta con un cross-compilatore MinGW su Linux (Credo che Dev-C++ sia basato su MinGW).

Nota: questa tecnica è generalmente applicabile quando si utilizza una toolchain GNU. Se stai creando binari ELF (ad esempio Linux nativo), c'è un modo più ordinato per tornare alla sezione di testo, che è quella di usare .previous, che significa "qualunque fosse la sezione precedente alla precedente .section". (L'esempio precedente funziona su Linux se si modifica _puts in puts per tenere conto delle diverse convenzioni di prefisso dei simboli.)

+0

Cool! "1:" significa che è un'etichetta all'indirizzo della stringa? L'istruzione "pushl $ 1b" preme l'indirizzo di "Hello"? Cosa fa ".precedente"? Grazie! – jyz

+0

":" .previous "funziona su Windows? Non riesco a .. Sto usando Dev-Cpp Portable – jyz

+1

@jyzuz: no, non sembra, mi dispiace, ho aggiornato la mia risposta con un '1:' è davvero un'etichetta, e '1b' si riferisce ad essa (vedi la documentazione dell'assembler alla quale ho collegato nella mia risposta aggiornata) quindi sì,' pushl $ 1b' spinge il valore dell'etichetta - che è l'indirizzo della stringa - come costante sullo stack. –

Problemi correlati