2009-07-30 7 views
12

¿Por qué esta impresión de basura en lugar de salir de mi programa correctamente? Utilizo las llamadas al sistema de esta manera en BSD, y me pregunto qué necesitaría para que funcione en Linux.Syscall desde el asm en línea en x86_64 Linux?

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

Gracias.

Respuesta

13

¿Por qué esta basura de impresión en lugar de salir de mi programa de forma normal?

Por CESA-2009-001, "Syscall 1 sale en i386 pero escribe en x86_64".

¿Qué necesitaría para hacer que funcione en Linux

Use los ordinales syscall del actual unistd_64.h

Espero que esto ayude!

+0

¡gracias! eso es todo. Sin embargo, no sé por qué tuvieron que cambiarlo. Entonces BSD usa los números tradicionales mientras Linux 64 los ha cambiado. Esto significa que no puedo reutilizar mi código :( – jbcreix

+1

@jbcreix, por curiosidad * ¿por qué? ¿Harías esto en lugar de usar las llamadas portátiles 'exit()' y 'write()'? ¿No es esto solo un problema? ? – RBerteig

+0

Las llamadas portátiles necesitan vincularse a glibc u otras bibliotecas C. De esta forma puedo implementar solo las funciones que necesito de la manera que necesito e independiente del SO. Por supuesto, la vinculación estática lograría un resultado similar, pero luego hay problemas de licencia con código GPL – jbcreix

3

Syscall 1 es la salida de i386 pero escribo en x86-64, creo.

EDITAR: esto parece impreciso: De acuerdo con la web, que no parece tener demasiada información sobre x86-64 Linux assembly, esta parece ser la configuración de registro esperada antes de la instrucción 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, ¿esta información de registro es incorrecta? ¿Es rdi para arg1 como sugiere OP? –

+1

Sí. El orden es rdi, rsi, rdx, ... como en las funciones normales con el número de syscall yendo a rax. Esto podría haber sido cierto para las primeras versiones de Linux x86_64 que tal vez copiaron el i386 abi, pero no estoy seguro. De todos modos, en este caso, un mal valor para arg1, etc. no podría haber causado el problema, ya que la salida siempre tendrá éxito y terminará el proceso. – jbcreix

+0

Sí, estaba bastante seguro de que el problema principal se debía a utilizar NR_write en lugar de NR_exit, ¡pero pensé que el argumento también podría estar apagado! –

Cuestiones relacionadas