INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
1 FUNDAMENTOS 1.1 INTRODUCCIÓN Todo procesador, grande o pequeño, desde el de una calculadora hasta el de un supercomputador, ya sea de propósito general o específico, posee un lenguaje único que es capaz de reconocer y ejecutar. Por razones que resultan obvias, este lenguaje ha sido denominado Lenguaje Máquina y más que ser propio de un computador pertenece a su microprocesador. El lenguaje Máquina está compuesto por una serie de instrucciones, que son las únicas que pueden ser reconocidas y ejecutadas por el microprocesador. Este lenguaje es un conjunto de números que representan las operaciones que realiza el microprocesador a través de su circuitería interna. Estas instrucciones, por decirlo así, están grabadas o "alambradas" en el hardware y no pueden ser cambiadas. El nivel más bajo al que podemos aspirar a llegar en el control de un microprocesador es precisamente el del lenguaje de máquina. Obviamente es el lenguaje más simple es el empleado por el propio ordenador (compuesto de 0 y 1, código binario). Es comprensible que al usar sólo ceros y unos su utilización sea difícil, larga y motivo de frecuentes errores. Con el Lenguaje Máquina, se obtiene un control total del microprocesador sin embargo, la programación en este lenguaje resulta muy difícil y fácil para cometer errores. No tanto por el hecho de que las instrucciones son sólo números, sino porque se debe calcular y trabajar con las direcciones de memoria de los datos, los saltos y las direcciones de llamadas a subrutinas, además de que para poder hacer ejecutable un programa, se deben enlazar las rutinas de run-time y servicios del sistema operativo. Este proceso es al que se le denomina ensamblado de código. Para facilitar la elaboración de programas a este nivel, se desarrollaron los Ensambladores y el Lenguaje Ensamblador. Lenguaje Ensamblador Programar en Ensamblador es como programar en un lenguaje máquina ya que hay una identificación entre lenguaje máquina de 0 y 1 y un lenguaje simbólico El ensamblador es un lenguaje intermedio, creado para facilitar la comunicación entre el hombre y la máquina. Utiliza códigos nmotécnicos o nmónicos, generalmente difíciles de aprender y que además son específicos de cada microprocesador. Para facilitar el trabajo del programador y hacer la programación accesible al mayor número de personas, se han creado lenguajes avanzados, que no dependen del ordenador. En realidad, estos lenguajes son programas que convierten las distintas instrucciones y datos en lenguaje máquina, el único que es procesado por el ordenador. Por lo tanto, se deduce que el Lenguaje Ensamblador es un lenguaje de bajo nivel compuesto por una serie de códigos nmotécnicos (o nmónicos) o de petición que son traducidos a lenguaje máquina. Sus características son: 1. Muy rápido. 2. Difícil de aprender. 3. Propio de cada procesador. Una característica fundamental del lenguaje ensamblador es que cada una de sus sentencias es una codificación simbólica de una instrucción numérica máquina. Otra característica que presenta es que nos permite llegar a usar cualquier recurso del sistema (hw), cosa que no nos permiten los lenguajes de alto nivel. 1
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
El uso de referencias simbólicas es una característica básica del lenguaje ensamblador, evitando tediosos cálculos y direccionamiento manual luego de cada modificación del programa. También incluyen facilidades para crear macros , a fin de generar series de instrucciones cortas que se ejecutan en tiempo real, en lugar de utilizar subrutinas. Existe una correspondencia 1 a 1 entre las instrucciones del lenguaje de máquina y las del lenguaje ensamblador. Cada uno de los valores numéricos del lenguaje de máquina tiene una representación simbólica de 3 a 5 letras como instrucción del lenguaje ensamblador. Adicionalmente, este lenguaje proporciona un conjunto de pseudo-operaciones (también conocidas como directivas del ensamblador) que sirven para definir datos, rutinas y todo tipo de información para que el programa ejecutable sea creado de determinada forma y en determinado lugar. El propósito para el que se crearon este tipo de aplicaciones es la de facilitar la escritura de programas, ya que escribir directamente en código binario, que es el único código entendible por la computadora, es en la práctica imposible.
USUARIO
P R O G R A M A D O R
APLICACIONES
Lenguajes Visuales
SOFTWARE
Lenguaje de Alto Nivel Lenguaje Ensamblador
HARDWARE Lenguaje Máquina
Ensambladores El proceso importante que convierte las instrucciones de Lenguaje Ensamblador en un código Máquina es el de traducción. Los traductores son programas que realizan ese proceso de conversión. En el proceso de traducción es necesario identificar los diferentes tipos de código que se involucran. Código Fuente se denomina al programa escrito con las instrucciones propias del lenguaje. El Código Objeto es el que se genera cuando ha pasado por la traducción y está escrito generalmente en código máquina. Los traductores se dividen en dos grupos dependiendo de la relación entre código fuente y código objeto. Cuando una instrucción de un código fuente nos genera una única instrucción numérica máquina decimos que ese código fuente es ensamblador. Cuando la instrucción simbólica de código fuente (como Basic, Cobol, Fortran, llamados de Lenguajes de Alto Nivel) nos genera varias instrucciones máquina o varias instrucciones simbólicas de otro lenguaje, el traductor realiza la transformación en una de 2 formas: Cuando todas las instrucciones son traducidas en un solo bloque se le llama compilador. Si las instrucciones y datos son traducidas a lenguaje máquina línea por línea, entonces se llama intérprete. 2
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel Un ensamblador crea código objeto traduciendo instrucciones mnemónicas a códigos operativos, y resolviendo los nombres simbólicos para posiciones de memoria y otras entidades. Los ensambladores son por lo general más fáciles de programar que los compiladores de lenguajes de alto nivel, y han estado disponibles desde la década de 1950. Los ensambladores modernos, especialmente para arquitecturas basadas en RISC, como por ejemplo MIPS, SPARC y PA-RISC optimizan las instrucciones para explotar al máximo la eficiencia de segmentación del CPU.
Diferencias entre Lenguaje de Alto Nivel y Lenguaje Ensamblador. 1. El lenguaje ensamblador es muy próximo al lenguaje máquina, mientras que el lenguaje de alto nivel es muy próximo al lenguaje humano. 2. La sintaxis del lenguaje ensamblador es muy sencilla, y la de los lenguajes de alto nivel son más complicadas. 3. La estructura en el lenguaje ensamblador se presenta únicamente en tres columnas, mientras que en los lenguajes de alto nivel, se hace uso de las identaciones como herramienta para la escritura. 4. La lógica para desarrollar un programa en ensamblador debe ser mucho más cuidadosa y específica, ya que en este lenguaje el programador realiza todas las operaciones, mientras que en el lenguaje de alto nivel existen instrucciones que ejecutan operaciones que son transparentes para el usuario, es decir, no se visualiza paso a paso, sólo se obtiene el resultado final. 1.1.1 Uso y aplicaciones del Lenguaje Ensamblador Fue usado ampliamente en el pasado para el desarrollo de software, pero actualmente sólo se utiliza en contadas ocasiones, especialmente cuando se requiere la manipulación directa del hardware o se pretenden rendimientos inusuales de los equipos. Su uso más frecuente se especifica en las siguientes categorías: Programación de aplicaciones. No necesita de un conocimiento específico del hardware o de cualquier otro aspecto asociado con el lenguaje ensamblador. Manejador de Hardware. Está íntimamente ligada con la arquitectura del procesador, la dirección de los puertos de los periféricos e interrupciones. Programación de sistemas. Se utiliza para desarrollar programas que sean marco de referencia para mantener la computadora activa y en espera de que el usuario proporcione instrucciones para el manejo de archivos, de memoria o para la ejecución de comandos e instrucciones, un sistema operativo, por ejemplo. Los ensambladores de alto nivel proveen posibilidades de abstracción que incluyen: Control avanzado de estructuras Procedimientos de alto nivel, declaración de funciones. Tipos de datos que incluyen estructuras, registros, uniones, clases y conjuntos. Sofisticado procesamiento de macros.
1.1.2 Escalabilidad de los microprocesadores El procesador mayormente usado en el mundo es toda la zaga de Intel, desde el 8086 hasta el más reciente lanzamiento de este fabricante. 3
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
Obviamente, el lenguaje de máquina de un microprocesador no puede ser ejecutado por otro microprocesador de arquitectura distinta, a menos que haya cierto tipo de compatibilidad prevista. Por ejemplo, un 80486 es capaz de ejecutar lenguaje de máquina propio y soporta el código generado para microprocesadores anteriores de la misma serie (desde un 8086 hasta un 80386). Por otra parte, un PowerPC es capaz de ejecutar instrucciones de los microprocesadores Motorola 68xxx y de los Intel 80xx/80x86. En ambos casos, el diseño de los microprocesadores se hizo tratando de mantener cierto nivel de compatibilidad con los desarrollados anteriormente. En el segundo caso, este nivel de compatibilidad se extendió a los de otra marca. Sin embargo, un 8088 no puede ejecutar código de un 80186 o superiores, ya que los procesadores más avanzados poseen juegos de instrucciones y registros nuevos no contenidos por un 8088. Un caso similar es la serie 68xxx, pero de ninguna manera podemos esperar que un Intel ejecute código de un Motorola y viceversa. Y esto no tiene nada que ver con la compañía, ya que Intel desarrolla otros tipos de microprocesadores como el 80860 y el iWARP, los cuales no pueden compartir código ni entre ellos ni entre los 80xx/80x86. Una característica importante en la evolución de los procesadores es la longitud (o tamaño) de los datos que manejan, por ello es importante detallar en qué consiste esta característica. Longitud de los Datos. Los tipos principales de datos permitidos por los micro-programa de Intel tiene una longitud de palabras de 1, 4, 8, 16 y 32 bits y se denominan, respectivamente, Bit, Nibble, Byte, Palabra, Doble Palabra. Composición de Palabra, Byte, Nibble y Bit La información en el procesador, se almacena en bits, esto es 0 ó 1. Como ya es sabido, el procesador solo reconoce dos estados: encendido (1) o apagado (0). 1. El byte, con 8 bits, determina el valor en decimal según la posición en que se encuentre un 0 ó un 1. Base Elevada Valor Posicional Combinación Binaria
27 128 1 1*128 12810
26 64 0
25 24 32 16 1 0 1*32 3210 (128+32+8+4+1) = 17310
23 8 1 1*8 810
22 4 1 1*4 410
21 2 0
20 1 1 1*1 110
2. Este byte es dividido es 2 partes, cada uno de 4 bits. Cada una de estas partes recibe el nombre de NIBBLE. El sistema de numeración hexadecimal es usado en esta conversión, siendo sus dígitos del 0 al 9 que representan respectivamente los números del 0 al 9, los números del 10 al 15 se representan como sigue: A=10, B=11, C=12, D=13, E=14 y F=15. Nibble Alto 23 8 1 1*8
22 4 0
Nibble Bajo 21 2 1 1*2
20 1 0
23 8 1 1*8
22 4 1 1*4
21 2 0
20 1 1 1*1 4
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel 8
2 (8+2) = 1010 = A16 161 16 10*16 16010
8
4 (8+4+1) = 1310 = D16 160 1 13*1 1310
1
(160+13)= 17310
3. El procesador 80386 utiliza la PALABRA que está compuesto de 2 bytes. El byte de valores mayores (las 8 posiciones de la izquierda) recibe el nombre de byte más significativo, el de valores menores (8 posiciones a la derecha) recibe el nombre de byte menos significativo.
PALABRA Byte más significativo
Byte menos significativo Nibble Nibble 23 20 23 20 23 22 21 20 23 22 21 8 1 8 1 8 4 2 1 8 4 2 1 0 1 0 1 0 1 0 0 0 1 8 8 8 2 1 Valores en Hexadecimal, que es la forma en que se representan las direcciones en ensamblador. 8 8 A (10) 1 163 162 161 160 8*16*16*16=32768 8*16*16=2048 10*16=160 1*1=1 Valor Decimal 34977 Nibble 22 21 4 2 0 0
Nibble 22 21 4 2 0 0
20 1 0
Los números decimales se pueden almacenar de varias formas, como por ejemplo: Desempaquetado, donde cada byte contiene un dígito. Ejemplo: 1434 01 04 03 0000 0001 0000 0100 0000 0011
Empaquetado, donde cada byte contiene dos dígitos. Ejemplo: 1434 14 0001 0100
04 0000 0100
34 0011 0100
Agrupaciones superiores al byte: Nombre Palabra Doble Palabra Cuádruple Palabra
Tamaño 2 bytes. 2 palabras, 4 bytes 4 palabras, 8 bytes 5
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel Párrafo Página Segmento
8 palabras, 16 bytes. 128 palabras (normalmente) 256 bytes 64k bytes ( normalmente) 32,768 palabras 65,536 bytes
Familias de Procesadores 8086. Procesador
Modos disponibles
Memoria Direccionable
Tamaño del Registro
8086 / 8088
Real
1 MegaB
16 bits
80186 / 80188
Real
1 MegaB
16 bits
80286
Real y Protegido
16 MegaB
16 bits
80386
Real y Protegido
4 GigaB
16 o 32 bits
80486
Real y Protegido
4 GigaB
16 o 32 bits
En modo Real solo se puede ejecutar a la vez un proceso. El sistema operativo DOS solo funciona en modo real. En el modo Protegido, más de un proceso pueden ser activados a la vez. 1.1.3 Tipos de Lenguajes Ensambladores Podemos distinguir entre tres tipos de ensambladores: Ensambladores básicos. Son de muy bajo nivel, y su tarea consiste básicamente en ofrecer nombres simbólicos a las distintas instrucciones, parámetros y cosas tales como los modos de direccionamiento. Además, reconoce una serie de directivas (o meta instrucciones) que indican ciertos parámetros de funcionamiento del ensamblador. Ensambladores modulares, o macro ensambladores. Descendientes de los ensambladores básicos, fueron muy populares en las décadas de los 50 y los 60, antes de la generalización de los lenguajes de alto nivel. Hacen todo lo que puede hacer un ensamblador, y además proporcionan una serie de directivas para definir e invocar macroinstrucciones (o simplemente, macros). Ensambladores modulares 32-bitso de alto nivel. Son ensambladores que aparecieron como respuesta a una nueva arquitectura de procesadores de 32 bits, muchos de ellos teniendo compatibilidad hacia atrás pudiendo trabajar con programas con estructuras de 16 bits. Además de realizar la misma tarea que los anteriores, permitiendo también el uso de macros, permiten utilizar estructuras de programación más complejas propias de los lenguajes de alto nivel. 1.1.4 Clasificación de la Memorias Para las PCs la memoria se clasifica en tres tipos:
6
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
Convencional. Es la memoria de tipo básico y que abarca las direcciones de 0 a 640KB. En ésta es donde se cargan los programas de usuario y el sistema operativo, y es la que está disponible para equipo XT (8088,8086, 80186 y 80188). Extendida. Esta memoria sólo está disponible para procesadores 80286 y mayores (equipo AT, 80386 y 80486). Muchos programas que usan la memoria convencional no pueden usar la memoria extendida porque las direcciones en memoria extendida están más allá de las que el programa puede reconocer. Únicamente las direcciones dentro de los 640KB pueden ser reconocidas por todos los programas. Para reconocer la memoria extendida se requiere de un manejador de memoria extendida, como HIMEM.SYS que provee MS-DOS. Expandida. Esta es la memoria que se agrega al computador a través de una tarjeta de expansión, y que debe ser administrada por un programa especial, como el EMM386.EXE. A diferencia de la memoria convencional o extendida, la memoria expandida es dividida en bloques de 16K llamados páginas (pages). Cuando un programa solicita información de memoria expandida el manejador copia la página correspondiente en un área denominada page frame para poder ser accedida en la memoria extendida. Como podremos ver, el 8088, 8086, 80188 y 80186 son capaces de direccionar hasta 1 MB de memoria. Ya hemos indicado que la memoria convencional sólo abarca 640KB, así nos quedan 384KB libres. Esta parte de la memoria es denominada parte alta, y como no está disponible para muchos programas generalmente se usa para cargar drivers del sistema operativo, programas residentes y datos de hardware (ROM y páginas de video). La memoria principal puede ser considerada como un arreglo lineal de localidades de almacenamiento de un byte de tamaño. Cada localidad de almacenamiento tiene asignada una dirección que la identifica. La memoria principal es el lugar donde el CPU lee las instrucciones a ejecutar, así como algunos datos a emplear. Un método de asignación de memoria es la manera mediante la cual el Sistema Operativo lleva el control de la memoria tratando de que sea lo más eficiente posible. El método de asignación usada por ensamblador es la segmentación. Arquitectura de Segmentos. Los registros son elementos con un número determinado de bits que usa el procesador para hacer unas operaciones específicas. Un segmento es una porción de memoria seleccionada por el procesador para almacenar cierto tipo de información. Con la llegada de procesadores en modo protegido, la arquitectura de segmento consiguió que los segmentos puedan separarse en bloques diferentes para protegerlos de interacciones indeseables. La arquitectura de segmentos realizó otro cambio significativo con el lanzamiento de procesadores de 32 bits, empezando con el 80386, que minimizan las limitaciones de memoria de la arquitectura de segmentos de los 16 bits, siendo, además, compatibles con éstos de 16 bits. Ambos ofrecen paginación para mantener la protección de los segmentos. En DOS los segmentos se asignan normalmente adyacentes uno al otro. En modo Protegido los segmentos estarían en cualquier parte de memoria. El programador no sabe donde están ubicados y no tiene ningún control sobre ellos. Los segmentos pueden incluso moverse a una nueva posición de memoria o cambiarse al disco mientras que el programa se está ejecutando.
7
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
Asignación Programa Modo Real Memoria Segmento 0
1º dirección disponible
Segmento 1
Siguiente dirección a partir de segmento0
Asignación Programa Modo Protegido Memoria ... ... Segmento 0 dirección disponible en alguna parte de memoria
... ... Segmento 1
Siguiente dirección después del segmento0, en alguna parte de memoria
Direccionamiento de los segmentos.
8
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
Las direcciones en ensamblador están divididas en 2 componentes: segmentos y desplazamientos (offset). Segmento: Es un área de memoria que puede tener una longitud de 64 Kbytes, esto es 32,768 palabras, o sea 65,536 bytes. Debe iniciar en un área de memoria cuya dirección sea límite de 16 bytes. Puede traslaparse con otros segmentos intercalando localidades de memoria. La dirección de inicio del segmento define su localización. Cuando se trabaja la memoria en Ensamblador se divide en 4 regiones de 64k. Estas serían: 1. 2. 3. 4.
El de código, que contiene los códigos de instrucción del programa que se está ejecutando. El de datos, que guarda las variables del programa. El de stack, con información referente a la pila o stack. El extra, o área de datos complementario, usada generalmente para operaciones con cadenas.
Desplazamiento: Dado que los segmentos pueden tener hasta 64 Kbytes de tamaño, es necesario especificar la ubicación de las localidades dentro de un segmento. Este parámetro es el desplazamiento de la localidad de memoria. El desplazamiento necesita de una palabra de 16 bits para definir todas las posiciones posibles dentro de un segmento de 64 Kbytes (64*1024=65,536) de longitud máxima. La representación de una localidad de memoria que incluye la dirección de inicio del segmento y el desplazamiento es la siguiente:
88A1:0015 Dirección del Desplazamiento Dirección de inicio del Segmento Este mecanismo interior combina el valor del segmento y un valor de desplazamiento para crear una dirección. Las 2 partes representan una dirección 'segmento:desplazamiento'. Memoria
…
<--- 1 byte --->
…
Segmento 0
0000:0000 0000:0001 ..... 0000:FFFF
9
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel Memoria
.....
<--- 1 byte ---> Segmento 1
0001:0000 0001:0001 ...... 0001:FFFF
La porción del segmento es siempre de 16 bits. La porción del desplazamiento es de 16 y 32 bits. En modo real el valor del segmento es una dirección física que tiene una relación aritmética con el desplazamiento. El segmento y el desplazamiento crean junto una dirección física de 20 bits, con la que se puede acceder a un MegaB de memoria (220), aunque, por ejemplo, el sistema operativo de IBM usa sobre 640k de memoria por programa. Para efectos de explicación se considera un desplazamiento de 16 bits. El segmento seleccionará una región de 64k y se usará el desplazamiento para seleccionar 1 byte dentro de esa región. La forma de hacerlo sería: 1. El procesador desplaza la dirección del segmento 4 posiciones binarias a la izquierda y la rellena con 0. Este funcionamiento tiene el efecto de multiplicar la dirección del segmento por 16. 2. El procesador añade esta dirección de segmento de 20 bits resultante a la dirección de desplazamiento de 16 bits. La dirección de desplazamiento no se cambia. 3. El procesador usa la dirección de 20 bits resultante, a menudo llamada dirección física, al acceder a una posición en el MegaB de espacio direccionado. Ejemplo: Hexadecimal --> Binario ------> +
5 0101
3 0011
C 1100
2 0010
0101 0101 5
0011 0001 0100 4
1100 0000 1100 C
0010 0111 1001 9
1 0001
3 0011
F 1111
7 0111
0001
0011 0011 0111 7
1111 1000 1000 8
0111 1010 0001 1
:
1 0001
0 0000
7 0111
A 1010
A 1010
C 1100
0000 1010 1010 A Dirección Física
Ejemplo: Hexadecimal --> Binario ------> +
0001 1
:
3 0011
8 1000
0000 1100 1100 C Dirección Física
10
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
Las direcciónes base actuales de cada segmento se guardan en registros punteros especiales de 16 o 32 bits, denominados Registro de Segmento.
DIRECCIONAMIENTO MS-DOS MS-DOS(Segmentación) 8086 (16 Bits)
Capacidad de direccionamiento: 220=1'048,576=1MB.
80286 (16 Bits) Puede funcionar de alguno de los 2 modos: Modo real = 8086 Modo protegido: Para cada programa se implementa una tabla de descriptores. El valor que contenga un registro de segmento se utiliza como un apuntador (selector) a la tabla de descriptores. 11
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
Capacidad de direccionamiento: 224=16'777,216=16MB
SEGMENTACION MS-DOS Si un programa trata de asignar un bloque de memoria de cierto tamaño, MS-DOS busca un bloque apropiado, si lo encuentra, se modifica para que pertenezca al proceso solicitado. Si el bloque es demasiado grande, MS-DOS divide en un bloque asignado y un nuevo bloque libre. Cuando un programa libera un bloque de memoria, MS-DOS lo modifica para indicar que está disponible. Cuando un programa reduce la cantidad de memoria que necesita, MS-DOS crea un nuevo bloque de control de memoria para la memoria liberada. Tamaño Maximo de Segmento. En realidad no solo se ampliaron solo los registros de 32 bits, sino que también la longitud máxima del segmento que puede ocupar hasta 4 GB (232). Existe un tipo de segmento que específicamente sirve para la gestión de programas en modo protegido el SEGMENTO DEL SISTEMA.
1.1.5 Unidades de Entrada/Salida
1.2 EL MICROPROCESADOR 1.2.1 Buses Bus es el conjunto o grupo de cables que transportan los datos, las direcciones (ubicaciones) en las que puede encontrarse información específica, y las señales de control para asegurar que las diferentes partes del sistema utilizan su ruta compartida sin conflictos. Los buses se caracterizan por el número de bits que pueden transmitir en un determinado momento. Un equipo con un bus de 8 bits de datos, por ejemplo, transmite 8 bits de datos cada vez, mientras que uno con un bus de 16 bits de datos transmite 16 bits de datos simultáneamente. Para diferenciar las cuatro funciones diferentes, el bus está dividido en cuatro partes: líneas de potencia, bus de control, bus de direcciones y bus de datos. 12
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
La información codificada viaja a través de la computadora por un bus. El bus soporta tres tipos principales de información: El grupo de cables que transporta datos, tales como la letra A codificada El grupo de cables que lleva la dirección del componente al que van dirigidos los datos. Cada componente acepta sólo la información que va dirigida a él; por ejemplo, la información enviada a la impresora no será aceptada de forma inadvertida por la unidad de disco. El grupo de cables que lleva la tercera clase de información que son señales de tiempo, que sincronizan todo lo que hay conectado al bus para enviar y recibir mensajes en el instante correcto. 1.2.2 Registros Todos los procesadores 8086 tiene la misma base de registros de 16 bits. Se puede acceder a algunos registros como 2 registros separados de 8 bits. En el 80386/486 se puede acceder a registros de 32 bits.
Registros de Datos
Función
L Low (Baja) H High (Alta) AH
AL
AX Acumulador
Funciona como AC en algunas ocasiones. Realiza operaciones como entrada/salida de datos, multiplicación, división, operaciones con decimales codificados en binario.
BH
BL
BX Base
Funciona como registro Base, en algunas ocasiones, para referenciar direcciones de memoria En estos casos mantiene la dirección de base, inicio de tabla o matrices, en la que la dirección se determina usando valores de desplazamiento.
CH
CL
CX Contador
Funciona como registro Contador, en algunas ocasiones, es decir, cuenta el número de bits o palabras en una determinada cadena de datos durante los operaciones con cadenas. Ejemplo: Si se va a mover de un área de memoria a otra n palabras, CX mantiene inicialmente el número total de palabras a desplazar llevando la cuenta de la palabra o byte que va siendo trasladada. En las instrucciones de desplazamiento y rotación CL se usa como contador.
DH
DL
DX Extra
Se usa en la multiplicación para mantener parte del producto de 32 bits o en las división, para mantener el valor del resto. Y en operaciones de Entrada/Salida de datos para especificar la dirección del puerto de E/S usado.
8 bits
8 Bits
Total 16 bits
Registros Punteros e Indices SP
Puntero de Pila
Función
Apunta a la posición de la cima de la pila del segmento de pila en memoria. Es un registro usado 13
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel para guardar un valor de desplazamiento que direcciona la posición de un operando origen durante operaciones de tratamiento de cadenas. BP
Puntero de Base
Apunta a una zona dentro del segmento de pila dedicada al almacenamiento de datos.
SI
Índice Origen
Es usado como registro índice en ciertos modos de direccionamiento indirecto. También puede guardar un valor de desplazamiento indirecto. Se usa para almacenar un desplazamiento que direcciona la posición de un operando origen durante operaciones de tratamiento de cadenas.
DI
Índice Destino
También se usa como registro índice en determinados modos de direccionamiento indirecto. Además almacena un desplazamiento de dirección, la posición de un operando destino durante operaciones con cadenas.
16 bits (4 nibbles)
Los registros Indices SI y DI y los registros Punteros SP y BP guardan los valores de desplazamiento empleados para el acceso a determinadas posiciones de memoria. Una característica importante de los 4 registros es que se pueden usar operaciones aritméticas y lógicas de modo que los valores de desplazamiento que almacenan pueden ser el resultado de cálculos previos. Función
Registros de Segmentos CS
Segmento de Código
Apunta la dirección donde inicia el segmento de código en memoria.
DS
Segmento de Datos
Apunta la dirección donde inicia el segmento de datos en memoria.
SS
Segmento de Pila
Apunta la dirección donde inicia el segmento de pila en memoria.
ES
Segmento Extra
Apunta la dirección donde inicia el segmento de datos extra en memoria.
16 bits
Las áreas de memoria asignadas al código de programa, datos y pila se direccionan por separado a pesar de poder solaparse. En un momento dado hay siempre 4 bloques disponibles de memoria direccionable denominadas segmento. Cada uno de los segmento suele tener una longitud de 64k. Para determinar una direcciones en el segmento de código tendremos que realizar el desplazamiento de 4 bits hacia la izquierda del registro CS poniendo a 0 los bits 0, 1, 2 y 3. Lo que equivale a multiplicar CS por 16. Sumando a continuación el valor de 16 bits almacenado en IP. La dirección dentro de los otro 3 registros se calcula similarmente. Las combinaciones de registro de segmento y desplazamiento depende de los tipos de operaciones que se esté ejecutando. Por omisión se asume que la dirección de un operando está en el segmento de datos y el registro de segmento a usar es por tanto DS con el desplazamiento BX, SI o DI.
Segmento de
Segmento de
Segmento de
Segmento de 14
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel Datos
Código
Stack
Extra de Datos
DS : BX DS : SI DS : DI
CS : IP
SS : SP SS : BP
ES : DI ES : SI
Si el desplazamiento está almacenado en un registro puntero como SP o BP se asume que el operando está en el segmento de pila y, por tanto, el registro de segmento de pila SS se usa como base. Si la dirección del operando es el destino de una instrucción de cadena, el registro del segmento Extra ES constituye la base y el desplazamiento se almacena en DI o SI. Función
Puntero de Instrucción IP
Puntero de instrucción
Se usa para localizar la posición inicial de la próxima instrucción a ejecutar dentro del segmento de código en curso. Como el registro CS contiene la dirección base del segmento de código, cualquier dirección de 20 bits dentro del segmento se localizará empleando cualquier IP como desplazamiento desde CS.
16 bits
Registro de Indicadores o de Banderas 15
.
.
. 11 10 OF DF
9
8
7
6
IF TF SF ZF
.
4 AF
.
2 PF
.
0 CF FLAGS: Registro de Indicadores
Los bits 0, 2, 4, 6, 7 y 11 son indicadores de condición que reflejan los resultados de operaciones del programa. Los bits del 8 al 10 son indicadores de control. Los indicadores de condición pueden comprobarse tras ejecutar determinadas operaciones usando el resultado de la comprobación en la toma de decisiones de bifurcación condicional. Indicadores de Condición: Bit 0. Indicador de acarreo (CF) Se pone a 1 si en una operación de suma o resta se produce un acarreo por exceso o por defecto. Si una operación no produce acarreo estará a 0. Bit 2. Indicador de paridad (PF) Se pone a 1 si el resultado de una operación tiene un número par de bits a 1. Y se pone a 0 cuando el resultado tiene un número impar de bits a 1. Bit 4 acarreo por exceso o defecto de los 4 bits menos significativos en los valores de BCD (decimal codificado en binario). Bit 6 e a 1 si el resultado de una operación es 0, esto ocurre, por ejemplo, después de usar una instrucción de resta o decremento o al hacer una comparación entre 2 número de igual valor. Para resultados distintos de 0 el indicador estará a 0. Bit 7. Indicador aritméticas de complemento a 2. Se usa el bit más significativo de cualquier número en complemento 2 15
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
para indicar si dicho número es positivo cuando está a 0 o negativo cuando está a 1. Y se copia en el bit 7 del registro de indicadores. Bit 11 operando provoca un desbordamiento (overflow) y activará este indicador a 1. Registro indicador de Control: Bit 8 activado, haciendo que el micro-procesador ejecute la instrucción paso a paso. El procesador genera instrucción una detrás de otra. Un debugging puede usar este rango para procesar un programa instrucción a instrucción. Bit 9 activarla. IF se controla con la instrucción CLI (desactiva interrupción externa) y STI (activa interrupción externa). Bit 10 en relación con SI y DI. Se pone a 0 para la cadena que se procesa hacia arriba, o sea, hacia direcciones de memoria más altas y se pone a 1 para las cadenas que se procesan hacia abajo, o sea, hacia direcciones más bajas. Solo para 80386 / 486. Los procesadores de este tipo usan registros de 8 y 16 bits igual que el resto de la familia de los 8086. Todos los registros se extienden a 32 bits excepto los registros de segmento de 16 bits. Los registros extendidos comienzan con la letra E: el registro extendido de AX es EAX. Los procesadores 386 / 486 tienen 2 registros de segmento adicionales: FS y GS.
L Low (Baja) H High (Alta)
Registro de Datos Extendidos HL AX
AH
AL
EAX: Acumulador
BX
BH
BL
EBX: Base
CX
CH
CL
ECX: Contador
DX
DH
DL
EDX: Extra
8 bits.
8 bits.
16 bits 16 bits
Registro Puntero e Indice Extendido
Total 32 bits L Low (Baja) H High (Alta)
SP
ESP: Puntero de Pila
BP
EBP: Puntero de Base
SI
ESI: Indice de Orden
16
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
H 16 bits
DI
EDI: Indice de Destino
L 16 bits
Total 32 bits
Puntero de Instrucción Extendido
16 bits
IP
EIP: Reg
16 bits
Total 32 bits
Registro de Segmentos Extendidos CS
CS: Segmento de Código
DS
DS: Segmento de Dato
SS
SS: Segmento de Pila
ES
ES: Segmento Extra
FS
FS: Segmento Extra
GS
GS: Segmento Extra
16 bits
Puntero de Bandera Extendida (EFlags) 31
30
.
.
.
.
.
.
.
.
.
.
19
18
17
16
A
V
R
15
14
13
N
IOP
12
11
10
OF
DF
9
.
.
.
.
.
.
.
1 0 CF
<--- 386/486 ---> <- 286/386/486 --> <--- Para todo los procesadores 8086 ->
IOP indica el nivel de protección para operaciones de Entrada/Salida. El bit 14 (N) se usa en relación con procesos anidados. R para reanudación de procesos. V está relacionado con el modo 8086 virtual. A está relacionado con el control de alineación.
1.2.3 Modos de Direccionamiento Estas maneras de obtener la dirección se denominan Modos de Direccionamiento y cada uno tiene asignado un registro de segmento por defecto. Modo de Direccionamiento
Comentario
Ejemplo 17
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel 1. Implícito 2. Inmediato 3. De Registro 4. Directo 5. De Registro Indirecto
6. Relativo a la Base
7. Indexado Directo
8. Indexado de Base
En este tipo de direccionamiento se omiten especificaciones de origen o destino de los datos, ya que la instrucción misma lo indica. El registro AX será colocado en la pila o stack El valor es especificado por el usuario. El 18 en decimal (la D al final indica que el valor está en decimal), es colocado en el registro AX 12 registros básicos con los que trabaja el microprocesador). Indica que se tomará el valor contenido en BX y será colocado en AX. El valor es tomado de un identificador definido por el usuario. El valor que contenga DDDW es asignado a AX. En este caso, en el registro BX, BP, SI o DI únicamente se colocará una dirección. La instrucción OFFSET se encarga de buscar la dirección inicial (no el valor) del dato que se especifique. (En BX se coloca la dirección de inicio de almacenamiento del identificador DDDX.) Después usando el registro en el que se colocó la dirección, se obtiene el valor contenido en esa dirección y será asignado a otro registro Es importante el uso de los corchetes, pues indican que en AX se asignará el valor almacenado dentro de la dirección indicada por BX, es decir BX indica una dirección, no un valor. Son usados únicamente los registros BX o BP, ya que son los que se usan para indicar base. A la dirección del desplazamiento contenida en el registro (sea BP o BX), se suma un valor: BX+2. En AX, se asignará el valor almacenado en la dirección que resulte de sumar 2 a la dirección indicada en BX. Se utilizan los registros SI o DI (índice), a los cuales es asignado un valor. Al combinarlo con un identificador, que tiene una dirección, a ésta última se sumará el valor del registro índice. En AX, se asignará el valor que esté en la dirección que tenga DDDZ + 2. El valor que tomará el registro, es la que esté contenida en la dirección determinada por la suma de lo que contenga BX más SI ó DI y un valor, este último es opcional.
PUSH AX
BX contendrá la dirección inicial de DDDW A SI se le asigna el valor de 8, que funciona como desplazamiento Por último a AX se le asignará el contenido de la dirección que resulte de la operación de suma de BX más SI.
MOV BX, OFFSET DDDW MOV SI, 8 MOV AX, [BX+SI
MOV AX, 18D
MOV AX, BX MOV AX, DDDW
MOV BX, OFFSET DDDX MOV AX, [BX
MOV AX, [BX+2
MOV SI, 2 MOV AX, DDDZ [SI
Especificaciones de Modos de Direccionamiento Absoluto e Indirecto Obtención Desplazamiento
Segmento
Direccionamiento Absoluto
Inmediato
DS
MOV al, 0
Direccionamiento Indirecto con Base (BX)
BX+XX
DS
MOV cx, [bx+2]
Direccionamiento Indirecto con base (BP)
BP+XX
SS
MOV ax, [bp+4]
Direccionamiento Indirecto con Indice (SI)
SI+XX
DS
MOV dx, [si+2]
Denominación
Ejemplo
18
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel Direccionamiento Indirecto con Indice (DI)
DI+XX
DS
MOV [di], es
Direccionamiento Indirecto con Base (BX) e Indice (SI)
BX+SI+XX
DS
MOV [bx+si-2], cx
Direccionamiento Indirecto con Base (BX) e Indice (DI)
BX+DI+XX
DS
MOV dx, [bx+di]
Direccionamiento Indirecto con Base (BP) e Indice (SI)
BP+SI+XX
SS
MOV ds, [bp+si]
Direccionamiento Indirecto con Base (BP) e Indice (DI)
BP+DI+XX
SS
MOV ax, [bp+di]
Puede apreciarse que todos los modos admiten que después de obtener el valor de desplazamiento de un registro o de la suma de dos, se añada una constante a éste, antes de generar la lectura, indicada por XX. Si se omite el valor XX se generan instrucciones que no añaden ningún valor al desplazamiento obtenido por los registros. Cada modo usa un registro de segmento por defecto para componer la dirección completa pero siempre es posible que le CPU use, no el registro de segmento por defecto, sino uno especificado por nosotros. A nivel de lenguaje máquina lo que se hace es añadir a la instrucción un prefijo de 1 byte que modifica el comportamiento de la siguiente instrucción haciendo que use el registro de segmento correspondiente al prefijo en lugar del registro por defecto. Hay 4 prefijos distintos, uno para cada registro de segmento y se denominan Prefijos de Segmento por convenio se añade el prefijo inmediato antes de la apertura de corchetes o después de PTR, si este aparece. Así las siguientes instrucciones acceden a posición de memoria dentro del segmento de código de datos extra y segmento de pila, respectivamente. MOV al, cs:[bx+4] MOV word ptr ds:[bp-0fh], 0 MOV es:[di], al MOV word ptr ss:[bx], 0 Es interesante tener en cuenta que por ejemplo: MOV [bx], ax y MOV ds:[bx], ax son equivalentes. Ya que si no se indica nada el registro por defecto es DS. También es interesante resaltar que para acceder a una posición de un vector, que haya sido previamente definido en el segmento de datos, usamos los corchetes. Segmento de datos... tabla word 100 dup (0) inicial 0. Segmento de código... MOV ax, tabla[si] MOV bx, 0 MOV ax, tabla[5] MOV ax, tabla+5
; Vector de 100 posiciónes, cada posición sería de 1 palabra con valor
; Donde SI actúa como índice del vector. ; Esto sería equivalente ; todas las sentencias pasarían al registro AX ; el valor de la posición 5 de la tabla pasa AX.
MOV ax, tabla[bx]+5 19
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
MOV ax, tabla[bx][di] MOV ax, tabla[di][bx] MOV ax, tabla[bx+di] MOV ax, [tabla+bx+di] MOV ax, [bx][di]+tabla
; Todas estas instrucciones también son equivalentes ; todas las sentencias mueven la posición ; indicada por BX+DI dentro de la tabla a AX.
1.3 INTERRUPCIONES Como se mencionó anteriormente la PC esta constituida lógicamente por su BIOS y sistema operativo. La mayoría de las rutinas que controlan al computador están grabadas en el ROM del BIOS, aunque muchas rutinas son establecidas por el sistema operativo y se cargan en RAM al momento de encender al computador. Estas rutinas son denominadas interrupciones y son activadas mediante la instrucción: INT número. Una interrupción es una operación que invoca la ejecución de una rutina específica que suspende la ejecución del programa que la llamó, de tal manera que el sistema toma control del computador colocando en el stack el contenido de los registros CS e IP. El programa suspendido vuelve a activarse cuando termina la ejecución de la interrupción y son restablecidos los registros salvados. Existen dos razones para ejecutar una interrupción: (1) intencionalmente como petición para la entrada o salida de datos de un dispositivo, y (2) un error serio y no intencional, como sobreflujo o división por cero. El operando de una interrupción indica cuál es la rutina a activar. La dirección de la rutina es localizada por medio de una tabla que el sistema mantiene a partir de la dirección 0000:0000h. Existen 256 entradas de 4 bytes de longitud, y cada interrupción proporciona varias funciones. Las interrupciones de 00h a 1Fh corresponden al BIOS y de 20h a FFh son del DOS y BASIC. Una interrupción es una señal que provoca la suspensión del programa que se estaba ejecutando y provoca el comienzo de ejecución de un programa de tratamiento que de solución a esa interrupción. A ese programa se le conoce como RUTINA DE TRATAMIENTO de esa interrupción. 1.3.1 Hardware Interrupciones Hardware o Interrupciones Externas, que son aquellas provocadas por los dispositivos periféricos, controladas por un procesador especial de interrupciones (8259) o IPC (Controlador de Interrupciones Programable), y la rutina de tratamiento está "cableada". Interrupciones Internas, que son aquellas provocadas dentro del propio procesador por una situación anormal de funcionamiento de alguna de sus partes. 1.3.2 Software Son aquellas que son programables y que podemos cambiar. Las interrupciones de software podemos llegar a manejarlas y por ello el ensamblador nos proporciona una instrucción que nos permita poner en funcionamiento una determinada rutina de interrupción; esta instrucción es INT. Interrupción Formato INT núm_entero. 20
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
Ese "núm_entero", asociado a la instrucción, es un identificativo que indica, mediante la aplicación de un algoritmo, la posición de Memoria Interna donde se encuentra almacenada la dirección de comienzo de la rutina de tratamiento de esa interrupción. El ensamblador permite, normalmente, identificar 256 interrupciones. Una parte de ellas son las correspondientes a la ROM-BIOS y las proporciona el fabricante. Otra parte de ellas forman del sistema operativo DOS, y otra parte de ellas queda libre para que el programador genere sus propias rutinas de interrupción. Las interrupciones correspondientes a la parte de la BIOS y las correspondientes a la parte del DOS representas características similares. Existe un flag denominado IF (Interrupción Flag, bandera de Interrupción) que determina la reacción del microprocesador ante una interrupción. Si el flag está a uno, el rpocesador responde a la interrupción producida; pero si el flag IF está a cero, la petición de interrupción será ignorada completamente por el microprocesador. En algunas secciones de código, resulta necesario deshabilitar las interrupciones (poner el flag IF a cero) durante algunos ciclos, y habilitarlas de nuevo después. La familia 8086 provee dos instrucciones que realizan estas tareas: STI (Activar flag de interrupciones): Pone la bandera IF a i, de forma que se premiten las interrupciones. CLI (Borrar flag de interrupciones): Pone la bandera IF a 0, de modo que el microprocesador no responde a más interrupciones hasta que se ejecuta un STI o se altera el contenido de las banderas (entre ellas el de IF) recuperándolos de la pila con POPF o IRET. MOV ax, 8000h CLI MOV ss, ax MOV sp, 2000h STI Retorno de interrupción. Formato IRET (no tiene operandos) Retorna de una rutina de servicio a la interrupción, extrayendo de la pila los nuevos valores de IP y CS, en este orden, y el contenido del registro de flags. La ejecución continúa en la instrucción siguiente a la que se estaba ejecutando cuando ocurrió la interrupción. Ejemplos de interrupciones del DOS. La interrupción más conocida (y utilizada) es la 21h. Esta interrupción presenta una gran cantidad de funciones diversas; por ello además de indicar el "nº entero", debemos indicar también el "nº función" que se desea dentro de esa interrupción. Dicho número se almacena siempre el registro AH. No. De Interrupción No. De Función INT 21h. Función 01h
Acción
Código
Permite dar entrada a un carácter de teclado y al mismo tiempo dicho carácter aparece en pantalla, en la posición en la que se encuentre el cursor. El carácter tecleado queda almacenado en AL. Si no hay ningún carácter disponible, se espera hasta que haya alguno.
MOV ah, 01h INT 21h ; El carácter tecleado queda en AL
21
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel INT 21h. Función 02h INT 21h. Función 08h
INT 21h. Función 09h
INT 21h. Función 4Ch
Permite llevar un carácter desde el procesador hacia la pantalla. Dicho carácter debe estar almacenado en el registro DL. Aparecerá en la posición donde se encuentre el cursor. Permite dar una entrada de un carácter desde el teclado pero sin que aparezca en pantalla. El carácter tecleado queda almacenado en el registro Al. Si no hay un carácter disponible se espera hasta que lo haya. Visualización de una cadena de caracteres. Nos permite llevar una cadena de caracteres hacia la pantalla. Dicha cadena aparecerá a partir de la posición en la que se encuentre el cursor. Esta función necesita que en el registro DX se encuentre la dirección de comienzo de la cadena a presentar en pantalla. (DS:DX). Acabar el proceso con código de retorno. Permite realizar el retorno al Sistema Operativo. Acaba el proceso actual, enviando un código de retorno al programa original. Se trata de uno de los diversos métodos con los que se puede provocar una salida definitiva de un programa.
MOV dl, carácter MOV ah, 02h INT 21h MOV ah, 08h INT 21h ; El carácter tecleado queda en AL En DX queda el desplazamiento que hay que hacer dentro; de DS para llegar a la posición donde se encuentra; "cadena" MOV dx, offset cadena MOV ah, 09h INT 21h MOV ah, 4ch INT 21h
1.4 ESTRUCTURA DE UN PROGRAMA EN ENSAMBLADOR Cualquier lenguaje de programación tiene 3 características, es decir, debe cumplir con 3 requisitos: Sintaxis. Son las reglas que deben seguirse para escribir un programa. Estructura. Es la forma de escribir el programa, para que sea claro y legible y sea menos complicado encontrar errores. Lógica. Es el pensamiento del programador, que hace que el programa ejecute las instrucciones adecuadamente Un programa escrito en lenguaje ensamblador consiste en una serie de instrucciones que corresponden al flujo de órdenes ejecutables que pueden ser cargadas en la memoria de una computadora. Por ejemplo, un procesador x86 puede ejecutar la siguiente instrucción binaria como se expresa en código maquina: Binario Hexadecimal
1011 0000 0110 0001 0xb061)
La representación equivalente en ensamblador es más fácil de recordar: mov al, 061h Esta instrucción significa: Mueva el valor hexadecimal 61 (97 decimal) al registro "al". El mnemónico "mov" es un código de operación u "opcode" , elegido por los diseñadores de la colección de instrucciones para abreviar "move" (mover).- El opcode es seguido por una lista de argumentos o parámetros, completando una instrucción de ensamblador típica. El siguiente es un ejemplo del programa clásico Hola mundo escrito para la arquitectura de procesador x86 (bajo el sistema operativo DOS ). 22
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
dosseg .model small .stack 100h .data Cadena1 DB 'Hola Mundo.$' .code programa: mov ax, @data mov ds, ax mov dx, offset Cadena1 mov ah, 09h int 21h end programa 1.4.1 Data Segment Cuando el programa requiere del uso de datos, deben definirse en este segmento, en ensamblador no existen “tipos” de datos, solo tamaño de datos. Dato
Tamaño en bits 8 16 32 64
DB DW DD DT
Valor Numérico Máximo 255 65,535 4,294,967,296 18,446,744,073,709,551,616
No. De Bytes por cada caracter 1 byte 2 bytes 4 bytes 8 bytes
El segmento se define de la siguiente manera: .data Iden1 db 23d Iden2 dw 420 Cadena db “mensaje$”
; es db, por lo tanto su valor máximo podría ser 255 ; se define dw porque 420 sobrepasa el valor de 255 para un db ; cada carácter de la cadena se almacenará en 1 byte
1.4.2 Stack Segment En esta sección se define el tamaño que tendrá el segmento de stack para ese programa. Este segmento debe definirse una sola vez. Si se está trabajando con programas modularizados, esta definición deberá escribirse en el programa principal. .stack 100h
; Se define un stack de 256 bytes de tamaño (162 =256)
1.4.3 Code Segment En este segmento del programa se escriben todas las instrucciones que se realizarán. .code xor ax, ax mov ax, @data mov ds, ax 23
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
mov bx, offset cadena mov al, [bx+1] ….. ….. end 1.4.4 Instrucciones del Programa Cada arquitectura de computadoras tiene su propio lenguaje de máquina, y en consecuencia su propio lenguaje ensamblador. Las computadoras difieren en el tipo y número de operaciones que soportan; también pueden tener diferente cantidad de registros, y distinta representación de los tipos de datos en memoria. Aunque la mayoría de las computadoras son capaces de cumplir esencialmente las mismas funciones, la forma en que lo hacen difiere, y los respectivos lenguajes ensambladores reflejan tal diferencia. Pueden existir múltiples conjuntos de mnemónicos o sintaxis de ensamblador para un mismo conjunto de instrucciones, instanciados típicamente en diferentes programas ensamblador. En estos casos, la alternativa más popular es la provista por los fabricantes, y usada en los manuales del programa. Código máquina El lenguaje de máquina esta formado por instrucciones discretas, que -dependiendo de la arquitectura del procesador- pueden especificar: Registros específicos para operaciones aritméticas, direccionamiento o control de funciones. Posiciones de memoria específicas (offset). Modos de direccionamiento usados para interpretar a los operandos. Las operaciones más complejas se realizan combinando estas simples instrucciones, que pueden ser ejecutadas secuencialmente o mediante instrucciones de control de flujo. Las operaciones disponibles en la mayoría de los conjuntos de instrucciones incluye: Mover Llenar un registro con un valor constante Mover datos de una posición de memoria a un registro o viceversa Escribir y leer datos de dispositivos Computar Sumar, restar, multiplicar o dividir los valores de dos registros, colocando el resultado en uno de ellos o en otro registro Realizar operaciones binarias, incluyendo operaciones lógicas (AND/OR/XOR/NOT) Comparar valores entre registros (mayor, menor, igual) Afectar el flujo del programa Saltar a otra posición en el programa y ejecutar instrucciones allí Saltar si se cumplen ciertas condiciones (IF) Saltar a otra posición, pero guardar el punto de salida para retornar (CALL, llamada a subrutinas) Algunas computadoras incluyen instrucciones complejas dentro de sus capacidades. Una sola instrucción compleja hace lo mismo que en otras computadoras puede requerir una larga serie de instrucciones, por ejemplo: Salvar varios registros en la pila de una sola vez Mover grandes bloques de memoria Operaciones aritméticas complejas o de punto flotante (seno, coseno, raíz cuadrada ) 24
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
1.4.5 Directivas El MASM (Macro Assembler, ensamblador) posee un conjunto de instrucciones que no pertenecen al lenguaje ensamblador propiamente sino que son instrucciones que únicamente son reconocidas por el ensamblador y que han sido agregadas para facilitar la tarea de ensamblado, tanto para el programador como para el programa que lo lleva a cabo. Dichas instrucciones son denominadas directivas. En general, las directivas son usadas para especificar la organización de memoria, realizar ensamblado condicional, definir macros, entrada, salida, control de archivos, listados, cross-reference, direcciones e información acerca de la estructura de un programa y las declaraciones de datos. Conjunto de instrucciones Dentro de las directivas más importantes, tenemos las que establecen el conjunto de instrucciones a soportar para un microprocesador en especial: .8086(defecto).- Activa las instrucciones para el 8086 y 8088 e inhibe las del 80186 y 80286. .8087(defecto).- Activa instrucciones para el 8087 y desactiva las del 80287. .186.- Activa las instrucciones del 80186. .286c.- Activa instrucciones del 80286 en modo no protegido. .286p.- Activa instrucciones del 80286 en modo protegido y no protegido. .287.- Activa las instrucciones para el 80287. Declaración de segmentos En lo que respecta a la estructura del programa tenemos las directivas SEGMENT y ENDS que marcan el inicio y final de un segmento del programa. Un segmento de programa es una colección de instrucciones y/o datos cuyas direcciones son todas relativas para el mismo registro de segmento. Su sintaxis es: nombre SEGMENT [alineación] [combinación] [´clase´ nombre ENDS El nombre del segmento es dado por nombre, y debe ser único. Segmentos con el mismo nombre se tratan como un mismo segmento. Las opciones alineación, combinación, y clase proporcionan información al LINK sobre cómo ajustar los segmentos. Para alineación tenemos los siguientes valores: byte (usa cualquier byte de dirección), word (usa cualquier palabra de dirección, 2 bytes/word), para (usa direcciones de párrafos, 16 bytes/párrafo, deafult), y page (usa direcciones de página, 256 bytes/page). Combinación define cómo se combinarán los segmentos con el mismo nombre. Puede asumir valores de: public (concatena todos los segmentos en uno solo), stack (igual al anterior, pero con direcciones relativas al registro SS, common (crea segmentos sobrepuestos colocando el inicio de todos en una misma dirección), memory (indica al LINK tratar los segmentos igual que MASM con public, at address (direccionamiento relativo a address). clase indica el tipo de segmento, señalados con cualquier nombre. Cabe señalar que en la definición está permitido el anidar segmentos, pero no se permite de ninguna manera el sobreponerlos. 25
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
Fin de código fuente Otra directiva importante es la que indica el final de un módulo. Al alcanzarla el ensamblador ignorará cualquier otra declaración que siga a ésta. Su sintaxis es: END [expresión] la opción expresión permite definir la dirección en la cual el programa iniciará. Asignación de segmentos La directiva ASSUME permite indicar cuales serán los valores por defecto que asumirán los registros de segmento. Existen dos formas de hacer esto: ASSUME registrosegmento:nombre,,, ASSUME NOTHING NOTHING cancela valores previos. Etiquetas Las etiquetas son declaradas nombre: donde nombre constituye una cadena de caracteres. Declaración de datos Estos se declaran según el tipo, mediante la regla [nombre] directiva valor,,, donde directiva puede ser DB (bytes), DW (palabras), DD (palabra doble), DQ (palabra cuádruple), DT (diez bytes). También pueden usarse las directivas LABEL (crea etiquetas de instrucciones o datos), EQU (crea símbolos de igualdad) , y el símbolo = ( asigna absolutos) para declarar símbolos. Estos tienen la siguiente sintaxis: nombre = expresión nombre EQU expresión nombre LABEL tipo donde tipo puede ser BYTE, WORD, DWORD, QWORD, TBYTE, NEAR, FAR. 26
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
Declaración de estructuras Para la declaración de estructuras de datos se emplea la directiva STRUC. Su sintaxis es: nombre STRUC campos nombre ENDS
1.5 PROCEDIMIENTO DE ENSAMBLE, ENLACE Y EJECUCIÓN La transformación del lenguaje ensamblador en código máquina la realiza un programa ensamblador, y la traducción inversa la puede efectuar un des-ensamblador. A diferencia de los lenguajes de alto nivel, aquí hay usualmente una correspondencia 1 a 1 entre las sencillas instrucciones en ensamblador y el lenguaje máquina. Sin embargo, en algunos casos, un ensamblador puede proveer "pseudo instrucciones" que se expanden en un código de máquina más largo a fin de proveer la necesaria funcionalidad. Por ejemplo, para un código máquina condicional como "si X mayor o igual que", un ensamblador puede utilizar una pseudo instrucción al grupo "haga si menor que" , y "si = 0" sobre el resultado de la condición anterior. Los ensambladores más completos también proveen un rico lenguaje de macros que se utiliza para generar código más complejo y secuencias de datos. El nivel de lenguaje ensamblador tiene aspectos importantes de los niveles de micro-arquitectura, en los cuales se encuentra (ISA y sistema operativo) estos dos se utilizan para la traducción en lugar de la interpretación. Algunas características del lenguaje se describen a continuación Como se especificó al inicio, se usa la traducción cuando se cuenta con un procesador (ya sea hardware o un interprete) para el lenguaje objeto pero no para el lenguaje fuente. Si la traducción se realiza correctamente, la ejecución del programa traducido dará exactamente los mismos resultados que habría dado la ejecución del programa fuente. Hay dos diferencias entre traducción e interpretación, en la traducción no se ejecuta directamente el programa original, en el lenguaje fuente se convierte en un programa equivalente llamado programa objeto o programa binario ejecutable y este funciona solo cuando se ha acabado la traducción. El código máquina, un simple patrón de bits, es hecho legible reemplazando valores crudos por símbolos denominados mnemónicos. Se inventó para facilitar la tarea de los primeros programadores que hasta ese momento tenían que escribir directamente en código binario. Antes aún era peor, ya que el código de ceros y unos (el programa) debía introducirse en una tarjeta perforada. La posición ocupada por cada punto equivalía a un "1" o a un "0" según hubiera un hueco o no. Lo cual suponía una forma casi idéntica en la que hoy se escriben los datos binaros en soportes tales como los CDs y DVDs. Mientras que una computadora reconoce la instrucción de máquina IA-32 10110000 01100001 para los programadores de microprocesadores x86 es mucho más fácil reconocer dicha instrucción empleando lenguaje ensamblador: 27
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
mov al, 0x61 (que significa mover el valor hexadecimal 61 (97 decimal) al registro 'al'.) Cada instrucción de la máquina se transforma en una única instrucción en código simbólico. Pero además, para mejorar la legibilidad del programa, el código simbólico introduce instrucciones adicionales, que no corresponden a ninguna instrucción de la máquina y que proporcionan información. Se llaman "pseudo-instrucciones". El código simbólico puede parecer de difícil acceso, pero es más fácil de recordar e interpretar que el binario o el hexadecimal. Los lenguajes simbólicos no resuelven definitivamente el problema de cómo programar un ordenador de la manera más sencilla posible. Para utilizarlos, hay que conocer a fondo el microprocesador, los registros de trabajo de que dispone, la estructura de la memoria, y muchas cosas más. Además, el lenguaje ensamblador está demasiado ligado al microprocesador para que sea posible escribir programas independientes de la máquina en que van a ejecutarse. Este código simbólico no puede ser ejecutado directamente por un ordenador, por lo que es preciso traducirlo previamente. Pero la traducción es un proceso mecánico y repetitivo, que se presta a su realización por un programa de ordenador. Los programas que traducen código simbólico al lenguaje de máquina se llaman ensambladores ("assembler", en inglés), porque son capaces de ensamblar el programa traducido a partir de varias piezas, procedimientos o subrutinas a código binario ("1" y "0") que entiende el procesador.
INTERPRETE
Programa Fuente .PAS .BAS .CBL .PRG .ASM
EJECUCIÓN
.OBJ COMPILACION O ENSAMBLE Programa Objeto
.EXE
Programa Ejecutable
Para la elaboración de programas ejecutables, se sigue el proceso esquematizado en la figura anterior. 1. Se inicia con la captura de un programa denominado Programa Fuente, escrito en código ASCII en cualquier editor de textos que almacene sus archivos es este formato (código ASCII), ya que algunos editores, como el WORD, guardan sus archivos en un formato diferente. 2. Una vez capturado el programa fuente, se procede a la verificación de la sintaxis del mismo, esto es que no tenga errores en la escritura y las instrucciones. Según la forma que se ejecute se denomina: 28
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
intérprete, cuando se verifica línea a línea, y compilado o ensamblado cuando se verifica la totalidad del programa. En el caso del intérprete la ejecución es inmediatamente después de la verificación de la línea, esto tiene como consecuencia que el programa se ejecutará hasta que encuentre un error y no genera programa objeto. En el caso del compilado o ensamblado no es así, una vez que el programa ya no tiene errores sintácticos, se genera el Programa Objeto, que está escrito en código máquina. 3. El proceso de ligado es el que se lleva a cabo después del compilado o ensamblado, es este paso, se determinan las direcciones de las localidades de memoria que utilizará el programa cuando se ejecute. Se genera el Programa Ejecutable, que al ser llamado directamente de sistema operativo se ejecutará. PASO 1: EDICION. Los archivos fuente de código ensamblador deben estar en formato ASCII standard. Para esto puede usarse cualquier editor que permita crear archivos sin formato, por ejemplo: Edlin, Edit, Write, el editor del Turbo Pascal, Works, Word. Las declaraciones pueden ser introducidas en mayúsculas y/o minúsculas. Una buena práctica de programación es poner todas las palabras reservadas (directivas e instrucciones) en mayúsculas y todo lo del usuario en minúsculas para fines de facilidad de lectura del código. Las sentencias pueden comenzar en cualquier columna, no pueden tener más de 128 caracteres, no se permiten líneas múltiples ni códigos de control, y cada línea debe ser terminada con una combinación de line-feed (avance de linea) y carriage-return (retorno de carro). Los comentarios se declaran con “;” y terminan al final de la línea. PASO 2: ENSAMBLADO. El ensamblado se lleva a cabo invocando al MASM. Este puede ser invocado, usando una línea de comando, de la siguiente manera: MASM archivo [,[objeto][,[listado][,[cross]]]]][opciones][;] donde: archivo objeto listado. cross. opciones.
Corresponde al programa fuente. Por defecto se toma la extensión .ASM. Es el nombre para el archivo objeto. Nombre del archivo de listado de ensamblado. Es un archivo de referencias cruzadas. Pueden ser: /A escribe los segmentos en orden alfabético /S escribe los segmentos en orden del fuente /Bnum fija buffer de tamaño num /C especifica un archivo de referencias cruzadas /L especifica un listado de ensamble /D crea listado del paso 1 /Dsym define un símbolo que puede usarse en el ensamble /Ipath fija path para buscar archivos a incluir /ML mantiene sensitividad de letras (mayús./minús) en nombres /MX mantiene sensitividad en nombre públicos y externos 29
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
convierte nombres a mayúsculas suprime tablas en listados checa por código impuro crea código para instrucciones de punto flotante crea código para emular instrucciones de punto flotante suprime mensajes de ensamble exitoso despliega estadísticas adicionales en pantalla incluir condicionales falsos en pantalla despliega líneas de error en pantalla
/MU /N /P /R /E /T /V /X /Z
Si el “;” al final se omite es necesario poner todas las comas que se indican. Si no se quiere poner algún valor basta con dejar la coma. La otra forma de invocar al ensamblador es sólo tecleando MASM y respondiendo a la información que se solicita. Para omitir algún valor sólo basta teclear ENTER si dar ningún valor. TERCER PASO: LIGADO De la misma forma que el ensamblado, la fase de liga se lleva a cabo con el LINK. Este puede ser invocado de la misma forma que el MASM. Los parámetros que este requiere son: LINK objeto [,[ejecutable][,[mapa][,[librería]]]]][opciones][;] donde: objeto Es el nombre para el archivo .OBJ ejecutable Nombre del archivo .EXE mapa Nombre del archivo mapa librería Nombre del archivo biblioteca de rutinas opciones Pueden ser: /HELP muestra lista de opciones /PAUSE pausa en el proceso /EXEPACK empaca archivo ejecutable /MAP crea mapa se símbolos públicos /LINENUMBERS copia número de líneas al mapa /NOIGNORECASE mantiene sensitividad en nombres /NODEFAULTLIBRARYSEARCH no usa bibliotecas por defecto /STACK:size fija el tamaño del stack a usar /CPARMAXALLOC:número fija alojación máxima de espacio /HIGH fija la dirección de carga más alta /DSALLOCATE aloja grupo de datos /NOGROUPASSOCIATION ignora asociaciones para direcciones /OVERLAYINTERRUPT:número asigna nuevo número a la INT 03Fh /SEGMENTS:número procesa un número de segmentos /DOSSEG sigue la convención de orden de DOS PASO 4: EJECUCION. Para la ejecución del programa simplemente basta teclear su nombre en el prompt de MS-DOS y teclear ENTER. Con esto el programa será cargado en memoria y el sistema procederá a ejecutarlo. El 30
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
proceso completo para poder crear un programa ejecutable con el Microsoft Macro Assembler se muestra abajo.
PASO 5: DEPURACION. Para la depuración de un programa en ensamblador tenemos disponibles dos herramientas. Por un lado tenemos el debugger que nos proporciona MS-DOS (DEBUG.EXE) y por otro lado tenemos el que nos proporciona Microsoft (SYMDEB.EXE). Este último trabaja igual que el de MS-DOS pero nos proporciona muchas ventajas más. Una de ellas es la facilidad de desplegar el código fuente correspondiente a la instrucción que se esta ejecutando (si el programa ejecutable fue ensamblado o compilado con un ensamblador o compilador compatible), nos permite ejecutar comandos del S.O. y nos permite obtener información de las interrupciones de manera simbólica. Otra opción es usar el programa TD.EXE o Turbo Debugger.
1.6 ENTORNO DE PROGRAMACIÓN Se recomienda ampliamente trabajar en ensamblador en modo de consola, para un adecuado uso de los registros del procesador, utilizarlo en entorno gráfico puede tener como consecuencia interrupciones abruptas del sistema. Por tanto el entorno de programación es el austero modo de consola, pantalla negra, tecleando los comando, sin el entretenido uso del ratón. Ejecutando el proceso de ensamble y ligado, lo que se vería en la pantalla sería lo siguiente: Ensamblado C:\DATA\PROGRAMS\ASM>masm main Microsoft (R) Macro Assembler Version 4.00 Copyright (C) Microsoft Corp 1981, 1983, 1984, 1985. All rights reserved. Object filename [main.OBJ]: Source listing [NUL.LST]: Cross-reference [NUL.CRF]: 50966 Bytes symbol space free 0 Warning Errors 31
INSTITUTO TECNOLÓGICO SUPERIOR DE SAN ANDRES TUXTLA INGENIERIA EN SISTEMAS COMPUTACIONALES Lenguaje de Interfaz Unidad 1: Fundamentos MTI. Ana Francisca Lule Rangel
0 Severe Errors Ensamblado del programa MAIN.ASM
C:\DATA\PROGRAMS\ASM>masm task Microsoft (R) Macro Assembler Version 4.00 Copyright (C) Microsoft Corp 1981, 1983, 1984, 1985. All rights reserved. Object filename [task.OBJ]: Source listing [NUL.LST]: Cross-reference [NUL.CRF]: 51034 Bytes symbol space free 0 Warning Errors 0 Severe Errors Ensamblado del programa TASK.ASM
Ligado C:\DATA\PROGRAMS\ASM>link main+task Microsoft (R) 8086 Object Linker Version 3.05 Copyright (C) Microsoft Corp 1983, 1984, 1985. All rights reserved. Run File [MAIN.EXE]: List File [NUL.MAP]: Libraries [.LIB]: C:\DATA\PROGRAMS\ASM>main Entrando a un submodulo.... .......saliendo del submodulo. Ligado de los programas MAIN.OBJ y TASK. OBJ
C:\DATA\PROGRAMS\ASM>
32