Sie sind auf Seite 1von 8

Lenguajes de interfaz

Prctic 6: Subrutins
(Para ira a la parte de directivas sin pasar por todo el cdigo en ensamblador y saltarte chorromil pginas de teora, pincha aqu) (Si te crees el pap de los pollitos y vas a hacer la prctica sin leer el resto, pincha aqu)

Teora:
Las instrucciones de subrutina permiten pasar de un procedimiento a otro, manteniendo la informacin necesaria para continuar con el procedimiento que origin la llamada.

Instrucciones en ensamblador.
CALL destino. Salta al destino. El destino es una direccin relativa o una direccin de memoria contenida en un registro, ubicacin de memoria o apuntador. RET. Salta de vuelta a un procedimiento que realiz una instruccin CALL Opcionalmente, saca un nmero inmediato de bytes de la pila. INT inmediato. Genera una llamada al manejador de interrupciones o excepciones indicado con el valor inmediato. IRET. Salta de vuelta a un procedimiento que llam a una interrupcin INT o de un tarea anidada. ENTER tamao,0. Crea un marco de pila para procedimientos de tamao inmediatro. ENTER tamao, nmero de marcos. Crea marcos de pila anidados para procedimientos LEAVE. Libera los marcos establecidos por ENTER. CALL y RET actan de forma distinta si se ejecuta una llamada cercana, lejana, inter nivel de privilegio o a otra tarea. Llamada cercana Una llamada cercana es un salto en el segmento de cdigo actual, La llamada: 1. Empuja EIP en la pila 2. Carga el desplazamiento en EIP 3. Inicia la ejecucin del procedimiento

El regreso: 1. Saca el tope de la pila en EIP 2. Incrementa el apuntador de pila n bytes. 3. Contina la ejecucin del procedimiento Llamada lejana Una llamada lejana es un salto a un segmento distinto. La llamada: 1. 2. 3. 4. 5. Empuja CS en la pila Empuja EIP en la pila Carga el selector de segmento en CS Carga el desplazamiento en EIP Inicia la ejecucin del proceso.

El regreso: 1. 2. 3. 4. Saca el tope de la pila a EIP Saca el tope de la pila a CS Incrementa el apuntador de pila n bytes. Contina la ejecucin del procedimiento

Llamada inter nivel de privilegio Una llamada inter nivel de privilegio es un salto a una rutina en una tarea con un nivel de privilegio distinto. La llamada: 1. Checa los permisos de acceso. 2. Almacena temporalmente SS,ESP, CS y EIP 3. Carga el selector de segmento y el apuntador de pila para la nueva pila (la pila del nivel de privilegio llamado) del TSS en los registros SS y ESP y cambia de tarea. 4. Empuja los valores SS y ESP temporalmente salvados en la nueva pila. 5. Copia los parmetros de la pila antigua a la pila nueva. Un valor en la descriptor de compuerta determina cuantos parmetros copiar. 6. Empuja los valores CS y EIP guardados temporalmente en la pila. 7. Carga el selector de segmento para el nuevo segmento de cdigo y el nuevo apuntador de instrucciones en los registros CS y EIP.

8. Inicia la ejecucin del procedimiento en el nuevo nivel de privilegio.

El regreso: 1. 2. 3. 4. 5. 6. Realiza un chequeo de privilegios. Saca el tope de la pila a CS y EIP Incrementa el apuntador de pila n bytes. Saca del tope de la pila a SS y ESP Incrementa el apuntador de pila n bytes. Contina la ejecucin del procedimiento.

Cambio de tarea Un cambio de tarea es la transferencia de ejecucin de una tarea otra. El programa que realiza el llamado se pausa y el programa llamado se inicia o reanuda donde se qued. La llamada: 1. Obtiene el selecto de segmento TSS como operando de un JMP o CALL, de una compuerta o del campo con el enlace a la tarea previa. 2. Checa si el programa tiene permiso para cambiar a la nueva tarea. 3. Checa si el descriptor de la nueva tarea est presente y tiene un lmite vlido. 4. Checa si la nueva tarea est disponible (CALL,JMP, excepcin o interrupcin) u ocupada (IRET) 5. Checa que el TSS actual, el nuevo y todos los descriptores de segmento usados estn paginados en memoria del sistema. 6. Si el cambio fue realizado con JMP o IRET, el procesador desmarca la bandera de ocupado del TSS actual. Si es iniciado con CALL, una excepcin o una interrupcin, la bandera de ocupado se deja marcada. 7. La bandera NT se limpia en una imagen de EFLAGS si el cambio fue realizado con IRET. 8. Guarda el estado de la tarea en TSS (Los registros de propsito general, los selectores de segmento, EFLAGS y EIP) 9. La bandera NT se marcar si se inici con CALL, una instruccin o una excepcin. Si se inici con JMP o IRET, NT reflejar el estado cargado de la nueva tarea. 10. La bandera Busy se marcar en el nuevo descriptor TSS si se inici con CALL, JMP, una instruccin o una excepcin. Si se inici con IRET, Busy se quedar marcada. 11. Carga el registro de tareas con el selector de segmento y el descriptor para el TSS de la nueva tarea. 12. El estado TSS es cagado en el procesador. 13. Los descriptores asociados con los segmentos son cargados y cualificados. 14. Comienza a ejecutar la nueva tarea.

Estructura de la subrutina sin parmetros: Una subrutina bsica en ensamblador tiene la siguiente forma: Segmento origen: CALL destino

Segmento Destino: Destino: Instrucciones RET Estructura de la subrutina sin parmetros: Para pasar parmetros en una subrutina, usamos la pila: Segmento origen: PUSH dato1 PUSH dato2 . . . Push datoN CALL destino

Segmento Destino: Destino: POP datoN

. . . POP dato2 POP dato1 Instrucciones RET Las subrutinas no tienen mtodos incorporados para devolver valores. Los mtodos ms para devolver valores son: Usando los registros. Antes de llamar a RET, cargamos los registros que no se modifican con los datos necesarios. Habitualmente, el registro EAX es el registro para este propsito. Usando referencias de memoria: Usamos apuntadores a memoria como parmetros. Pasamos las direcciones de memoria donde planeamos almacenar los resultados. Variables locales Las variables locales se almacenan en la pila, decrementando la pila el espacio suficiente para almacenar el total de variables locales que necesitemos, para posteriormente incrementarla antes de regresar. Inicializar el espacio para las variables Rutina: push ebp mov ebp, esp sub esp, n Ahora tenemos n bytes en memoria que podemos usar para variables. Instrucciones Liberar el espacio de las variables mov esp,e bp pop ebp

ret n Fin rutina:

Directivas
Las directivas de MASM permiten manejar a travs de etiquetas las direcciones de los procedimientos y definir el paso de parmetros a los procedimientos. Etiquetas con distancia Normalmente, usamos etiquetas cercanas Etiqueta: Esta etiqueta la podemos escribir como Etiqueta LABEL NEAR . Para manejar una etiqueta lejana, entonces tendramos Etiqueta LABEL FAR. Procedimientos La sintaxis bsica para un procedimiento es Etiqueta PROC instrucciones RET Etiqueta ENDP La sintaxis completa es

Etiqueta PROC [atributos][USES registros] [ ,][parmetro:tipo]


Atributos [Distancia] [Lenguaje] [Visibilidad] [Prologo] Distancia: NEAR o FAR Lenguaje: Usa las convenciones de un lenguaje para accesar a los parmetros y restaurar la pila. BASIC, FORTRAN, PASCAL. Convierten los nombres de los procedimientos a maysculas, colocan el ltimo parmetro en la parte ms baja de la pila y usan RET n. C, STDCALL. Agregan _ Como prefijo al nombre del procedimiento cuando la visibilidad es PUBLIC o EXPORT y colocan el primer parmetro en la parte ms baja de la pila. STDCALL limpia la pila solo si hay :VARARG

SYSCALL. Equivalente a C pero sin _ al principio. Visibilidad: Indica su disponibilidad para otros mdulos.Si no se define como PRIVATE (privada), la visibilidad es PUBLIC(pblica). EXPORT coloca al procedimiento en la tabla para exportar. Prlogo: Determina los argumentos para la generacin de prlogos y eplogos de PROC (El cdigo que MASM genera cuando encuentra PROC o al final de un procedimiento). USES Contiene el listado de los registros que el procedimiento va a usar, para que genere el prlogo y el eplogo para restablecerlos a sus valores previos al llamado de la funcin. Los registros se separan con espacios en blanco USES registro registro Parmetros Es el listado de parmetros. Cada parmetro se compone de un nombre y un tipo. El ltimo parmetro puede ser VARARG, que especifica que se aade uno o ms parmetros, indexados con respecto al parmetro VARARG. Variables locales Se definen dentro de un procedimienco como LOCAL nombre:tipo o LOCAL nombre[cantidad]:tipo Prototipo El prototipo de un procedimiento se escribe: Nombre PROTO [distancia][lenguaje][,] [parmetros:tipo]

Llamadas a procedimientos
Para llamar a los procedimientos usamos la directiva INVOKE INVOKE genera una secuencia de instrucciones que empuja los argumentos y llama al procedimiento. INVOKE convierte los argumentos a los tipos esperados, empuja los argumentos en el orden correcto y limpia la pila cuando el procedimiento retorna. Sintaxis: INVOKE nombre [,argumentos] Los argumentos pueden ser una expresin, un par de registros o una expresin precedida por ADDR u OFFSET.

ADDR pasa la direccin de una expresin que espera un apuntador NEAR PTR o FAR PTR; ADDR ocupa EAX al resolver la direccin. OFFSET devuelve el desplazamiento de una direccin de memoria en el segmento. Solo funciona con variables globales.

Desarrollo de la prctica:
El alumno estudiar la estructura de una funcin de C proporcionada por el maestro y la traducir a cdigo ensamblador. Posteriormente, probar la funcin usando cinco constantes.

void sumatoria (int* suma, unsigned int sumandos, int argumentos[]) { Int contador; suma=0; for (contador=0;contador<sumandos;contador++) { suma=suma+argumentos[contador]; }

return; }

Conclusiones y observaciones: