llamar a las funciones de montaje de c
Pregunta
Estoy tratando de utilizar una función en el ensamblaje, invocado desde un proyecto C. Esta función debe llamar printf()
por ejemplo una función de Let libc, pero aparece un fallo de segmentación.
En el archivo .c tengo la declaración de ejemplo de la función let
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
Cualquiera punteros sería apreciada comentarios.
as func.asm -o func.o
gcc prog.c func.o -o prog
Solución
Cambiar push printtext
a push $printtext
.
Como es, va a cargar un valor de la dirección y empujando printtext
que, en lugar de empujar la dirección. Por lo tanto, estás pasando 'test'
como un número de 32 bits, en lugar de un puntero, y printf
está tratando de interpretarlo como una dirección y estrellarse.
Otros consejos
Una de las mejores maneras de empezar con el montaje de las funciones del lenguaje es escribir una función similar en C y, a continuación, construirlo con el modificador de compilador que genera un ensamblaje lista (-S
en gcc). A continuación, se puede estudiar la salida de lo que hizo el compilador, y modificar según sea necesario.
Esto es particularmente útil si estás funciones tales como printf
que utilizan una convención de llamada diferente (debido al número variable de argumentos) llamando. Llamar a esas funciones pueden ser bastante diferentes de llamar a no varargs funciones.
el problema era que yo estaba usando
pushl printtext
en lugar de que
pushl $printtext
Gracias a todos por su ayuda y lo siento por perder su tiempo: P
Después de esto:
push printtext
call printf
¿Quieres:
addl $4, %esp
Explicación adicional:
Debido a que usted está utilizando Linux x86 Asumo la convención de llamada requiere que el destinatario de la llamada a la limpieza de los parámetros. Debido a que empujó un puntero antes de llamar printf
, su pila está desactivada por 4 después de que ocurrió la instrucción ret
de esa función.
Actualización:
Sí, está bien, yo estaba acostumbrado a la sintaxis de Intel, así que estaba recibiendo el orden de los argumentos hacia atrás en mi cabeza. En realidad, la falta de la parte posterior addl
a esp
no importa, porque estás restaurando esp
correctamente cerca de su ret
. Mi siguiente conjetura es que la cadena va a ceder a printf
que falta un terminador nulo ... Vamos a ver lo que hace gas
...
Actualización 2:
OK, nula gas
termina cuerdas para usted, así que supongo que mi segundo presentimiento que estaba mal. Parece que has encontrado el problema por lo que el punto es discutible.