2009-07-30 16 views
12

Perché questa stampa è inutilizzabile anziché uscire dal mio programma con garbo? Uso le chiamate di sistema in questo modo su BSD e mi chiedo che cosa mi servirebbe per farlo funzionare su Linux.Syscall da in linea asm in x86_64 Linux?

int 
main(int argc, char **argv) 
{ 
    __asm ("movq $1,%rax; movq $0,%rdi; syscall"); /* exit(0) ? */ 
    return 0; 
} 

Grazie.

risposta

13

Perché questa immondizia di stampa invece di uscire il mio programma con grazia?

Per CESA-2009-001, "Syscall 1 è uscita su i386 ma scrive su x86_64".

quello che avrei bisogno di farlo funzionare in Linux

Utilizzare i numeri ordinali syscall dagli attuali unistd_64.h

Spero che questo aiuti!

+0

grazie! questo è. Non so perché hanno dovuto cambiarlo però. Quindi BSD usa i numeri tradizionali mentre Linux 64 li ha modificati. Ciò significa che non riesco a riutilizzare il mio codice però :( – jbcreix

+1

@jbcreix, per curiosità * perché * lo faresti invece di usare le chiamate portatili 'exit()' e 'write()'? Non è solo per chiedere guai? ? – RBerteig

+0

Le chiamate portatili devono collegarsi a lebc o ad altre librerie C. In questo modo posso implementare solo le funzioni di cui ho bisogno e indipendentemente dal sistema operativo. Ovviamente il collegamento statico otterrebbe un risultato simile, ma poi ci sono problemi di licenza con codice GPL – jbcreix

3

Syscall 1 è in uscita su i386 ma su x86-64 credo.

EDIT: questo sembra impreciso: Secondo il web, che non sembra avere troppe informazioni su x86-64 assemblaggio Linux questo sembra essere il setup registro previsto prima dell'istruzione syscall.

rax system call number 
rbx arg0 
rcx return address from syscall 
rdx arg2 
rsi arg3 
rdi arg4 
r8 arg5 
r9 arg1 (expected by gcc in %rcx) 
r10-r15 should be saved/restored by C code 
rbp dito What is dito?? 
+1

Hmm, questa informazione di registro è errata? È rdi per arg1 come suggerisce OP? –

+1

Sì. L'ordine è rdi, rsi, rdx, ... come nelle normali funzioni con il numero di syscall che va in rax. Questo potrebbe essere vero per le prime versioni di Linux x86_64 che forse hanno copiato ii i6i abi, ma non ne sono sicuro. In ogni caso, in questo caso, un valore errato per arg1, ecc. Non può aver causato il problema in quanto l'uscita avrà sempre successo e terminerà il processo. – jbcreix

+0

Sì, ero abbastanza sicuro che il problema principale fosse dovuto all'utilizzo di NR_write invece di NR_exit, ma pensavo che anche l'argomento potesse essere disattivato! –