Datos Personales















NOMBRE ALUMNO:
Antonio Ivan Hernandez Barcenas

MATERIA:
Organización y Arquitecturas de Computadoras
GRUPO:
3-F


LIGAS DE INTERES:

Para que mires las mejores series ONLINE!!
www.seriesflv.net

Para que descargues las mejores peliculas!!



 

Compilador

Diagrama a bloques de la operación de un buen compilador.Un compilador es un programa informático que traduce un programa escrito en un lenguaje de programación a otro lenguaje de programación, generando un programa equivalente que la máquina será capaz de interpretar. Usualmente el segundo lenguaje es lenguaje de máquina, pero también puede ser simplemente texto. Este proceso de traducción se conoce como compilación.
Un compilador es un programa que permite traducir el código fuente de un programa en lenguaje de alto nivel, a otro lenguaje de nivel inferior (típicamente lenguaje de máquina). De esta manera un programador puede diseñar un programa en un lenguaje mucho más cercano a como piensa un ser humano, para luego compilarlo a un programa más manejable por una computadora.

Partes de un compilador

La construcción de un compilador involucra la división del proceso en una serie de fases que variará con su complejidad. Generalmente estas fases se agrupan en dos tareas: el análisis del programa fuente y la síntesis del programa objeto.
Análisis: Se trata de la comprobación de la corrección del programa fuente, e incluye las fases correspondientes al Análisis Léxico (que consiste en la descomposición del programa fuente en componentes léxicos), Análisis Sintáctico (agrupación de los componentes léxicos en frases gramaticales ) y Análisis Semántico (comprobación de la validez semántica de las sentencias aceptadas en la fase de Análisis Sintáctico).

Síntesis: Su objetivo es la generación de la salida expresada en el lenguaje objeto y suele estar formado por una o varias combinaciones de fases de Generación de Código (normalmente se trata de código intermedio o de código objeto) y de Optimización de Código (en las que se busca obtener un código lo más eficiente posible).
Alternativamente, las fases descritas para las tareas de análisis y síntesis se pueden agrupar en Front-end y Back-end:
Front-end: es la parte que analiza el código fuente, comprueba su validez, genera el árbol de derivación y rellena los valores de la tabla de símbolos. Esta parte suele ser independiente de la plataforma o sistema para el cual se vaya a compilar, y está compuesta por las fases comprendidas entre el Análisis Léxico y la Generación de Código Intermedio.

Back-end: es la parte que genera el código máquina, específico de una plataforma, a partir de los resultados de la fase de análisis, realizada por el Front End.
Esta división permite que el mismo Back End se utilice para generar el código máquina de varios lenguajes de programación distintos y que el mismo Front End que sirve para analizar el código fuente de un lenguaje de programación concreto sirva para generar código máquina en varias plataformas distintas. Suele incluir la generación y optimización del código dependiente de la máquina.
El código que genera el Back End normalmente no se puede ejecutar directamente, sino que necesita ser enlazado por un programa enlazador (linker)

Tipos de compiladores
Esta taxonomía de los tipos de compiladores no es excluyente, por lo que puede haber compiladores que se adscriban a varias categorías:
• Compiladores cruzados: generan código para un sistema distinto del que están funcionando.
• Compiladores optimizadores: realizan cambios en el código para mejorar su eficiencia, pero manteniendo la funcionalidad del programa original.
• Compiladores de una sola pasada: generan el código máquina a partir de una única lectura del código fuente.
• Compiladores de varias pasadas: necesitan leer el código fuente varias veces antes de poder producir el código máquina.
• Compiladores JIT (Just In Time): forman parte de un intérprete y compilan partes del código según se necesitan.
Pauta de creación de un compilador: En las primeras épocas de la informática, el software de los compiladores era considerado como uno de los más complejos existentes.
Los primeros compiladores se realizaron programándolos directamente en lenguaje máquina o en ensamblador. Una vez que se dispone de un compilador, se pueden escribir nuevas versiones del compilador (u otros compiladores distintos) en el lenguaje que compila ese compilador.
Actualmente existen herramientas que facilitan la tarea de escribir compiladores ó intérpretes informáticos. Estas herramientas permiten generar el esqueleto del analizador sintáctico a partir de una definición formal del lenguaje de partida, especificada normalmente mediante una gramática formal y barata, dejando únicamente al programador del compilador la tarea de programar las acciones semánticas asociadas.
Proceso de compilación
Es el proceso por el cual se traducen las instrucciones escritas en un determinado lenguaje de programación a lenguaje máquina. Además de un traductor, se pueden necesitar otros programas para crear un programa objeto ejecutable. Un programa fuente se puede dividir en módulos almacenados en archivos distintos. La tarea de reunir el programa fuente a menudo se confía a un programa distinto, llamado preprocesador. El preprocesador también puede expandir abreviaturas, llamadas a macros, a proposiciones del lenguaje fuente.
Normalmente la creación de un programa ejecutable (un típico.exe para Microsoft Windows o DOS) conlleva dos pasos. El primer paso se llama compilación (propiamente dicho) y traduce el código fuente escrito en un lenguaje de programación almacenado en un archivo a código en bajo nivel (normalmente en código objeto, no directamente a lenguaje máquina). El segundo paso se llama enlazado en el cual se enlaza el código de bajo nivel generado de todos los ficheros y subprogramas que se han mandado compilar y se añade el código de las funciones que hay en las bibliotecas del compilador para que el ejecutable pueda comunicarse directamente con el sistema operativo, traduciendo así finalmente el código objeto a código máquina, y generando un módulo ejecutable.
Estos dos pasos se pueden hacer por separado, almacenando el resultado de la fase de compilación en archivos objetos (un típico.obj para Microsoft Windows, DOS o para Unix); para enlazarlos en fases posteriores, o crear directamente el ejecutable; con lo que la fase de compilación se almacena sólo temporalmente. Un programa podría tener partes escritas en varios lenguajes (por ejemplo C, C++ y Asm), que se podrían compilar de forma independiente y luego enlazar juntas para formar un único módulo ejecutable.


 

Memoria Virtual

La memoria virtual es una técnica que permite al software usar más memoria principal que la que realmente posee el ordenador. La mayoría de los ordenadores tienen cuatro tipos de memoria: registros en la CPU, la memoria caché (tanto dentro como fuera del CPU), la memoria física (generalmente en forma de RAM, donde la CPU puede escribir y leer directa y razonablemente rápido) y el disco duro que es mucho más lento, pero también más grande y barato.

Muchas aplicaciones requieren el acceso a más información (código y datos) que la que se puede mantener en memoria física. Esto es así sobre todo cuando el sistema operativo permite múltiples procesos y aplicaciones ejecutándose simultáneamente. Una solución al problema de necesitar mayor cantidad de memoria de la que se posee consiste en que las aplicaciones mantengan parte de su información en disco, moviéndola a la memoria principal cuando sea necesario. Hay varias formas de hacer esto. Una opción es que la aplicación misma sea responsable de decidir qué información será guardada en cada sitio (segmentación), y de traerla y llevarla. La desventaja de esto, además de la dificultad en el diseño e implementación del programa, es que es muy probable que los intereses sobre la memoria de dos o varios programas generen conflictos entre sí: cada programador podría realizar su diseño teniendo en cuenta que es el único programa ejecutándose en el sistema. La alternativa es usar memoria virtual, donde la combinación entre hardware especial y el sistema operativo hace uso de la memoria principal y la secundaria para hacer parecer que el ordenador tiene mucha más memoria principal (RAM) que la que realmente posee. Este método es invisible a los procesos. La cantidad de memoria máxima que se puede hacer ver que hay tiene que ver con las características del procesador. Por ejemplo, en un sistema de 32 bits, el máximo es 232, lo que da 4096 Megabytes (4 Gigabytes). Todo esto hace el trabajo del programador de aplicaciones mucho más fácil, al poder ignorar completamente la necesidad de mover datos entre los distintos espacios de memoria.


Aunque la memoria virtual podría estar implementada por el software del sistema operativo, en la práctica casi siempre se usa una combinación de hardware y software, dado el esfuerzo extra que implicaría para el procesador.
 

Administracion de Memoria

Se le llama administración de memoria a los diversos métodos y operaciones destinados a obtener la máxima utilidad y provecho de una memoria informática, en pos del buen uso y funcionamiento del sistema en su totalidad.

Una memoria informática consiste en la serie de componentes, dispositivos y medios en una computadora que tienen el fin de retener y almacenar datos informáticos en forma circunstancial o permanente. Toda computadora moderna dispone de unidades de memoria que permiten el correcto funcionamiento del CPU o Unidad Central de Procesamiento.
Las hay de distintos tamaños y formatos. Una memoria puede ser un chip inserto en el interior de la computadora, pero también puede considerarse memoria al uso de unidades externas de almacenamiento como CDs, DVDs o memorias flash. A menudo una computadora dispone de una memoria principal, pero ésta puede ser complementada con otras unidades de memoria que se agreguen o con memorias movibles que permitan intercambiar datos entre varias computadoras.

La administración de memoria refiere, entonces, a la serie de métodos y procesos que se llevan adelante desde la parte usuaria a los efectos de obtener el mejor rendimiento posible por parte de estas unidades.

Estas operaciones son múltiples y tienen distintos usos y objetivos directos. Por ejemplo, una típica operación es trasladar la información a ser ejecutada dentro y fuera de la memoria principal, procurando maximixar el uso del procesador. Otras operaciones comunes son la protección de los procesos de interferencias de otros, uso compartido de datos, para que varios procesos compartan la misma información y memoria, partición de memoria en varias partes, limpieza de datos en la memoria que son poco utilizados o irrelevantes, formateo de disco y muchas otras.


Todos estos procesos son flexibles y dependen del uso y propósito del ordenador por parte del usuario para optimizar su rendimiento. Con frecuencia, la ejecución de estas operaciones brindará mayor espacio disponible para el almacenamiento de información y proporcionará una mayor agilidad en la gestión de procesos de diversa índole y nivel.
 

Sistemas Operativos. Parte2

Componentes Y Servicios Basicos De Un Sistema Operativo
Componentes del sistema operativo

El sistema operativo está compuesto por un conjunto de paquetes de software que pueden utilizarse para gestionar las interacciones con el hardware.Estos elementos se incluyen por lo general en este conjunto de software:

• El núcleo, que representa las funciones básicas del sistema operativo, como por ejemplo, la gestión de la memoria, de los procesos, de los archivos, de las entradas/salidas principales y de las funciones de comunicación.
• El intérprete de comandos, que posibilita la comunicación con el sistema operativo a través de un lenguaje de control, permitiendo al usuario controlar los periféricos sin conocer las características del hardware utilizado, la gestión de las direcciones físicas, etcétera.
• El sistema de archivos, que permite que los archivos se registren en una estructura arbórea.

Servicios Del Sistema Operativo


El S.O. ofrece a los programas una serie de servicios para trabajar en el computador:
• Ejecución de programas
• Operaciones de E/S
• Manipulación de archivos y directorios
• Comunicación entre procesos
• Comunicación con equipos remotos
• Administración de la protección y seguridad
• Leer el estado del sistema (hora, nº de procesos, etc.)

Administracion De Procesos

La implementación del modelo de procesos se logra debido a que el sistema operativo almacena en una tabla denominada tabla de control de procesos información relativa a cada proceso que se esta ejecutando en el procesador. Cada línea de esta tabla representa a un proceso.

La información que se almacena es la siguiente:


• Identificación del proceso.
• Identificación del proceso padre.
• Información sobre el usuario y grupo.
• Estado del procesador.
• Información de control de procesoInformación del planificador.
• Segmentos de memoria asignados.
• Recursos asignados.




 

Sistemas Operativos

Un sistema operativo (SO o, frecuentemente, OS —del inglés Operating System—) es un programa o conjunto de programas que en un sistema informático gestiona los recursos de hardware y provee servicios a los programas de aplicación, ejecutándose en modo privilegiado respecto de los restantes (aunque puede que parte del mismo se ejecute en espacio de usuario)




Necesidad de los Sistemas Operativos
Según [Alcal92], se deben observar dos tipos de requisitos cuando se construye un sistema operativo, los cuales son:
Requisitos de usuario: Sistema fácil de usar y de aprender, seguro, rápido y adecuado al uso al que se le quiere destinar.
Requisitos del software: Donde se engloban aspectos como el mantenimiento, forma de operación, restricciones de uso, eficiencia, tolerancia frente a los errores y flexibilidad.


Componentes y servicios básicos de un sistema operativo
El sistema operativo está compuesto por un conjunto de paquetes de software que pueden utilizarse para gestionar las interacciones con el hardware.Estos elementos se incluyen por lo general en este conjunto de software: 
• El núcleo, que representa las funciones básicas del sistema operativo, como por ejemplo, la gestión de la memoria, de los procesos, de los archivos, de las entradas/salidas principales y de las funciones de comunicación.
• El intérprete de comandos, que posibilita la comunicación con el sistema operativo a través de un lenguaje de control, permitiendo al usuario controlar los periféricos sin conocer las características del hardware utilizado, la gestión de las direcciones físicas, etcétera.
• El sistema de archivos, que permite que los archivos se registren en una estructura arbórea.
Servicios Del Sistema Operativo

• Operaciones de E/S
• Manipulación de archivos y directorios
• Comunicación entre procesos
• Comunicación con equipos remotos
• Administración de la protección y seguridad
• Leer el estado del sistema (hora, nº de procesos, etc.)


Tipos de sistemas operativos
A continuación se describen las distintas estructuras que presentan los actuales sistemas operativos para satisfacer las necesidades que de ellos se quieren obtener.


1.1 Estructura monolítica.
Es la estructura de los primeros sistemas operativos constituídos fundamentalmente por un solo programa compuesto de un conjunto de rutinas entrelazadas de tal forma que cada una puede llamar a cualquier otra. Las características fundamentales de este tipo de estructura son:
Construcción del programa final a base de módulos compilados separadamente que se unen a través del ligador.
Buena definición de parámetros de enlace entre las distintas rutinas existentes, que puede provocar mucho acoplamiento.
Carecen de protecciones y privilegios al entrar a rutinas que manejan diferentes aspectos de los recursos de la computadora, como memoria, disco, etc.
Generalmente están hechos a medida, por lo que son eficientes y rápidos en su ejecución y gestión, pero por lo mismo carecen de flexibilidad para soportar diferentes ambientes de trabajo o tipos de aplicaciones.

1.2 Estructura jerárquica.
A medida que fueron creciendo las necesidades de los usuarios y se perfeccionaron los sistemas, se hizo necesaria una mayor organización del software, del sistema operativo, donde una parte del sistema contenía subpartes y esto organizado en forma de niveles.
Se dividió el sistema operativo en pequeñas partes, de tal forma que cada una de ellas estuviera perfectamente definida y con un claro interface con el resto de elementos.
Se constituyó una estructura jerárquica o de niveles en los sistemas operativos, el primero de los cuales fue denominado THE (Technische Hogeschool, Eindhoven), de Dijkstra, que se utilizó con fines didácticos. Se puede pensar también en estos sistemas como si fueran `multicapa'. Multics y Unix caen en esa categoría. [Feld93].

 1.3 Máquina Virtual.
Se trata de un tipo de sistemas operativos que presentan una interface a cada proceso, mostrando una máquina que parece idéntica a la máquina real subyacente. Estos sistemas operativos separan dos conceptos que suelen estar unidos en el resto de sistemas: la multiprogramación y la máquina extendida. El objetivo de los sistemas operativos de máquina virtual es el de integrar distintos sistemas operativos dando la sensación de ser varias máquinas diferentes.
El núcleo de estos sistemas operativos se denomina monitor virtual y tiene como misión llevar a cabo la multiprogramación, presentando a los niveles superiores tantas máquinas virtuales como se soliciten. Estas máquinas virtuales no son máquinas extendidas, sino una réplica de la máquina real, de manera que en cada una de ellas se pueda ejecutar un sistema operativo diferente, que será el que ofrezca la máquina extendida al usuario


1.4 Cliente-servidor ( Microkernel)
El tipo más reciente de sistemas operativos es el denominado Cliente-servidor, que puede ser ejecutado en la mayoría de las computadoras, ya sean grandes o pequeñas.
Este sistema sirve para toda clase de aplicaciones por tanto, es de propósito general y cumple con las mismas actividades que los sistemas operativos convencionales.
El núcleo tiene como misión establecer la comunicación entre los clientes y los servidores. Los procesos pueden ser tanto servidores como clientes. Por ejemplo, un programa de aplicación normal es un cliente que llama al servidor correspondiente para acceder a un archivo o realizar una operación de entrada/salida sobre un dispositivo concreto. A su vez, un proceso cliente puede actuar como servidor para otro." [Alcal92]. Esteparadigma ofrece gran flexibilidad en cuanto a los servicios posibles en el sistema final, ya que el núcleo provee solamente funciones muy básicas de memoria, entrada/salida, archivos y procesos, dejando a los servidores proveer la mayoría que el usuario final o programador puede usar. Estos servidores deben tener mecanismos de seguridad y protección que, a su vez, serán filtrados por el núcleo que controla el hardware.

 

Interprete

  Un intérprete permite que un programa fuente escrito en un determinado lenguaje vaya traduciéndose y ejecutándose directamente, sentencia a sentencia, por el ordenador. El intérprete capta una sentencia fuente, la analiza e interpreta, dando lugar a su ejecución inmediata, no creándose, por tanto, un archivo o programa objeto almacenaje en memoria masiva para posteriores ejecuciones. La ejecución del programa estará supervisada por el intérprete.
            En la práctica, el usuario crea un archivo con el programa fuente. Esto suele realizarse con un editor específico del propio intérprete del lenguaje. Según se van almacenado las instrucciones simbólicas, se analizan y se producen los mensajes de error correspondientes; así, el usuario puede proceder inmediatamente a su corrección. Una vez creado el archivo fuente, el usuario puede dar la orden de ejecución y el intérprete lo ejecuta línea a línea. Siempre el análisis antecede inmediatamente a la ejecución.
            Si utilizamos un intérprete para traducir un programa, cada vez que necesitemos ejecutar el programa se volverá a analizar, ya que, no se genera un fichero objeto. En cambio, con un compilador, aunque sea más lenta, la traducción sólo debe realizarse una vez. Además los traductores no permiten realizar optimizaciones del código (que eliminan órdenes innecesarias compactando el código) más allá del contexto de cada sentencia del programa.

            La principal ventaja de los intérpretes frente a los compiladores es que resulta más fácil localizar y corregir errores de los programas, ya que la ejecución de un programa bajo un intérprete puede interrumpirse en cualquier momento para conocer los valores de las distintas variables y la instrucción fuente que acaba de ejecutarse. Con un compilador esto no se puede realizar, salvo que el programa se ejecute bajo el control de un programa especial de ayuda denominado depurador (“debugger”). Por este motivo, los intérpretes resultan más pedagógicos para aprender a programar, ya que el alumno puede detectar y corregir más fácilmente sus errores.
 

Ensamblador

Ensamblador se refiere a un tipo de programa, informático que se encarga de traducir un fichero fuente escrito en un lenguaje ensamblador, a un fichero objeto que contiene código máquina ejecutable directamente por la máquina para la que se ha generado, en si la funcion de un ensamblador es traducir un programa en lenguaje de ensamblador al código correspondiente en lenguaje de maquina.

Ventajas para utilizarlo:
Mayor control de la computadora.
Independencia de lenguaje.
La mayoría de las computadoras pueden ensamblar.
Los programas hechos en lenguaje ensamblador son generalmente más rápidos y consumen menos recursos del sistema.

Desventajas para no utilizarlo:
Demasiado complejo.
Comprensión más profunda de la computadora.
Errores más frecuentes en el programa.
Mayor tiempo de codificación.
Difícilmente portable, es decir, un código escrito para un microprocesador en particular necesita ser modificado muchas veces en su totalidad para poder ser usado en otro microprocesador.

Tipos de ensambladores:
Ensambladores cruzados: Se denominan así a los ensambladores que se utilizan en una computadora que posee el procesador diferente al que tendrán las computadoras donde se va a ejecutar el programa objeto producido.

Ensambladores residentes: Son aquellas que permanecen en la memoria principal de la computadora y cargar para su ejecución al programa objeto producido.


Micro ensambladores: Al programa que indica al intérprete de instrucciones de la CPU como debe actuar se le denomina microprograma. El programa que ayuda a realizar este microprograma se llama micro ensamblador.

Macro ensambladores: Son ensambladores que permiten el uso de macroinstrucciones.

Ensambladores de una fase: Leen una línea y la traducen directamente para producir una instrucción de lenguaje maquina o la ejecuta si se trata de una pseudosinstrucción. Se construye la tabla de símbolos a medida que aparecen las definiciones de variables, etiquetas, etc.

Ensambladores de dos fases: Realiza la traducción en dos etapas: 1° fase leen el programa fuente y construyen la tabla de símbolos, 2° fase vuelve a leer el programa fuente y pueden ir traduciendo totalmente pues reconocen la totalidad de los símbolos.











 

Tipos de Lenguaje


Una computadora es una máquina que solo comprende las instrucciones que se le den en un determinado formato. Cada máquina reconoce y ejecuta un número de instrucciones diferentes que se agrupan en los distintos lenguajes de programación.
Los lenguajes más próximos a la arquitectura hardware se denominan lenguajes de bajo nivel y los que se encuentran más cercanos a los programadores y usuarios se denominan lenguajes de alto nivel.

Lenguajes de bajo nivel

Son lenguajes totalmente dependientes de la máquina, es decir que el programa que se realiza con este tipo de lenguajes no se pueden migrar o utilizar en otras maquinas.

Al estar prácticamente diseñados a medida del hardware, aprovechan al máximo las características del mismo.

Dentro de este grupo se encuentran:



·         El lenguaje maquina: este lenguaje ordena a la máquina las operaciones fundamentales para su funcionamiento. Cnsiste en la combinación de 0's y 1's para formar las ordenes entendibles por el hardware de la maquina.
Este lenguaje es mucho más rápido que los lenguajes de alto nivel.
La desventaja es que son bastantes difíciles de manejar y usar, además de tener códigos fuente enormes donde encontrar un fallo es casi imposible.
·         El lenguaje ensamblador es un derivado del lenguaje maquina y esta formado por abreviaturas de letras y números llamadas mnemotécnicos. Con la aparición de este lenguaje se crearon los programas traductores para poder pasar los programas escritos en lenguaje ensamblador a lenguaje máquina. Como ventaja con respecto al código máquina es que los códigos fuentes eran más cortos y los programas creados ocupaban menos memoria. Las desventajas de este lenguaje siguen siendo prácticamente las mismas que las del lenguaje ensamblador, ñadiendo la dificultad de tener que aprender un nuevo lenguaje difícil de probar y mantener.

Lenguajes de alto nivel

Son aquellos que se encuentran más cercanos al lenguaje natural que al lenguaje máquina.
Están dirigidos a solucionar problemas mediante el uso de EDD's.


Nota: EDD's son las abreviaturas de Estructuras Dinamicas de Datos, algo muy utilizado en todos los lenguajes de programación. Son estructuras que pueden cambiar de tamaño durante la ejecución del programa. Nos permiten crear estructuras de datos que se adapten a las necesidades reales de un programa.

Se tratan de lenguajes independientes de la arquitectura del ordenador. Por lo que, en principio, un programa escrito en un lenguaje de alto nivel, lo puedes migrar de una máquina a otra sin ningún tipo de problema.

Estos lenguajes permiten al programador olvidarse por completo del funcionamiento interno de la maquina/s para la que están diseñando el programa. Tan solo necesitan un traductor que entiendan el código fuente como las características de la maquina.

Suelen usar tipos de datos para la programación y hay lenguajes de propósito general (cualquier tipo de aplicación) y de propósito especifico (como FORTRAN para trabajos científicos).

Lenguajes de Medio nivel

Se trata de un termino no aceptado por todos, pero q seguramente habrás oído. Estos lenguajes se encuentran en un punto medio entre los dos anteriores. Dentro de estos lenguajes podría situarse C ya que puede acceder a los registros del sistema, trabajar con direcciones de memoria, todas ellas características de lenguajes de bajo nivel y a la vez realizar operaciones de alto nivel.

Generaciones

La evolución de los lenguajes de programación se puede dividir en 5 etapas o generaciones.



·         Primera generación: lenguaje maquina.
·         Segunda generación: se crearon los primeros lenguajes ensambladores.
·         Tercera generación: se crean los primeros lenguajes de alto nivel. Ej. C, Pascal, Cobol…
·         Cuarta generación. Son los lenguajes capaces de generar código por si solos, son los llamados RAD, con lo cuales se pueden realizar aplicaciones sin ser un experto en el lenguaje. Aquí también se encuentran los lenguajes orientados a objetos, haciendo posible la reutilización d partes del código para otros programas. Ej. Visual, Natural Adabes…

·         Quinta generación: aquí se encuentran los lenguajes orientados a la inteligencia artificial. Estos lenguajes todavía están poco desarrollados.