Monografias | Componentes básicos de un sistema MS-DOSComponentes básicos de un sistema MS-DOSResumen: Componentes básicos de un sistema ms-dos. Arquitectura interna del intel 80x86. Definición de los sistemas numéricos. Transformaciones. Tipos de programas ejecutables. Acceso a las interrupciones del bios y dos desde rom. Principales interrupciones del bios y del dos. Indice 1. Componentes básicos de un
sistema ms-dos Investigación
Las operaciones de un sistema de computación incluyendo un IBM PC’s ycompatibles están basadas en un concepto simple. Ellas guardan intrusiones ydatos en la memoria y usan el CPU para repetir intrusiones y datos recibidosdesde la memoria y ejecutan las instrucciones para manipular los datos(Computadoras basadas en la Arquitectura de Von Newmann), por lo tanto el CPU yla memoria son los dos componentes básicos de cualquier sistema de computación.La memoria esta definida en dos variedades random access memory (RAM) la quepermite la escritura y la lectura de cualquier localidad de memoria y la readonly memory (ROM), que la que contiene valores que pueden ser leídos pero noalterados. La ROM es usada para almacenar pequeños primitivos programas paraejecutar instrucciones de entrada y salida y control de periféricos. La RAM esusada para el Sistema Operativo y programas para usuarios. El Sistema Operativoes un componente fundamental en un sistema. Este programa de computadoras setoma la tarea de cargar otros programas y ejecutarlos, provee acceso a losarchivos del sistema. La performa la E/S, y hace interfaces interactivas con elusuario. El sistema operativo es el que provee al sistema su personalidad.MS-DOS, OS/2, UNIX son ejemplo de algunos Sistema Operativos para PC,similarmente CP/M es un Sistema Operativos para antiguos microprocesadores deINTEL de 8 Bits como el 8080. El hardware de toda computadora incluyendo lascomputadoras que usan el MS-DOS está interconectados. El CPU, memoria, y periféricos de entrada (teclado, escáner, lápiz óptico,lector de código de barra, micrófono, mouse etc.) y salida (monitor,impresora, cornetas, etc.) están todos interconectados por una serie de cablesllamados Buces y cada Buz esta claramente definido. Un Buz es un hardware queespecifica una señal y tiempo estándar que son seguidos y entendidos por elCPU y su circuito de soporte (incluyendo periféricos aun no instalados). Losbuces a su vez se clasifican en Buz de Datos, Buz de Dirección, y Buz deControl. El Buz de Dirección selecciona la localidad de memoria entre lamemoria usada y el CPU. El Buz de Control refiere la líneas de señales detiempo y la línea de poder a los componentes. Un Sistema Operativo MS-DOS nonecesita ningún tipo de Buz especifico. Esto es porque es posible tener el Buzen un segundo plano y estar ejecutando su sistema y así mismo lo aplica paraotro tipo de programas compatibles. Por ejemplo los antiguos sistemas IBM PC-ATcon los PC-AT Buces y el nuevo IBM PS/2 basado en la arquitectura de MCA (MicroChannel Architecture), y puede ser ejecutado en MS-DOS y OS/2.
2. Arquitectura interna del intel 80x86 Fue el primer microprocesador de 16 bits que INTEL fabrico a principios del año1978. Los objetivos de la arquitectura de dicho procesador fueron los de ampliarla capacidad del INTEL 80x80 de forma simétrica, añadiendo una potencia deproceso no disponible en los micros de 8 bits. Algunas de estas característicasson: aritmética en 16 bits, multiplicación y división con o sin signo,manipulación de cadena de caracteres y operación sobre bits. También se hanrealizado mecanismo de software para la construcción de códigos reentrante yreubicable. Su estructura interna esta representada por la figura numero 1.Consta de 2 unidades claramente diferenciadas denominadas EU (Unidad de Ejecución)y BIU (interfaces del Bus). La EU ejecuta las operaciones requeridas por la instrucciones sobre una UALde 16 bits. No tiene conexión con el exterior y solamente se comunica con laBIU que es la parte que realiza todas las operaciones en el bus solicitadas porla EU. Un mecanismo, tal vez único dentro de los microprocesadores aunque muyempleado dentro de los mínimos y grandes ordenadores, es el denominado de búsquedaanticipada de instrucciones (prefetch). En el INTEL 8086 existe una estructuraFIFO en RAM de 6 octetos de capacidad que es llenada por la BIU con loscontenidos de las intrusiones siguientes a la que la EU esta ejecutando en esemomento. Los registros del procesador se especifican en la figura numero 1. y son lossiguientes: a.-) Cuatro registros de 16 bits, denominados AX,BX,CX y DX, que pueden serdireccionados de 8 registros de 8 bits, denominados AH,AL,....DL. los siete últimosson equivalentes a los registros A, H, L, B, C, D y E, del microprocesador Intel80x86. El registro AX sirve fundamentalmente como acumulador y como registro detrasferencia en las intrusiones E/S. El registro BX puede usarse como acumuladory como registro base para calcular la direcciones de los datos de memoria. Elregistro CX puede usarse como acumulador y se utiliza como contador para lasintrusiones interactivas. El registro DX puede usarse como acumulador y seemplea como puntero de datos en ciertas intrusiones especificas de E/S. b.-) Cuatro registros de puntero de segmento denominado CS, DS, SS y ES.Dicho puntero definen cuatro segmentos de 64 K octetos cada uno. Cualquierdirección de memoria se forma, como ya veremos en el apartado dedireccionamiento, sumando al puntero del segmento una dirección efectivacalculada por diversos procedimientos. El registro CS, (CODE SEGMENT) se usajunto con el PC para calcular las direcciones de las intrusiones del programa;el registro SS (STACK SEGMENT) se emplea junto con el SP (STACK POINTER) paracalcular la dirección de las intrusiones que manejan la pila tales como PUSH,POP, CALL y RETURN; por su parte, el registro DS (DATA SEGMENT) se usa eninstrucciones que manejan datos de memoria y el registro ES (EXTRA SEGMENT) seutiliza en instrucciones que manejan cadena de caracteres. c.-) Cuatro registros que contiene direcciones de desplazamiento dentro delos segmentos denominadas SP, BP, SI, DI. El registro SP puntero de la pila losregistros SI (INDEX SEGMENT) y DI (Índice Destino) contienen desplazamientos delos punteros de segmento DS y ES en las intrusiones que manejan cadena decaracteres. El registro BP (BASE POINTER) es el puntero base. d.-) Un registro contador de programas, PC. e.-) Un registro de estado, S, de 16 bits con la siguiente asignación: Bit bo(C)es el acarreo, Bit b2(P) es el de paridad, Bit b4(A) es elde acarreo auxiliar, Bit b6(Z) el de cero, Bit b7(S) el designo, Bit b8 (T) el de Trap, Bit b9(I) que sirve paracontrolar el bloqueo de las intrusiones, Bit b10(D) que determinan sise han de autoincrementar o autodecrementar los punteros SI y DI en lasintrusiones que manejan cadenas de caracteres, Bit b11(O) queespecifica el desbordamiento (Overflow).
El 8086 representa la arquitectura base para todos los microprocesadores de16 bits de Intel: 8088, 8086, 80188, 80186 y 80286. Aunque han aparecido nuevascaracterísticas a medida que estos microprocesadores han ido evolucionando;todos los procesadores Intel, usados en la actualidad en los PC’s ycompatibles son miembros de la familia 8086. El conjunto de instrucciones,registros y otras características son similares, a excepción de algunosdetalles, todo la familia 80x86 en adelante poseen dos características en común:a) Arquitectura Segmentada, Esto significa que la memoria es divida en segmentoscon un tamaño máximo de 64k (información importante para el direccionamientode la memoria en la futura programación segmentada en el lenguaje ensamblador)y b) Compatibilidad de Las intrusiones y registros de las anteriores versionesson soportados por las nuevas versiones, y estas versiones son soportadas porversiones anteriores. La familia de microprocesadores 80x86 consta de los siguientesmicroprocesadores: 8088: Es un microprocesador de 16 bits, usado en las primeras PC´S (XTcompatibles). Soporte solamente el modo real. Es capaz de direccionar unmegabytes de memoria y posee un bus de datos de 8 bits. El 8086 es Similar al8088, con la excepción de que el bus de datos es de 16 bits. El 0188 es similaral 8088, pero con un conjunto de instrucciones extendidos y ciertas mejoras enla velocidad de ejecución. Se incorporan dentro del microprocesador algunoschips que anteriormente eran externos, consiguiéndose unas mejoras en elrendimiento del mismo. El 80186 es igual al 80188 pero con un bus de datos de 16bits. El 80286 Incluye un conjunto de instrucciones extendidos del 80186, peroademás soporta memoria virtual, modo protegido y multitarea. El 80386 soportaprocesamientos de 16 y 32 bits. El 80386 es capas de manejar memoria real yprotegida, memoria virtual y multitarea. Es más rápido que el 80286 y contieneun conjunto de instrucciones ampliables. El 80386SX es similar al 80386 por unbus de datos de solo 16 bits. El 80486 incorpora un cache interno de 8k yciertas mejoras de velocidad con respecto al 80386. Incluye un coprocesadormatemático dentro del mismo chip. El 80486SX es Similar a los 80486 con ladiferencia que no posee coprocesador matemático y 80486DX2 es Similar al 80486,pero con la diferencia de que internamente, trabaja al doble de la frecuenciaexterna del reloj. El 80x86 tiene dos procesadores en el mismo chip. Estos son La Unidad deEjecución y La Unidad de Interface con los Buces. Cada uno de ellos contiene supropio registro, su propia sección aritmética, sus propias unidades de controly trabajan de manera asincrónica el uno con el otro para proveer la potenciatotal de computo. La unidad de Interface de bus se encarga de buscar lasinstrucciones para adelantar su ejecución y proporciona facilidades en elmanejo de las direcciones. Luego, la unidad de Interface se responsabiliza delcontrol de la adaptación con los elementos externos del CPU central. Dichaunidad de interface proporciona una dirección de 20 Bits o un dato de 16 parala unidad de memoria o para la unidad de E/S en la estructura externa delcomputador. 3. Definición de los sistemas numéricos Sistema decimal Desde hace muchos años, el hombre ha utilizado como sistema para contar eldenominado decimal, que derivó del sistema numérico indoarábigo; posiblementese adoptó este mismo por contar con diez dedos en las manos. El sistema decimales unos de los denominados sistemas posicionales, utilizando un conjunto de símboloscuyo significado depende fundamentalmente de su posición relativa al símbolode coma (.), Denominado coma decimal, que en caso de ausencia se supone colocadaimplícitamente a al derecha. Utiliza como base el 10, que corresponde al númerode símbolos que comprende para la representación de cantidades; estos símbolos(también denominados dígitos) son: 0 1 2 3 4 5 6 7 8 9. Una determinadacantidad, que denominaremos número decimal, se puede expresar de la siguienteforma:
Donde: base = 10, i= posición respecto a la coma, D = Nº. Dígitos a laizquierda de la coma, N = Nº , de dígitos a la Izquierda de la coma, Dígito =cada uno de los que componen el número. Esta forma corresponde al teoremafundamental de la numeración y por tanto corresponde a la representación,Porejemplo, la representación de las cantidad 1992 es:
Sistema binario Es el sistema que utiliza internamente el hardware de las computadorasactuales, por ello será el sistema al que se le prestará mayor atención yestudio. Se basa en la representación de cantidades utilizando los dígitos 1 y0. Por tanto su base es 2 (número de dígitos del sistema). Cada dígito de unnúmero en este sistema se denomina bit (contracción de binary digit). Se puede utilizar con nombre propio determinados conjuntos de dígitos enbinario. Cuatro bits se denominan cuaterno (ejemplo: 1001), ocho bits octeto obyte (ejemplo: 10010110), al conjunto de 1024 bytes se le llama Kilobyte osimplemente K, 1024 Kilobytes forman un megabyte y 1024 megabytes se denominanGigabytes. Sistema octal Es un sistema de numeración cuya base es 8, es decir, utiliza 8 símbolospara la representación de las cantidades, Estos símbolos son; 0 1 2 3 4 5 7.Este sistema también es de los llamados posicionales y la posición de suscifras se mide con relación a la coma decimal que en caso de no aparecer sesupone implícitamente a la derecha del número. La aritmética en este sistemaes similar a la de los sistemas binario y decimal, por lo que no entraremos ensu estudio. Sistema hexadecimal Es un sistema posicional de numeración en el que su base es 16, por tanto,utilizará 16 símbolos para la representación de cantidades, estos símbolosson; 0 1 2 3 4 5 6 7 8 9 A B C D E F. Se la asignan los siguientes valoresabsolutos a los símbolos A, B, C, D, E y F:
Cabe destacar que este sistema numérico tiene mucha utilidad, en lasoperaciones internas del computador, ya que por ejemplo cuando se utiliza elcomando DEBUG, los valores contenidos en todos los registros de memoria seespecifican en hexadecimal. Sí dos valores se suman, restan, multiplican odividen, el resultado se presenta en hexadecimal. Dado que lo más común es elsistema decimal, es necesario efectuar una conversión de hexadecimal yviceversa para obtener el resultado de cualquier operación en el formato DEBUG. Conversión Decimal-Binario: Para convertir números enteros de decimal abinario, la forma más simple es dividir sucesivamente el numero decimal y loscocientes que se van obteniendo por, hasta que una de las divisiones se haga 0.La unión de todos los restos obtenidos escritos en orden inverso, nosproporcionan el número inicial expresado en el sistema binario. Ej.:
10(10)=1010(2)
Conversión de binario a decimal: el método consiste en reescribir élnumero binario en posición vertical de tal forma que la parte de la derechaquede en la zona superior y la parte izquierda quede en la zona inferior. Serepetirá el siguiente proceso para cada uno de los dígitos comenzados por elinferior: Se coloca en orden descendente la potencia de 2 desde el cero hasta n,donde el mismo el tamaño del numero binario, el siguiente ejemplo ilustra de lasiguiente manera. Utilizando el teorema fundamental de la numeración tenemosque 1001.1es igual a:
Conversión decimo octal: Consiste en dividir un numero y sussucesivos cocientes obtenidos por ocho hasta llegar a una división cuyocociente sea 0. El numero Octal buscado es el compuesto por todos los restosobtenidos escritos en orden inverso a su obtención. Ej.:
1000(10)=3710(8) Conversión de una fracción decimal a una octal: Se toma la fraccióndecimal y se multiplica por 8, obteniendo en la parte entera del resultado elprimer dígito de la fracción octal resultante y se repite el proceso con laparte decimal del resultado para obtener el segundo dígito y sucesivos. Elproceso termina cuando desaparece la parte fraccionaria del resultado o dichaparte fraccionaria es inferior al error máximo que deseamos obtener. Ej. : 0.140625*8=1.125 0.140625(10)=0.11(8) Conversión octal a decimal: Existen varios métodos siendo el másgeneralizado el indicado por el TFN (Teorema fundamental de la numeración) quehace la conversión de forma directa por medio de la formula. Ej. : utilizandoel teorema fundamental de la numeración tenemos que 4701 es igual a:
Conversión decimal – hexadecimal: Se divide el numerodecimal y los cocientes sucesivos por 16 hasta obtener un cociente igual a 0. Elnúmero hexadecimal buscado será compuesto por todos logros obtenidos en ordeninverso a su obtención. Ej.:
1000(10)=3E8(16) Conversión de una fracción decimal a hexadecimal: a la fracción decimal semultiplica por 16, obteniendo en la parte entera del resultado el primer dígitode la fracción hexadecimal buscada, y se repite el proceso con la partefraccionaria de este resultado. El proceso se acaba cuando la parte fraccionariadesaparece o hemos obtenido un número de dígitos que nos permita no sobrepasarel máximo error que deseemos obtener. Ej.: Pasar a hexadecimal la fraccióndecimal 0.06640625 0.06640625*16=1.0625 0.0625*16 = 1.0 Luego 0.06640625(10)=0.11(16)
Conversión de hexadecimal-binario: para convertir un numero hexadecimal abinario, se sustituye cada dígito hexadecimal por su representación binariasegún la siguiente tabla.
Ej.: pasar el número 2BC a binario
Finalmente él número hexadecimal en binario es igual a: 001010111100
Ej.: Convertir el número octal 1274 en binario.
Por lo tanto el número octal en binario es igual a: 001010111100
5. Tipos de programas ejecutables Estructura del programa con extensión com: Un programa con extensión COM están almacenados en archivos que contienen una copia fiel del código a ser ejecutado. Ya que no contienen información para la reasignación de localidades, son más compactos y son cargados más rápidamente que sus equivalentes EXE. El MS-DOS no tiene manera de saber si un archivo con extensión COM es un programa ejecutable válido. Este simplemente lo carga en memoria y le transfiere el control. Debido al hecho de que los programas COM son siempre cargados inmediatamente después del PSP y no contienen encabezado que especifique el punto de entrada al mismo, siempre debe comenzar en la dirección 0100h. Esta dirección deberá contener la primera instrucción ejecutable. La longitud máxima de un programa COM es de 65536 bytes, menos la longitud de PSP (256 bytes) y la longitud de la pila (mínimo 2 bytes). Cuando el sistema operativo transfiere el control a un programa COM, todos los registros de segmento apuntan al PSP. El registro apuntador de pila (SP), contiene el valor en la memoria de OFFFEh si la memoria los permite. En otro caso adopta el mínimo valor posible menos dos bytes (el MS-DOS introduce un cero en la pila antes de transferir el control al programa). Aún cuando la longitud de un programa COM no puede exceder de los 64 , las versiones actuales del MS-DOS reservan toda la memoria disponible. Si un programa COM debe ejecutar otro proceso, es necesario que el mismo libere la memoria no usada de tal manera que pueda ser empleada por otra aplicación. Cuando un programa COM termina, puede retornar al control del sistema operativo por varios medios. El método preferido es el uso de la función 4Ch de la Int 21, la cual permite que el programa devuelva un código de retorno al proceso que invocó. Sin embargo, si el programa está ejecutándose bajo la versión 1.00 del MS.DOS, el control debe ser retornado mediante el uso de la Int 20h. Un programa COM puede ser ensamblado a partir de varios módulos objeto, con la condición de todos ellos empleen los mismos nombres y clases de segmentos y asegurando que él modulo inicial, con el punto de entrada en 0100h sea enlazado primero. Adicionalmente todos los procedimientos y funciones deben tener el atributo NEAR, ya que todo el código ejecutable estará dentro del mismo segmento. Al enlazar un programa COM el enlazador mostrará el siguiente mensaje; "Warnig: no stack segment". Este mensaje puede ser ignorado, ya que el mismo se debe a que se ha instruido al enlazador para que genere un programa con extensión EXE donde el segmento de pila debe ser indicado de manera explícita, y no así en los COM donde esta es asumida por defecto. En la zona desde 000Ah hasta 0015h dentro del PSP se encuentran las direcciones de las rutinas manejadoras de los eventos Ctrl-C y Error critico. Si el programa de aplicación altera estos valores para sus propios propósitos, el MS-DOS los restaura al finalizar la ejecución del mismo. Estructura del prefijo de programa.
La palabra de datos en desplazamiento 002Ch contiene la direccion delsegmento de bloque de variables de ambiente (Environment block), el cualcontiene una serie de cadenas ASCIIZ. Este bloque es heredado del proceso quecauso la ejecución del programa aplicación. Entre la información que contienetenemos, el paso usado por el COMAND.COM para encontrar el archivo ejecutable,el lugar del disco donde se encuentra el propio COMAND.COM y el formato delprompt empleado por este. La cola de comandos, la cual está constituida por loscaracteres restantes en la línea de comandos, después del nombre del programa,es copiado a partir de la localidad 0081h en el PSP. La longitud de la cola, sinincluir el carácter de retorno al final, está ubicada en la posición 0080h.Los parámetros relacionados con redireccionamiento o piping no aparecen en estaposición de la linea de comandos, ya que estos procesos son transparentes a losprogramas de aplicación. Para proporcionar compatibilidad con CP/M, el MS-DOScoloca los dos primeros comandos en la cola, dentro de los bloques de controldel archivo (FCD) por defecto en las direcciones PSP:005Ch yPSP:006Ch asumiendoque pueden ser nombre de archivos. Sin embargo, si alguno de estos comandos sonnombres de archivos que incluyen especificaciones del paso, la informacióncolocada en los FCB no será de utilidad ya que estas estructuras no soportan elmanejo de estructuras jerárquicas de archivos y subdirectorios. Los FCB son demuy escaso uso en los programas de aplicación modernos. El área de 128 bytesubicado entre las direcciones 0080h y 00FFh en el PSP pueden también servircomo área de transferencia de disco por defecto (DTA), la cual es establecidapor el MS-DOS antes de transferir el control al programa de aplicación. A menosque el programa establezca de manera explícita otra DTA, este será usado comobuffer de datos para cualquier intercambio con disco que este efectué. Losprogramas de aplicación no deben alterar la información contenida en el PSP apartir de la dirección 005Ch. Estructura de un programa de extension exe: Los programas EXE son ilimitadosen tamaño (él limite lo dictamina la memoria disponible del equipo). Además,los programas EXE pueden colocar el código, datos y pila en distintos segmentosde la memoria. La oportunidad de colocar las diversas partes de un programa enfragmentos diferentes de memoria y la de establecer segmentos de memoria consolamente códigos de que pudieran ser compartidos por varias tareas, es unsignificativo para ambientes multitareas tales como el Microsoft Windows. Elcargador del MS-DOS, sitúa al programa EXE, inmediatamente después del PSP,aunque el orden de los segmentos que lo constituyen pueden variar. El archivoEXE contiene un encabezado, bloque de información de control, con un formatocaracterístico. El tamaño de dicho encabezado pude variar dependiendo delnumero de instrucciones que deben ser localizadas al momento de carga delprograma, pero siempre será múltiplo de 512. Antes de que el MS-DOS transfierael control al programa, se calculan los valores iniciales del registro delsegmento de código (CS) y el apuntador de instrucciones (IP) basados en lainformación sobre el punto de entrada, al programa, contenida en el encabezadodel archivo EXE. Esta información es general a partir de la instrucción END enél modulo principal del programa fuente. Los registros de segmentos de datos ysegmentos extras inicializados de manera que apunten al PSP de tal manera que elprograma pueda tener acceso a la información contenida. Imagen de Memoria de un programa EXE típico
Formato de un archivo de carga EXE.
El contenido inicial del segmento de pila y de la apuntador de pila provienentambién del encabezado del archivo. Esta información es derivada de ladeclaración del segmento de pila efectuada mediante la sentencia STACK. Elespacio reservado para la pila puede ser inicializado o no dependiendo de lamanera como este haya sido declarado. Puede ser conveniente en muchos casosinicializar el segmento de pila con un patrón de caracteres predeterminados quepermitan su posterior inspección. Cuando el programa EXE finaliza su ejecucióndebe retornar el control al sistema operativo mediante la función 4Ch de la Int21h. Existen otros métodos, pero no ofrecen ninguna otra ventaja y sonconsiderablemente menos convenientes " Generalmente requieren que elregistro CS apunte al segmento de PSP". Un programa EXE puede ser construido a partir de varios módulosindependientes. Cada modulo puede tener nombres diferentes para el segmento de códigoy los procedimientos pueden llevar el atributo NEAR o FAR, dependiendo del tamañodel programa ejecutable. El programador debe asegurarse de que los módulos, aser enlazados solo tenga una declaración de segmento de pila y que haya sioddefinido un único punto de entrada (por medio de la directiva END). La salidadel enlazador es un archivo con extensión EXE el cual puede ser ejecutadoinmediatamente.
6. Acceso a las interrupciones del bios y dos desde rom
7. Principales Interrupciones del BIOS y del DOS
Anexo Nº 1
Medina, Ramon. Programación avanzada en lenguaje ensamblador. 1992, Págs.7-19. Barbakati, Nabaiyoti. Haybe, Randal. The waite group´s microsoft macroassembler bible. Godfrey, Terry J.Lenguaje ensamblador para microcomputadoras ibm(paraprincipiantes y avanzados). 1991, Editorial Prentice-hall hispanoamericana,S.A. Págs. 8-12 y 143-148. Alcalde E.; García M.; Peñuelas S. Informática básica.1988,Editorial McGraw-Hill. Págs. 23-48.
Autor: Publicación enviada por Miguel Pita Contactar mailto:m_pita@hotmail.com Código ISPN de la Publicación EpVAZVyZFAddUGTiMP Publicado Friday 1 de August de 2003 Ultimas Publicaciones en ilustrados.com
ilustrados.com nace con el fin difundir el conocimiento publicando trabajos de investigación, monografias, tesis, presentaciones powerpoint y afines. Publicar trabajos en ilustrados.com ha alcanzado prestigio y reconocimiento internacional siendo cada vez más el número de académicos, empresas, investigadores, científicos que consultan las publicaciones de nuestro portal. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||