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
¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top