que operario operador hace funciones ensamble ensamblaje departamento c linux assembly gas

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