2009-07-30 6 views
12

Warum wird Müll ausgegeben, anstatt das Programm ordnungsgemäß zu beenden? Ich verwende Systemaufrufe so auf BSD, und ich frage mich, was ich tun müsste, damit es unter Linux funktioniert.Syscall von Inline-Asm in x86_64 Linux?

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

Danke.

Antwort

13

Warum ist dieser Druck Müll statt mein Programm des Verlassens anmutig?

Pro CESA-2009-001, "Syscall 1 ist Ausgang auf i386 aber schreiben Sie auf x86_64".

, was ich brauche, um es in Linux funktioniert

Verwenden der syscall ordinals aus dem aktuellen unistd_64.h

hoffe, das hilft!

+0

danke! Das ist es. Ich weiß nicht, warum sie das ändern mussten. BSD verwendet also die traditionellen Zahlen, während Linux 64 sie geändert hat. Das bedeutet, dass ich meinen Code nicht wiederverwenden kann :( – jbcreix

+1

@jbcreix, aus Neugier * warum * würdest du das tun, anstatt die portablen Aufrufe 'exit()' und 'write()' zu benutzen? Ist das nicht nur Ärger? ? – RBerteig

+0

Die Portable Calls müssen mit glibc oder anderen C-Bibliotheken verlinkt sein, damit ich nur die Funktionen implementieren kann, die ich brauche und unabhängig vom Betriebssystem brauche.Natürlich würde statische Verknüpfung ein ähnliches Ergebnis erzielen, aber dann gibt es Lizenzprobleme mit GPL-Code – jbcreix

3

Syscall 1 ist Ausgang auf i386 aber schreibe auf x86-64 glaube ich.

EDIT: dies scheint ungenau: Nach dem Web, die nicht zu viele Informationen über x86-64 Linux Assembly scheint dies scheint die erwartete Register Setup vor der syscall-Anweisung zu sein.

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, ist diese Registerinformation falsch? Ist rdi für arg1 wie OP vorgeschlagen? –

+1

Ja. Die Reihenfolge ist rdi, rsi, rdx, ... wie in regulären Funktionen, wobei die syscall-Nummer zu rax geht. Dies könnte für die ersten Linux x86_64-Versionen gegolten haben, die das i386 abi kopiert haben, aber ich weiß es nicht genau. In diesem Fall könnte ein ungültiger Wert für arg1 usw. möglicherweise nicht das Problem verursacht haben, da exit immer erfolgreich ist und den Prozess beendet. – jbcreix

+0

Ja, ich war mir ziemlich sicher, dass das Hauptproblem darin lag, NR_write anstelle von NR_exit zu verwenden, dachte aber, das Argument könnte auch aus sein! –