La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Pbn - 17 - 1 © Jaime Alberto Parra Plaza CLASE 17 FUNCIONES Y PASO DE PARÁMETROS A PROCEDIMIENTOS.

Presentaciones similares


Presentación del tema: "Pbn - 17 - 1 © Jaime Alberto Parra Plaza CLASE 17 FUNCIONES Y PASO DE PARÁMETROS A PROCEDIMIENTOS."— Transcripción de la presentación:

1 Pbn - 17 - 1 © Jaime Alberto Parra Plaza CLASE 17 FUNCIONES Y PASO DE PARÁMETROS A PROCEDIMIENTOS

2 Pbn - 17 - 2 © Jaime Alberto Parra Plaza Cuando se diseña un lenguaje de alto nivel (en adelante llamado HLL), usualmente se hace abstracción del sistema sobre el cual operará, es decir, un lenguaje dado se crea como si fuera a ejecutarse sobre un computador virtual.

3 Pbn - 17 - 3 © Jaime Alberto Parra Plaza Siendo las funciones unas de las herramientas más poderosas de cualquier lenguaje, el paso de parámetros entre ellas tampoco debe depender del tipo de máquina en particular en que se ejecute en un momento dado.

4 Pbn - 17 - 4 © Jaime Alberto Parra Plaza Se comentó antes que para transferir parámetros entre procedimientos se puede usar la pila o los registros. Cuando una función es genérica, se usará como camino de transferencia la pila. Se dirá entonces que una función es un procedimiento que recibe parámetros a través de la pila, usando un mecanismo estandarizado.

5 Pbn - 17 - 5 © Jaime Alberto Parra Plaza APILAMIENTO: La forma en que los HLL transfieren parámetros a sus funciones a través de la pila se presenta en dos formatos: Apilamiento por izquierda Apilamiento por derecha

6 Pbn - 17 - 6 © Jaime Alberto Parra Plaza Para explicar la diferencia se usará la función genérica: func (a, b, c) Se tiene que el orden IZQUIERDO es: a-b-c en tanto que el orden DERECHO será c-b-a.

7 Pbn - 17 - 7 © Jaime Alberto Parra Plaza Un HLL será apilador por la izquierda si ingresa los parámetros en la pila en orden izquierdo. Para el ejemplo, la pila quedaría así: a b c SP

8 Pbn - 17 - 8 © Jaime Alberto Parra Plaza Por el contrario, será apilador por la derecha si el orden derecho es el escogido. Este método es el que se tomará como supuesto en adelante (que es el caso de C): c b a SP

9 Pbn - 17 - 9 © Jaime Alberto Parra Plaza Después de colocar los parámetros, se invoca el procedimiento respectivo; el microprocesador se encarga de apilar la dirección de retorno. El aspecto actual de la pila es: c b a SP IP de retorno

10 Pbn - 17 - 10 © Jaime Alberto Parra Plaza Esa es la forma en que la pila está cuando se entra al procedimiento. Para acceder a los parámetros, es norma utilizar el registro BP, el cual permite direccionar a cualquier elemento dentro de la pila. Puesto que BP podría tener un valor anterior (llamado de una función desde otra) es común apilar también el valor actual de BP.

11 Pbn - 17 - 11 © Jaime Alberto Parra Plaza Direcciones relativas de cada parámetro al ser direccionado por BP (después de asignar a BP el valor de SP): c b a BP = SP IP de retorno antiguo BP [BP+2] [BP+4] [BP+6] [BP+8]

12 Pbn - 17 - 12 © Jaime Alberto Parra Plaza PLANTILLA DE FUNCIÓN: De acuerdo a lo anterior, la entrada y salida típicas de una función son: funcPROC PUSHBP MOVBP, SP...... POPBP RET funcENDP

13 Pbn - 17 - 13 © Jaime Alberto Parra Plaza VALORES RETORNADOS: Prácticamente todos los HLL devuelven resultados a través del acumulador, usando los registros respectivos para acumulador de 8, 16 ó 32 bits. Cuando el resultado es mayor a 32 bits, se retorna un puntero al lugar donde el resultado ha quedado guardado.

14 Pbn - 17 - 14 © Jaime Alberto Parra Plaza EJEMPLO: Para visualizar mejor estas ideas se implementará la siguiente función, cuyo propósito en particular no interesa en el momento: char funcX(int a, char b) { return (a + 5) / b; }

15 Pbn - 17 - 15 © Jaime Alberto Parra Plaza Como es ya conocido, el procedimiento tiene una macro asociada para interfaz con el exterior. La macro se encarga de apilar los parámetros y de invocar al procedimiento. Puesto que se desconoce si los argumentos serán o no constantes (que no pueden apilarse directamente) es usual trabajar con el registro BX.

16 Pbn - 17 - 16 © Jaime Alberto Parra Plaza Los trabajos usuales de la macro son: Apilar BX para preservar su valor Llevar cada argumento a BX e irlo apilando en el orden escogido Invocar al procedimiento Quitar los argumentos de la pila Desapilar BX para restituir su valor original

17 Pbn - 17 - 17 © Jaime Alberto Parra Plaza funcXMACROArgA, ArgB PUSHBX; preservar reg. MOVBL, ArgB; primer param. PUSHBX MOVBX, ArgA; segundo param. PUSHBX CALLpfuncX; llamar proc. ADDSP, 4; limpiar pila POPBX; restituir reg. ENDM; funcX

18 Pbn - 17 - 18 © Jaime Alberto Parra Plaza Las labores normales de un procedimiento: Apilar BP para preservar su valor Copiar SP en BP Apilar los registros que vayan a utilizarse Realizar las tareas necesarias, usando a BP como puntero a los parámetros Llevar el resultado al Acc si es necesario Desapilar los registros apilados Desapilar BP Retornar

19 Pbn - 17 - 19 © Jaime Alberto Parra Plaza pfuncXPROC PUSHBP MOVBP, SP PUSHBX MOVAX, [BP+4] ADDAX, 5 MOVBX, [BP+6] IDIVBL POPBX POPBP RET pfuncXENDP

20 Pbn - 17 - 20 © Jaime Alberto Parra Plaza EJERCICIOS: Intercambio de dos variables Obtener el mayor de dos valores Conversión en mayúsculas de una cadena Ordenamiento de una lista por el método de la burbuja Función seno a partir de datos en tabla

21 Pbn - 17 - 21 © Jaime Alberto Parra Plaza CARACTERÍSTICAS ESPECIALES DE LAS FUNCIONES

22 Pbn - 17 - 22 © Jaime Alberto Parra Plaza Además de las consideraciones dadas anteriormente sobre las funciones en general, algunos aspectos particulares requieren especial atención. Ellos son: Retorno de errores Interfaz con otros lenguajes Recursividad

23 Pbn - 17 - 23 © Jaime Alberto Parra Plaza RETORNO DE ERRORES

24 Pbn - 17 - 24 © Jaime Alberto Parra Plaza Cuando se diseña una función, se debe tener en mente: Una solución general para la labor que hará la función Soluciones particulares para casos que no cubra la solución general Prever la posibilidad de errores y retornar un código de error indicándolo

25 Pbn - 17 - 25 © Jaime Alberto Parra Plaza CAUSAS DE ERROR: Una función puede fallar en lograr su cometido por dos causas fundamentales: Los operandos no se ajustan al tipo o a las características esperadas (error de entrada) El resultado no se ajusta al tipo en que debe retornarse la solución (error de salida)

26 Pbn - 17 - 26 © Jaime Alberto Parra Plaza Puede visualizarse esto mejor por un ejemplo. Se sabe que la función atoi debe convertir una cadena formada por caracteres numéricos a su número entero equivalente: atoi (2345) = 2345

27 Pbn - 17 - 27 © Jaime Alberto Parra Plaza Supóngase ahora que se pide realizar la conversión: atoi (23Wq&) Claramente, el argumento no se presta para la conversión y la función debe retornar un indicador del error.

28 Pbn - 17 - 28 © Jaime Alberto Parra Plaza Tradicionalmente, la solución es retornar un valor que no pertenezca al conjunto solución. Sin embargo, éste no es el caso, pues el rango de atoi es todo el conjunto de enteros. La función C retorna un 0 cuando el argumento no puede convertirse a un número, ¡pero el 0 también puede ser una solución verdadera!.

29 Pbn - 17 - 29 © Jaime Alberto Parra Plaza Debido a esto, cuando se invoca a atoi y se recibe como respuesta un 0, debe añadirse código que analice la solución. Podría ser algo como esto:

30 Pbn - 17 - 30 © Jaime Alberto Parra Plaza Debido a esto, cuando se invoca a atoi y se recibe como respuesta un 0, debe añadirse código que analice la solución. Podría ser algo como esto: x = atoi ( cadena ); if ( !x ) if ( !cadena[0] ) /* Error */ else /* Respuesta == 0 */ else /* Respuesta != 0 */

31 Pbn - 17 - 31 © Jaime Alberto Parra Plaza BANDERA DE CARRY: El ensamblador permite una solución mejor a este problema, que no está disponible en ningún otro lenguaje. Una función de ensamblador puede retornar 2 valores: La solución como tal y un indicador de si se logró éxito o fracaso en la actividad.

32 Pbn - 17 - 32 © Jaime Alberto Parra Plaza La solución se retorna en el acumulador, en tanto que el indicador éxito/fracaso es la bandera de acarreo. Normalmente, esta bandera es fijada por el uP cuando hay sobreflujo aritmético. Pero puede también fijarse a voluntad del programador usando las órdenes: CLC = Fijar el acarreo en 0 STC = Fijar el acarreo en 1

33 Pbn - 17 - 33 © Jaime Alberto Parra Plaza Así, la función llamadora deberá revisar el valor del acarreo y deducir si hubo o no error, usando las órdenes de salto: JC = Saltar si el acarreo está en 1 JNC = Saltar si el acarreo está en 0 Quedando la interacción como: CALLAtoi JCError ; código para éxito Error:; código para fracaso

34 Pbn - 17 - 34 © Jaime Alberto Parra Plaza CÓDIGOS DE ERROR: La misma función sirve para evidenciar otro concepto. Supóngase que se solicita: atoi (356712); Este argumento sí es convertible, pero al hacerlo se sobrepasa el máximo permitido. De nuevo, la función C retorna aquí un 0, y ahora sí es realmente difícil diferenciar este error del anterior.

35 Pbn - 17 - 35 © Jaime Alberto Parra Plaza Otra vez la solución será más adecuada en ensamblador. Cuando las causas de error son varias, se seguirá usando el acarreo para indicarlo, pero se usará el acumulador para explicar el tipo de error, conocido como un código de error. La asociación es: if (Carry==0) /* Solución está en Acc */ else /* Código de error está en Acc */

36 Pbn - 17 - 36 © Jaime Alberto Parra Plaza INTERFAZ CON OTROS LENGUAJES

37 Pbn - 17 - 37 © Jaime Alberto Parra Plaza Para lograr un acople exitoso entre funciones que han sido elaboradas con diferentes lenguajes, de debe escoger uno de los lenguajes como el de referencia y someter el código escrito en otros lenguajes a los parámetros del escogido. Se presentan aspectos a considerar tales como: nombres de segmento, paso de parámetros, recepción de resultados, tipo de saltos, etc.

38 Pbn - 17 - 38 © Jaime Alberto Parra Plaza Dada la variedad de lenguajes, sólo se explicará formalmente cómo enlazar funciones hechas en ensamblador para ser invocadas desde un programa hecho en lenguaje C. Además de ser C el lenguaje más popular actualmente, su forma de enlazar diversos códigos es bastante diferente a la de otros lenguajes conocidos.

39 Pbn - 17 - 39 © Jaime Alberto Parra Plaza Se darán diversas recomendaciones tanto para el código a ser llamado, que será escrito en ensamblador, como para el código llamador, hecho en ANSI C. Se recalca que es C estándar y no C++, pues en este caso la forma de interacción es algo diferente.

40 Pbn - 17 - 40 © Jaime Alberto Parra Plaza ARCHIVO ENSAMBLADOR: Escribir la(s) funcion(es) a enlazar en un archivo que sólo contenga el segmento de código, sin segmentos de datos o de pila, pues se supone que el programa llamador ya los ha declarado.

41 Pbn - 17 - 41 © Jaime Alberto Parra Plaza Si las funciones son estructuradas nunca usarán variables globales sino sólo parámetros de la pila (que debe ser una sola para todas funciones). La función debe asumir que los parámetros se han colocado siguiendo el método de apilación por la derecha.

42 Pbn - 17 - 42 © Jaime Alberto Parra Plaza El nombre del segmento de código debe ser igual al usado por el programa llamador. El estándar impuesto por MicroSoft y que es seguido por la mayoría de los compiladores es denominarlo _TEXT. Si este no es el caso, simplemente se puede leer el archivo.MAP generado por el compilador y determinar el nombre que asigna a los segmentos.

43 Pbn - 17 - 43 © Jaime Alberto Parra Plaza FUNCIONES: Para que las funciones puedan ser accesadas desde el exterior del archivo, deben declararse como públicas al comienzo del segmento, en la forma: publicNombreFuncion

44 Pbn - 17 - 44 © Jaime Alberto Parra Plaza C exige que las funciones que son externas (que están en otro archivo) empiecen su nombre por el caracter de subrayado. Así que las funciones deben declararse como: _NombreFuncPROC... _NombreFuncENDP

45 Pbn - 17 - 45 © Jaime Alberto Parra Plaza PARA EL ENSAMBLADOR: Dado que C es un lenguaje sensible al tipo de letra, debe instruirse al ensamblador para que no cambie las letras a mayúsculas que es su opción por defecto.

46 Pbn - 17 - 46 © Jaime Alberto Parra Plaza PARA EL COMPILADOR: Debe explicársele al compilador que la función a llamar está en otro archivo, es decir que es externa, al dar su prototipo: extern TipoRet NombreFunc(TipoParams); Para estar seguros que el código será compilado como C estándar, la extensión del archivo debe ser.C

47 Pbn - 17 - 47 © Jaime Alberto Parra Plaza PARA EL ENLAZADOR: Una vez el ensamblador y el compilador hayan generado sus respectivos archivos.OBJ, se entregan al enlazador para obtener el producto ejecutable final. En principio, cualquier enlazador servirá, puesto que el lenguajes origen de los archivos ya no interesa.

48 Pbn - 17 - 48 © Jaime Alberto Parra Plaza Debe tenerse en cuenta que el programa C requiere un código de inicio que el fabricante ubica en un archivo como código ensamblado. Existe uno distinto para cada modelo de memoria. En principio, para simplificar las labores, puede hacerse uso de la utilidad de crear un proyecto que ofrecen todos los compiladores y colocar en él los archivos objeto obtenidos.

49 Pbn - 17 - 49 © Jaime Alberto Parra Plaza NOMENCLATURA: Anteriormente se mencionó que una macro era la parte pública de un procedimiento y como tal debía tener el nombre significativo. Esto es válido cuando la función va a ser llamada desde otra función assembly. Cuando la función va a llamarse desde otro lenguaje la idea cambia.

50 Pbn - 17 - 50 © Jaime Alberto Parra Plaza Cuando la función se invoca desde otro lenguaje, el compilador de ese lenguaje se encarga de generar la macro de llamado, así que el nombre significativo debe darse al procedimiento. Debe aclararse que esto es recomendable sólo cuando dicho procedimiento sea hecho exclusivamente para ser llamado desde otro lenguaje.

51 Pbn - 17 - 51 © Jaime Alberto Parra Plaza Sea la función a ser llamada: funcY (int a, char b); El compilador guarda los parámetros en la pila y llama al procedimiento, el cual deberá llamarse: _funcYPROC

52 Pbn - 17 - 52 © Jaime Alberto Parra Plaza Cuando las funciones a invocar son recursivas (tema que se verá posteriormente), se tiene que desde dentro de la función assembly se hace un llamado a ella misma, aquí sí es válido el uso de la macro, puesto que se trata del caso de una función assembly llamando a otra función assembly.

53 Pbn - 17 - 53 © Jaime Alberto Parra Plaza Sea el llamado de la función recursiva: funcRecursiva (int a); De nuevo, el procedimiento se llamará: _funcRecursiva PROC... mfuncRecursiva... _funcRecursiva ENDP

54 Pbn - 17 - 54 © Jaime Alberto Parra Plaza El código anterior muestra la recomendación para nombres de funciones recursivas que son invocadas desde otro lenguaje: Dar al procedimiento el nombre significativo (funcion) Dar a la macro el mismo nombre precedido de la letra m (mfuncion) La macro sirve para que el procedimiento coloque los parámetros antes de llamarse a si mismo.

55 Pbn - 17 - 55 © Jaime Alberto Parra Plaza PREGUNTA 17: ¿Qué metodología debe seguirse para invocar rutinas de lenguaje ensamblador desde otros lenguajes distintos al C, y viceversa?. Dar ejemplos particulares.

56 Pbn - 17 - 56 © Jaime Alberto Parra Plaza

57 Pbn - 17 - 57 © Jaime Alberto Parra Plaza


Descargar ppt "Pbn - 17 - 1 © Jaime Alberto Parra Plaza CLASE 17 FUNCIONES Y PASO DE PARÁMETROS A PROCEDIMIENTOS."

Presentaciones similares


Anuncios Google