operario - llamar a funciones de ensamblaje desde c
operario de ensamble (4)
Intento utilizar una función en ensamblado, invocada desde un proyecto C. Se supone que esta función llama a una función libc, digamos printf()
, pero sigo recibiendo un error de segmentación.
En el archivo .c tengo la declaración de la función digamos
int do_shit_in_asm()
En el archivo .asm tengo
.extern printf
.section .data
printtext:
.ascii "test"
.section .text
.global do_shit_in_asm
.type do_shit_in_asm, @function
do_shit_in_asm:
pushl %ebp
movl %esp, %ebp
push printtext
call printf
movl %ebp, %esp
pop %ebp
ret
Cualquier comentario de punteros sería apreciado.
as func.asm -o func.o
gcc prog.c func.o -o prog
Cambie el push printtext
de push printtext
para push $printtext
.
Tal como está, está cargando un valor del texto de la dirección de printtext
y presionándolo, en lugar de presionar la dirección. Por lo tanto, está pasando ''test''
como un número de 32 bits, en lugar de un puntero, y printf
está tratando de interpretar eso como una dirección y bloqueo.
Después de este:
push printtext
call printf
Usted quiere:
addl $4, %esp
Explicación adicional:
Debido a que está utilizando x86 Linux, asumo que la convención de llamadas requiere que el destinatario limpie los parámetros. Debido a que presionó un puntero antes de llamar a printf
, su pila está desactivada por 4 después de que la instrucción ret
esa función haya sucedido.
Actualizar:
Sí, está bien, estaba acostumbrado a la sintaxis de Intel, así que estaba obteniendo el orden de los argumentos hacia atrás en mi cabeza. En realidad, la falta de este addl
para esp
no importa, porque estás restaurando esp
correctamente cerca de tu ret
. Mi próxima suposición es que la cadena que está pasando a printf
carece de un terminador nulo ... Déjame ver qué gas
...
Actualización 2:
OK, el gas
nulo termina cadenas para ti, así que supongo que mi segunda corazonada fue incorrecta. Parece que encontraste el problema así que el punto es discutible.
Una de las mejores formas de comenzar con las funciones del lenguaje en ensamblador es escribir una función similar en C y luego compilarla con el modificador del compilador que genera una lista de ensamblaje ( -S
en gcc). Luego puede estudiar el resultado de lo que hizo el compilador y modificarlo según sea necesario.
Esto es particularmente útil si está llamando a funciones como printf
que utilizan una convención de llamada diferente (debido a la cantidad variable de argumentos). Llamar a esas funciones puede ser bastante diferente de llamar funciones no varargs.
el problema era que estaba usando
pushl printtext
mejor que
pushl $printtext
Gracias a todos por su ayuda y lo siento por perder su tiempo: P