Práctica 3. Paso de parámetros entre C y ensamblador en Linux.

Anuncio
Arquitectura y Tecnologı́a de Ordenadores Personales (IS37 - II37)
Ingenierı́a Técnica en Informática de Sistemas - Ingenierı́a Informática
Práctica 3. Paso de parámetros entre
C y ensamblador en Linux.
1.
Objetivos
Con el desarrollo de esta práctica se podrá analizar el formato de los ficheros en lenguaje
ensamblador, su comunicación con programas en C y el procedimiento para mezclar ficheros
en ambos lenguajes.
2.
Introducción
Si bien la programación en ensamblador puede resultar tediosa y compleja por tratarse
de un lenguaje de muy bajo nivel, puede ser útil e incluso necesaria para acelerar ciertas
funciones, para tener un control riguroso sobre el código que queremos ejecutar, para acceder a recursos del ordenador a muy bajo nivel o por el mero hecho de estudiar el código
ensamblador en sı́. Como el desarrollo de aplicaciones enteramente en ensamblador no suele
ser necesario, esta práctica se va a centrar en la inclusión de subrutinas en ensamblador
llamadas desde programas en C. Por ello el paso de parámetros y la recuperación de los
resultados devueltos por las funciones son dos de los aspectos más importantes a tener en
cuenta.
3.
Uso del compilador gcc
Para incluir ficheros en ensamblador al compilar nuestros programas, basta con indicar
el nombre del fichero con la extensión .s o .S en la lı́nea de comandos. Por ejemplo, para
ejecutar la prueba de mistrlen se utilizarı́a la orden
gcc -o mistrlen mistrlen.c mistrlen.s
entonces el compilador invoca automáticamente al ensamblador as para generar el módulo objeto correspondiente que luego es enlazado de la forma habitual para generar el ejecutable.
Para generar código en ensamblador en lugar de un ejecutable –más bien, de un fichero
objeto pues el ejecutable incluye el código de librerı́as que no aparecen en el ensamblador
generado por el compilador– se invoca el compilador con la opción -S. El código generado
depende del nivel de optimización elegido, que se indica con la opción -On donde n es el
nivel de optimización. Por ejemplo
gcc -S -O2 programa.c
4.
Paso de parámetros en C
Cada lenguaje de programación tiene sus propios mecanismos para el paso de parámetros
entre subrutinas, y para la devolución de valores desde éstas. En el lenguaje C y utilizando
la pila para el paso de parámetros, una función de la forma
funcion(par1, par2, par3 ... parn)
apiları́a en primer lugar el parámtro n, luego el n-1, etcétera, y por último el parámetro
1 antes de realizar la llamada a la subrutina. Una vez dentro de la subrutina, si se sigue
el procedimiento habitual de apilar el frame pointer ebp y luego copiar en él el valor del
puntero a pila –mediante movl esp, ebp– se tiene que durante la ejecución de la subrutina
el estado de la pila es el siguiente:
parámetro n
parámetro n - 1
...
parámetro 3
parámetro 2
parámetro 1
dir. retorno
ebp anterior
←
←
←
←
←
←
←
4n+4(ebp)
4(n-1)+4(ebp)
...
16(ebp)
12(ebp)
8(ebp)
4(ebp)
0(ebp)
si el tamaño de los parámetros es de 32 bits. Además, en direcciones por debajo de ebp
se crean los almacenamientos para las variables locales de la subrutina, que comenzarı́an en
-4(ebp) hacia direcciones decrecientes.
En el caso de que la rutina devuelva un valor, éste se pasará en el registro eax. Todos los
demás registros de la arquitectura se deben preservar si van a ser modificados, apilándolos
antes de ser usados y desapilándolos al final.
5.
Trabajo a desarrollar
1. Estudiad los ejemplos de programación en ensamblador disponibles en la página web,
prestando especial atención a la estructura de la pila, el paso de parámetros y la programación en ensamblador. Compilad y ejecutad los ejemplos mistrlen e itohex. En
la página de la asignatura se pueden encontrar los distintos manuales del ensamblador
de la arquitectura.
2. Observar el código ensamblador generado por el compilador gcc con la opción -S y
distintos niveles de optimización en los programas de prueba anteriores.
3. Estudiad los ejemplos que usan las extensiones MMX y SSE mediante los ejemplos
itommhex, itommhex2p y las distintas versiones de ssefiltro –este último tarda casi
un minuto en ejecutarse.
4. Compilad y probad el programa registros. Estudiad, consultando los manuales de la
arquitectura, los valores de los registros, en especial los de segmento y flags. Comprobad
cómo dos procesos ejecutándose a la vez lo hacen en las mismas direcciones lógicas.
5. Realizad un pequeño programa que reciba dos parámetros enteros y devuelva un valor
del mismo tipo, calculado como se desee en función de los parámetros.
Descargar