PROCESADOR
El microprocesador (o simplemente procesador) es el circuito integrado central más complejo de un sistema informático; a modo de ilustración, se le suele llamar por analogía el «cerebro» de un computador.
Es el encargado de ejecutar los programas, desde el sistema operativo hasta las aplicaciones de usuario; sólo ejecuta instrucciones programadas en lenguaje de bajo nivel, realizando operaciones aritméticas y lógicas simples, tales como sumar, restar, multiplicar, dividir, las lógicas binarias y accesos a memoria.
Puede contener una o más unidades centrales de procesamiento (CPU) constituidas, esencialmente, por registros, una unidad de control, una unidad aritmético lógica (ALU) y una unidad de cálculo en coma flotante (conocida antiguamente como «coprocesador matemático»).
El microprocesador está conectado generalmente mediante un zócalo específico de la placa base de la computadora; normalmente para su correcto y estable funcionamiento, se le incorpora un sistema de refrigeración que consta de un disipador de calor fabricado en algún material de alta conductividad térmica, como cobre o aluminio, y de uno o más ventiladores que eliminan el exceso del calor absorbido por el disipador. Entre el disipador y la cápsula del microprocesador usualmente se coloca pasta térmica para mejorar la conductividad del calor. Existen otros métodos más eficaces, como la refrigeración líquida o el uso de células peltier para refrigeración extrema, aunque estas técnicas se utilizan casi exclusivamente para aplicaciones especiales, tales como en las prácticas de overclocking.
La medición del rendimiento de un microprocesador es una tarea compleja, dado que existen diferentes tipos de "cargas" que pueden ser procesadas con diferente efectividad por procesadores de la misma gama. Una métrica del rendimiento es la frecuencia de reloj que permite comparar procesadores con núcleos de la misma familia, siendo este un indicador muy limitado dada la gran variedad de diseños con los cuales se comercializan los procesadores de una misma marca y referencia. Un sistema informático de alto rendimiento puede estar equipado con varios microprocesadores trabajando en paralelo, y un microprocesador puede, a su vez, estar constituido por varios núcleos físicos o lógicos. Un núcleo físico se refiere a una porción interna del microprocesador casi-independiente que realiza todas las actividades de una CPU solitaria, un núcleo lógico es la simulación de un núcleo físico a fin de repartir de manera más eficiente el procesamiento. Existe una tendencia de integrar el mayor número de elementos dentro del propio procesador, aumentando así la eficiencia energética y la miniaturización. Entre los elementos integrados están las unidades de punto flotante, controladores de la memoria RAM, controladores de buses y procesadores dedicados de vídeo.
Desde el punto de vista lógico, singular y funcional, el microprocesador está compuesto básicamente por: varios registros, una unidad de control, una unidad aritmético lógica, y dependiendo del procesador, puede contener una unidad de coma flotante.
El microprocesador ejecuta instrucciones almacenadas como números binarios organizados secuencialmente en la memoria principal. La ejecución de las instrucciones se puede realizar en varias fases:
• Prefetch, prelectura de la instrucción desde la memoria principal.
• Fetch, envío de la instrucción al decodificador
• Decodificación de la instrucción, es decir, determinar qué instrucción es y por tanto qué se debe hacer.
• Lectura de operandos (si los hay).
• Ejecución, lanzamiento de las máquinas de estado que llevan a cabo el procesamiento.
• Escritura de los resultados en la memoria principal o en los registros.
Cada una de estas fases se realiza en uno o varios ciclos de CPU, dependiendo de la estructura del procesador, y concretamente de su grado de segmentación. La duración de estos ciclos viene determinada por la frecuencia de reloj, y nunca podrá ser inferior al tiempo requerido para realizar la tarea individual (realizada en un solo ciclo) de mayor coste temporal. El microprocesador se conecta a un circuito PLL, normalmente basado en un cristal de cuarzo capaz de generar pulsos a un ritmo constante, de modo que genera varios ciclos (o pulsos) en un segundo. Este reloj, en la actualidad, genera miles de megahercios.
Arquitectura: El microprocesador tiene una arquitectura parecida a la computadora digital. En otras palabras, el microprocesador es como la computadora digital porque ambos realizan cálculos bajo un programa de control. Consiguientemente, la historia de la computadora digital ayuda a entender el microprocesador. Hizo posible la fabricación de potentes calculadoras y de muchos otros productos. El microprocesador utiliza el mismo tipo de lógica que es usado en la unidad procesadora central (CPU) de una computadora digital. El microprocesador es algunas veces llamado unidad microprocesadora (MPU). En otras palabras, el microprocesador es una unidad procesadora de datos. En un microprocesador se puede diferenciar diversas partes:Encapsulado: es lo que rodea a la oblea de silicio en si, para darle consistencia, impedir su deterioro (por ejemplo, por oxidación por el aire) y permitir el enlace con los conectores externos que lo acoplaran a su zócalo de la placa base.
Memoria caché: es una memoria ultrarrápida que emplea el procesador para tener alcance directo a ciertos datos que «predeciblemente» serán utilizados en las siguientes operaciones, sin tener que acudir a la memoria RAM, reduciendo así el tiempo de espera para adquisición de datos. Todos los micros compatibles con PC poseen la llamada caché interna de primer nivel o L1; es decir, la que está dentro del micro, encapsulada junto a él. Los micros más modernos (Core i3, Core i5 , core i7, etc) incluyen también en su interior otro nivel de caché, más grande, aunque algo menos rápida, es la caché de segundo nivel o L2 e incluso los hay con memoria caché de nivel 3, o L3.
• Coprocesador matemático: unidad de coma flotante. Es la parte del micro especializada en esa clase de cálculos matemáticos, antiguamente estaba en el exterior del procesador en otro chip. Esta parte está considerada como una parte «lógica» junto con los registros, la unidad de control, memoria y bus de datos.
• Registros: son básicamente un tipo de memoria pequeña con fines especiales que el micro tiene disponible para algunos usos particulares. Hay varios grupos de registros en cada procesador. Un grupo de registros está diseñado para control del programador y hay otros que no son diseñados para ser controlados por el procesador pero que la CPU los utiliza en algunas operaciones, en total son treinta y dos registros.
• Memoria: es el lugar donde el procesador encuentra las instrucciones de los programas y sus datos. Tanto los datos como las instrucciones están almacenados en memoria, y el procesador las accede desde allí. La memoria es una parte interna de la computadora y su función esencial es proporcionar un espacio de almacenamiento para el trabajo en curso.
• Puertos: es la manera en que el procesador se comunica con el mundo externo. Un puerto es análogo a una línea de teléfono. Cualquier parte de la circuitería de la computadora con la cual el procesador necesita comunicarse, tiene asignado un «número de puerto» que el procesador utiliza como si fuera un número de teléfono para llamar circuitos o a partes especiales.
FAMILIA 8086
El Intel 8086 y el Intel 8088 (i8086, llamados oficialmente iAPX 86, y i8088) son los primeros microprocesadores de 16 bits diseñados por Intel. Fueron el inicio y los primeros miembros de la arquitectura x86. El trabajo de desarrollo para el 8086 comenzó en la primavera de 1976 y fue lanzando al mercado en el verano de 1978. El 8088 fue lanzado en 1979.
El 8086 y el 8088 ejecutan el mismo conjunto de instrucciones. Internamente son idénticos, excepto que el 8086 tiene una cola de 6 bytes para instrucciones y el 8088 de sólo 4. Exteriormente se diferencian en que el 8086 tiene un bus de datos de 16 bits y el del 8088 es de sólo 8 bits, por ello, el 8086 era más rápido. Por otro lado, el 8088 podía usar menos circuitos lógicos de soporte, lo que permitía la fabricación de sistemas más económicos.
El 8088 fue el microprocesador usado para la primera computadora personal de IBM, la IBM PC, que salió al mercado en agosto de 1981. Hay que tener en cuenta que la mayoría del hardware, de principios de los 80, era de 8 bits, y más barato. El hardware de 16 bits era casi inexistente en 1981 y carísimo.
El 8086 y el 8088 tienen internamente dos componentes, la Unidad de Interfaz del Bus y la Unidad de ejecución (Bus Interface Unit (BIU) y Execution Unit (EU)).
• La Unidad de Ejecución procesa las instrucciones del CPU. Está conformada por los registros generales, los registros índice y apuntadores, los flags, la unidad aritmético lógica, y la lógica de control que maneja todo el proceso para ejecutar las instrucciones.
• La Unidad de Interfaz del Bus maneja la lectura y escritura desde y hacia la memoria y los puertos de entrada/salida. Está conformada por los registros de segmento, una cola de 4 bytes para instrucciones en el 8088 y de 6 en el 8086, y lógica para controlar los buses externos del microprocesador.
En la figura de la derecha, la Unidad de Ejecución se encuentra en la parte de abajo y la Unidad de Interfaz del Bus está en la parte superior. Las dos están interconectadas mediante un bus interno.
Pines del 8086:
ENSAMBLADOR
El término ensamblador (del inglés assembler) se refiere a un tipo de programa informático que se encarga de traducir un fichero fuente escrito en un lenguaje ensamblador, a un fichero objeto que contiene código máquina, ejecutable directamente por el microprocesador.
Funcionamiento
El programa lee el fichero escrito en lenguaje ensamblador y sustituye cada uno de los códigos nemotécnicos que aparecen por su código de operación correspondiente en sistema binario para la plataforma que se eligió como destino en las opciones específicas del ensamblador.
Tipos de Ensambladores
Podemos distinguir entre dos 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.
• Ensambladores modulares 32-bits o 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.
El lenguaje ensamblador, o assembler (en inglés assembly language y la abreviación asm), es un lenguaje de programación de bajo nivel. Consiste en un conjunto de mnemónicos que representan instrucciones básicas para los computadores, microprocesadores, microcontroladores y otros circuitos integrados programables. Implementa una representación simbólica de los códigos de máquina binarios y otras constantes necesarias para programar una arquitectura de procesador y constituye la representación más directa del código máquina específico para cada arquitectura legible por un programador. Cada arquitectura de procesador tiene su propio lenguaje ensamblador que usualmente es definida por el fabricante de hardware, y está basada en los mnemónicos que simbolizan los pasos de procesamiento (las instrucciones), los registros del procesador, las posiciones de memoria y otras características del lenguaje. Un lenguaje ensamblador es por lo tanto específico de cierta arquitectura de computador física (o virtual). Esto está en contraste con la mayoría de los lenguajes de programación de alto nivel, que idealmente son portátiles.
Un programa utilitario llamado ensamblador es usado para traducir sentencias del lenguaje ensamblador al código de máquina del computador objetivo. El ensamblador realiza una traducción más o menos isomorfa (un mapeo de uno a uno) desde las sentencias mnemónicas a las instrucciones y datos de máquina. Esto está en contraste con los lenguajes de alto nivel, en los cuales una sola declaración generalmente da lugar a muchas instrucciones de máquina.
Muchos sofisticados ensambladores ofrecen mecanismos adicionales para facilitar el desarrollo del programa, controlar el proceso de ensamblaje, y la ayuda de depuración. Particularmente, la mayoría de los ensambladores modernos incluyen una facilidad de macro (descrita más abajo), y se llaman macro ensambladores.
Fue usado principalmente en los inicios del desarrollo de software, cuando aún no se contaba con potentes lenguajes de alto nivel y los recursos eran limitados. Actualmente se utiliza con frecuencia en ambientes académicos y de investigación, especialmente cuando se requiere la manipulación directa de hardware, alto rendimiento, o un uso de recursos controlado y reducido. También es utilizado en el desarrollo de controladores de dispositivo (en inglés, device drivers) y en el desarrollo de sistemas operativos, debido a la necesidad del acceso directo a las instrucciones de la máquina. Muchos dispositivos programables (como los microcontroladores) aún cuentan con el ensamblador como la única manera de ser manipulados.
BUS DE DATOS
En arquitectura de computadores, el bus (o canal) es un sistema digital que transfiere datos entre los componentes de una computadora o entre varias computadoras. Está formado por cables o pistas en un circuito impreso, dispositivos como resistores y condensadores además de circuitos integrados.
Existen dos tipos de transferencia en los buses:
1. Serie: El bus solamente es capaz de transferir los datos bit a bit. Es decir, el bus tiene un único cable que transmite la información.
2. Paralelo: El bus permite transferir varios bits simultáneamente, por ejemplo 8 bits.
Aunque en primera instancia parece mucho más eficiente la transferencia en paralelo, esta presenta inconvenientes:
1. La frecuencia de reloj en el bus paralelo tiene que ser más reducida.
2. La longitud de los cables que forman el bus está limitada, ya que a partir de determinada longitud la probabilidad de que los bits lleguen desordenados es elevada.
Además, los modernos buses serie están formados por varios canales: En este caso se transmite por varios buses serie simultáneamente.
En los primeros computadores electrónicos, era muy habitual encontrar buses paralelos, quedando los buses serie dedicados para funciones de menor entidad y dispositivos lentos, como el teclado.
La tendencia en los últimos años es reemplazar los buses paralelos por buses serie (que suelen ser multicanal). Estos son más difíciles de implementar, pero están dejando velocidades de transferencia más elevadas, y permitiendo longitudes de cable mayores.
El bus de datos permite el intercambio de datos entre la CPU y el resto de unidades. Como por ejemplo cable IDE
BUS DE DIRECCIONES
La memoria RAM es direccionable, de forma que cada celda de memoria tiene su propia dirección. Las direcciones son un número que selecciona una celda de memoria dentro de la memoria principal o en el espacio de direcciones de la unidad de entrada/salida.
El bus de direcciones es un canal del microprocesador totalmente independiente del bus de datos donde se establece la dirección de memoria del dato en tránsito.
El bus de dirección consiste en el conjunto de líneas eléctricas necesarias para establecer una dirección. La capacidad de la memoria que se puede direccionar depende de la cantidad de bits que conforman el bus de direcciones, siendo 2n el tamaño máximo en bits del banco de memoria que se podrá direccionar con n líneas. Por ejemplo, para direccionar una memoria de 256 bits, son necesarias al menos 8 líneas, pues 28 = 256. Adicionalmente pueden ser necesarias líneas de control para señalar cuando la dirección está disponible en el bus. Esto depende del diseño del propio bus.
REGISTROS
Los registros del i8086 e i8088 se basaron en el diseño del Intel 8080 y el Intel 8085, y de hecho son compatibles a nivel de lenguaje ensamblador con el i8080. El conjunto de registros también es similar al del i8080, pero ampliados a 16 bits. Tanto el i8086 como el i8088 tienen cuatro registros de propósito general de 16 bits, que también pueden ser accedidos como ocho registros de 8 bits, y tienen cuatro registros índice de 16 bits (incluyendo el puntero de pila). Los registros de datos se usan a veces de forma implícita por las instrucciones, haciendo más difícil la organización de los registros para emplearlos con valores temporales.
Los registros del procesador, se usan para contener los datos con que se está trabajando puesto que el acceso a los registros es mucho más rápido que los accesos a memoria. Se pueden realizar operaciones aritméticas y lógicas, comparaciones, entre otras. Se pueden hacer estas operaciones con todos los registros excepto los de segmento, el IP, y los flags.
Registros de Propósito General:
Los registros de propósito general son el AX, BX, CX, y DX, de 16 bits. Cada uno de ellos se divide en dos registros de 8 bits, llamados AH y AL, BH y BL, CH y CL, y, DH y DL, H significando High (alto) y L significando Low (bajo), indicando la parte alta o la parte baja del registro correspondiente de 16 bits (ver esquema). Un programa podía usar tanto los registros de 16 bits como los registros de 8 bits. Aparte del uso general de los registros para hacer cálculos aritméticos y lógicos, existen instrucciones que usan estos registros con un uso particular especializado, como se indica a continuación:
• Registro AX: El registro AX es el registro acumulador, es utilizado para operaciones que implican entrada/salida, multiplicación y división (estas dos últimas en conjunto con el registro DX).
• Registro BX: El registro BX es el registro base, y es el único registro de propósito general que puede ser un índice para direccionamiento indexado
• Registro CX: El registro CX es conocido como el registro contador. Puede contener un valor para controlar el número de veces que un ciclo se repite o un valor para corrimiento de bits.
• Registro DX: El registro DX es el registro de datos. En algunas operaciones se indica mediante este registro el número de puerto de entrada/salida, y en las operaciones de multiplicación y división de 16 bits se utiliza junto con el acumulador AX.
Registros Índice:
Los registros SI y DI están disponibles para direccionamiento indexado y para operaciones de cadenas de caracteres.
• Registro SI: El registro índice fuente de 16 bits es requerido por algunas operaciones con cadenas de caracteres. El SI está asociado con el segmento DS.
• Registro DI: El registro índice destino también es requerido por algunas operaciones con cadenas de caracteres. El DI está asociado con el segmento ES.
Registros Apuntadores:
Los registros SP (apuntador de pila) y BP (apuntador base) están asociados con el registro SS y permiten al sistema acceder a datos en el segmento de la pila.
• Registro SP: El apuntador de pila de 16 bits está asociado con el segmento SS y proporciona un valor de desplazamiento que se refiere a la palabra actual que está siendo procesada en la pila. El sistema maneja de manera automática este registro, aunque el programa puede hacer ciertas manipulaciones con él.
• Registro BP: El apuntador base de 16 bits facilita la referencia de parámetros dentro de la pila.
Registros de Banderas:
Es un registro de 16 bits, de los cuales nueve sirven para indicar el estado actual de la máquina y el resultado del procesamiento. Muchas instrucciones aritméticas y de comparación cambian el estado de las banderas y apoyándose en ellas se pueden tomar decisiones para determinar la acción subsecuente.
La tabla contiene 16 posiciones (de 0 a 15), que son los 16 bits del registro de banderas, numeradas de derecha a izquierda. La posición 0 la encontraremos a la derecha y la posición 15 a la izquierda.
Los bits de las banderas son las siguientes:
• OF (overflow, desbordamiento): Indica desbordamiento del bit de mayor orden después de una operación aritmética de números con signo (1=existe overflow; 0=no existe overflow). Para operaciones sin signo, no se toma en cuenta esta bandera.
• DF (dirección): Controla la selección de incremento o decremento de los registros SI y DI en las operaciones con cadenas de caracteres (1=decremento automático; 0=incremento). La bandera DF se controla con las instrucciones STD y CLD.
• IF (interrupción): Controla el disparo de las interrupciones (1=habilita las interrupciones; 0=deshabilita las interrupciones). La interrupción no enmascarable es la única que no puede ser bloqueada por esta bandera. El estado de la bandera IF se controla con las instrucciones STI y CLI.
• TF (trampa): Permite la operación del procesador en modo de depuración (paso a paso).
• SF (signo): Contiene el signo resultante de una operación aritmética (0=positivo; 1=negativo).
• ZF (cero): Indica el resultado de una operación aritmética o de comparación (0=resultado diferente de cero; 1=resultado igual a cero).
• AF (acarreo auxiliar): Contiene el acarreo del bit 3. Esta bandera se prueba con las instrucciones DAA y DAS para ajustar el valor de AL después de una suma o resta BCD.
• PF (paridad): Indica si el número de bits 1, del byte menos significativos de una operación, es par (0=número de bits 1 es impar; 1=número de bits 1 es par).
• CF (acarreo): Contiene el acarreo del bit de mayor orden después de una operación aritmética; también almacena el contenido del último bit en una operación de desplazamiento o de rotación.
Un ejemplo de activación de bandera se puede dar con la realización de una resta común, donde se realice la operación 5-5 en tal caso se activa indudablemente la bandera de ZF (zero flag), resultando la misma en 1.
Registros de Segmento:
Definen áreas de 64 Kb dentro del espacio de direcciones de 1 Mb del 8086. Estas áreas pueden solaparse total o parcialmente. No es posible acceder a una posición de memoria no definida por algún segmento: si es preciso, habrá de moverse alguno.
• Registro CS: El DOS almacena la dirección inicial del segmento de código de un programa en el registro CS. Esta dirección de segmento, más un valor de desplazamiento en el registro apuntador de instrucción (IP), indica la dirección de una instrucción que es buscada para su ejecución. Para propósitos de programación normal, no se necesita referenciar el registro CS.
• Registro DS: La dirección inicial de un segmento de datos de programa es almacenada en el registro DS. Esta dirección, más un valor de desplazamiento en una instrucción, genera una referencia a la localidad de un byte específico en el segmento de datos.
• Registro SS: El registro SS permite la colocación en memoria de una pila, para almacenamiento temporal de direcciones y datos. El DOS almacena la dirección de inicio del segmento de pila de un programa en el registro SS. Esta dirección de segmento, más un valor de desplazamiento en el registro del apuntador de la pila (SP), indica la palabra actual en la pila que está siendo direccionada. Para propósitos de programación normal, no se necesita referenciar el registro SS.
• Registro ES: Algunas operaciones con cadenas de caracteres utilizan el registro extra de segmento para manejar el direccionamiento de memoria. El registro ES está asociado con el registro DI (Índice). Un programa que requiere el uso del registro ES puede inicializarlo con una dirección de segmento apropiada.
Registro Apuntador de Instrucciones:
El registro IP de 16 bits contiene el desplazamiento de dirección de la siguiente instrucción que se ejecuta. El IP está asociado con el registro CS en el sentido de que el IP indica la instrucción actual dentro del segmento de código que se está ejecutando actualmente en la memoria.
STACK POINTER (SP)
Es el apuntador de la pila de 16 bits, está asociado con el registro SS (segmento de pila) y proporciona un valor de desplazamiento que se refiere a la palabra actual que está siendo procesada en la pila. Los procesadores 80386 y posteriores tienen un apuntador de pila de 32 bits, siendo almacenado en el registro ESP (stack pointer extendido). El sistema maneja de manera automática estos registros.
En el siguiente ejemplo el registro SS contiene la dirección de segmento 27B30H y el SP el desplazamiento 312H. Para encontrar la palabra que está siendo procesada en la pila, la computadora combina las direcciones en el SS y el SP de la siguiente forma.
27B30H+312H=27E42H
Encontrando que la dirección actual de la pila es 27E42H
PROGRAM CONTER
El contador de programa (en inglés Program Counter o PC), también llamado Puntero de instrucciones (Instruction Pointer), parte del secuenciador de instrucciones en algunas computadoras, es un registro del procesador de un computador que indica la posición donde está el procesador en su secuencia de instrucciones. Dependiendo de los detalles de la máquina particular, contiene o la dirección de la instrucción que es ejecutada, o la dirección de la próxima instrucción a ser ejecutada. El contador de programa es incrementado automáticamente en cada ciclo de instrucción de tal manera que las instrucciones son leídas en secuencia desde la memoria. Ciertas instrucciones, tales como las bifurcaciones y las llamadas y retornos de subrutinas, interrumpen la secuencia al colocar un nuevo valor en el contador de programa.
En la inmensa mayoría de los procesadores, el puntero de instrucciones es incrementado inmediatamente después de leer (fetch) una instrucción de programa; esto significa que la dirección a la que apunta una instrucción de bifurcación es obtenida agregando el operando de la instrucción de bifurcación a la dirección de la instrucción siguiente (byte o word, dependiendo del tipo de la computadora) después de la instrucción de bifurcación. La dirección de la siguiente instrucción a ser ejecutada siempre se encuentra en el contador de instrucción.
SISTEMAS OPERATIVOS
Los propósitos generales de un sistema operativo son (1) permitir a los usuarios instruir a una computadora con respecto a las acciones que debe tomar (como ejecutar un programa en particular) y (2) facilitar los métodos de almacenamiento de la información en el disco (“catalogar”) y de tener acceso a la misma.
El sistema operativo más común para la pc y sus compatibles es el MD-DOS de Microsoft, conocido como PC-DOS en la IBM PC. Cada una de las versiones del DOS ha proporcionado características adicionales que han extendido capacidades de la PC. También existen sistemas avanzados como OS/2 y UNIX.
PROCESO DE ARRANQUE
Encender la computadora provoca una “inicialización” (algunos le llaman “arranque den frio”). El procesador introduce un estado de restauración, limpia todas las localidades de memoria (es decir, coloca cero en todas ellas), realiza una verificación de paridad de la memoria y asigna al registro CS la dirección de segmento FFFF0H y al registro IP el desplazamiento cero. Por tanto, la primera instrucción a ejecutarse esta en la dirección formada por la pareja CS:IP, que es FFFF0H, la cual es el punto de entrada al BIOS en ROM.
La rutina de BIOS que inicia en FFFF0H verifica los diferentes puertos para identificarlos e inicializa los dispositivos que están conectados a la computadora. Después el BIOS establece dos áreas de datos:
1. Una tabla de servicios de interrupción, que inicia en memoria baja en la localidad 0 y contiene las direcciones de las interrupciones que ocurren.
2. Un área de datos del BIOS que inicia en la localidad 40, que está directamente relacionado con los dispositivos conectados.
A continuación el BIOS determina si está presente un disco que contenga los archivos de sistema del DOS y, en caso de que así sea, accesa el cargador de arranque desde el disco. Este programa carga los archivos de sistema IO.SYS y MSDOS.SYS desde el disco hacia la memoria y transfiere el control al punto de entrada del IO.SYS, el cual contiene los controladores de dispositivos y otro código especifico del hardware. El IO.SYS se reubica en memoria y este transfiere el control al MSDOS.SYS. Este módulo inicializa las tablas internas del DOS y la porción del DOS de la tabla de interrupciones. También lee el archivo CONFIG.SYS y ejecuta sus comandos. Finalmente, el MSDOS.SYS pasa el control al COMMAND.COM, el cual procesa el archivo AUTOEXEC.BAT, muestra su indicación y monitorea las entradas dadas desde el teclado.
INTERFAZ DOS-BIOS
El BIOS contiene un conjunto de rutinas en ROM para dar soporte a los dispositivos. El BIOS prueba e inicializa los dispositivos conectados y proporciona los servicios que son usados para la lectura y escritura desde los dispositivos. Una tarea del DOS es hacer interfaz con el BIOS cuando exista una necesidad de accesar estas facilidades.
Cuando un programa usuario solicita un servicio del DOS, este podría transferir la solicitud al BIOS, el cual a su vez accesa al dispositivo solicitado. Sin embargo, algunas veces un programa hace la petición directamente al BIOS, específicamente para servicios de teclado y de pantalla. Y en otras ocasiones (aunque es raro y poco recomendable) un programa puede pasar por alto tanto al DOS como al BIOS para accesar a un dispositivo directamente.
DIRECTIVAS DEL ENSAMBLADOR
Las directivas del ensamblador, también llamadas los pseudo opcodes, pseudo-operaciones o pseudo-ops, son instrucciones que son ejecutadas por un ensamblador en el tiempo de ensamblado, no por un CPU en el tiempo de ejecución. Pueden hacer al ensamblado del programa dependiente de parámetros entrados por un programador, de modo que un programa pueda ser ensamblado de diferentes maneras, quizás para diversas aplicaciones. También pueden ser usadas para manipular la presentación de un programa para hacerlo más fácil leer y mantener.
Por ejemplo, las directivas pudieran ser usadas para reservar áreas de almacenamiento y opcionalmente su para asignar su contenido inicial. Los nombres de las directivas a menudo comienzan con un punto para distinguirlas de las instrucciones de máquina.
Los ensambladores simbólicos les permiten a los programadores asociar nombres arbitrarios (etiquetas o símbolos) a posiciones de memoria. Usualmente, cada constante y variable tiene un nombre para que las instrucciones puedan referir a esas ubicaciones por nombre, así promoviendo el código autodocumentado. En el código ejecutable, el nombre de cada subprograma es asociado a su punto de entrada, así que cualquier llamada a un subprograma puede usar su nombre. Dentro de subprogramas, a los destinos GOTO se le dan etiquetas. Algunos ensambladores soportan símbolos locales que son léxicamente distintos de los símbolos normales (ej, el uso de "10$" como un destino GOTO).
La mayoría de los ensambladores proporcionan un manejo flexible de símbolos, permitiendo a los programadores manejar diversos espacios de nombres, calcular automáticamente offsets dentro de estructuras de datos, y asignar etiquetas que refieren a valores literales o al resultado de cálculos simples realizados por el ensamblador. Las etiquetas también pueden ser usadas para inicializar constantes y variables con direcciones relocalizables.
Los lenguajes ensambladores, como la mayoría de los otros lenguajes de computador, permiten que comentarios sean añadidos al código fuente, que son ignorados por el programa ensamblador. El buen uso de los comentarios es aún más importante con código ensamblador que con lenguajes de alto nivel, pues el significado y el propósito de una secuencia de instrucciones es más duro de descifrar a partir del código en sí mismo.
El uso sabio de estas facilidades puede simplificar grandemente los problemas de codificar y mantener el código de bajo nivel. El código fuente de lenguaje ensamblador crudo generado por compiladores o desensambladores - código sin ningún comentario, ni símbolos con algún sentido, ni definiciones de datos - es muy difícil de leer cuando deben hacerse cambios.
Algunas de las directivas más usadas en ensamblador son las siguientes:
- Directivas para listar:PAGE y TITLE
- Directiva SEGMENT
- Directiva PROC
- Directiva ASSUME
- Directiva END
COMPILADORES
Un compilador es un programa informático que traduce un programa que ha sido escrito en un lenguaje de programación a un lenguaje diferente, usualmente lenguaje de máquina, aunque también puede ser traducido a un código intermedio (bytecode) o a texto. Este proceso de traducción se conoce como compilación.
La construcción de un compilador involucra la división del proceso en una serie de fases que variará con su complejidad. Generalmente estas fases se agrupan en dos tareas: el análisis del programa fuente y la síntesis del programa objeto.
• Análisis: Se trata de la comprobación de la corrección del programa fuente, e incluye las fases correspondientes al Análisis léxico (que consiste en la descomposición del programa fuente en componentes léxicos), análisis sintáctico (agrupación de los componentes léxicos en frases gramaticales ) y análisis semántico (comprobación de la validez semántica de las sentencias aceptadas en la fase de análisis sintáctico).
• Síntesis: Su objetivo es la generación de la salida expresada en el lenguaje objeto y suele estar formado por una o varias combinaciones de fases de generación de código (normalmente se trata de código intermedio o de código objeto) y de optimización de código (en las que se busca obtener un código lo más eficiente posible).
Alternativamente, las fases descritas para las tareas de análisis y síntesis se pueden agrupar en Front-end y Back-end:
• Front-end: es la parte que analiza el código fuente, comprueba su validez, genera el árbol de derivación y rellena los valores de la tabla de símbolos. Esta parte suele ser independiente de la plataforma o sistema para el cual se vaya a compilar, y está compuesta por las fases comprendidas entre el análisis Léxico y la generación de código intermedio.
• Back-end: es la parte que genera el código máquina, específico de una plataforma, a partir de los resultados de la fase de análisis, realizada por el Front End.
Esta división permite que el mismo Back End se utilice para generar el código máquina de varios lenguajes de programación distintos y que el mismo Front End que sirve para analizar el código fuente de un lenguaje de programación concreto sirva para generar código máquina en varias plataformas distintas. Suele incluir la generación y optimización del código dependiente de la máquina.
Tipos de compiladores
Esta taxonomía de los tipos de compiladores no es excluyente, por lo que puede haber compiladores que se adscriban a varias categorías:
• Compiladores cruzados: generan código para un sistema distinto del que están funcionando.
• Compiladores optimizadores: realizan cambios en el código para mejorar su eficiencia, pero manteniendo la funcionalidad del programa original.
• Compiladores de una sola pasada: generan el código máquina a partir de una única lectura del código fuente.
• Compiladores de varias pasadas: necesitan leer el código fuente varias veces antes de poder producir el código máquina.
• Compiladores JIT (Just In Time): forman parte de un intérprete y compilan partes del código según se necesitan.
Pauta de creación de un compilador: En las primeras épocas de la informática, el software de los compiladores era considerado como uno de los más complejos existentes.
Los primeros compiladores se realizaron programándolos directamente en lenguaje máquina o en ensamblador. Una vez que se dispone de un compilador, se pueden escribir nuevas versiones del compilador (u otros compiladores distintos) en el lenguaje que compila ese compilador.
Actualmente existen herramientas que facilitan la tarea de escribir compiladores ó intérpretes informáticos. Estas herramientas permiten generar el esqueleto del analizador sintáctico a partir de una definición formal del lenguaje de partida, especificada normalmente mediante una gramática formal y barata, dejando únicamente al programador del compilador la tarea de programar las acciones semánticas asociadas.
Proceso de compilación
Es el proceso por el cual se traducen las instrucciones escritas en un determinado lenguaje de programación a lenguaje máquina. Además de un traductor, se pueden necesitar otros programas para crear un programa objeto ejecutable. Un programa fuente se puede dividir en módulos almacenados en archivos distintos. La tarea de reunir el programa fuente a menudo se confía a un programa distinto, llamado preprocesador. El preprocesador también puede expandir abreviaturas, llamadas a macros, a proposiciones del lenguaje fuente.
Normalmente la creación de un programa ejecutable (un típico.exe para Microsoft Windows o DOS) conlleva dos pasos. El primer paso se llama compilación (propiamente dicho) y traduce el código fuente escrito en un lenguaje de programación almacenado en un archivo a código en bajo nivel (normalmente en código objeto, no directamente a lenguaje máquina). El segundo paso se llama enlazado en el cual se enlaza el código de bajo nivel generado de todos los ficheros y subprogramas que se han mandado a compilar y se añade el código de las funciones que hay en las bibliotecas del compilador para que el ejecutable pueda comunicarse directamente con el sistema operativo, traduciendo así finalmente el código objeto a código máquina, y generando un módulo ejecutable.
Estos dos pasos se pueden hacer por separado, almacenando el resultado de la fase de compilación en archivos objetos (un típico.obj para Microsoft Windows, DOS o para Unix); para enlazarlos en fases posteriores, o crear directamente el ejecutable; con lo que la fase de compilación se almacena solo temporalmente. Un programa podría tener partes escritas en varios lenguajes (por ejemplo C, C++ y Asm), que se podrían compilar de forma independiente y luego enlazar juntas para formar un único módulo ejecutable.
CICLOS DE MAQUINA
Cuando un microprocesador ejecuta una instrucción, éste realiza una serie de operaciones o tareas básicas llamadas ciclos de máquina. Estas tareas que involucran a las componentes internas del CPU, algunas veces a la memoria o a los puertos de entrada y salida, son coordinadas con las señales de interfase generadas en la unidad de control en una secuencia ordenada.
El Z80 realiza siete diferentes ciclos de máquina, a saber:
1. Búsqueda del código de operación de la instrucción (ciclo M1).
2. Ciclo de escritura o lectura de datos en y de la memoria.
3. Ciclos de lectura o escritura en puertos de E/S.
4. Ciclo de petición /concesión de buses.
5. Ciclo de petición /concesión de interrupciones enmascarables.
6. Ciclo de petición/ concesión de interrupciones no enmascarables.
7. Salida de una instrucción HALT.
Cada ciclo de máquina se realiza en sincronía con el reloj maestro, cuya entrada es la CLK, de la terminal 6 del Z80.
El periodo de esta señal de reloj “T”, es la referencia básica de la duración de un ciclo de máquina. El número de ciclos T que se toma un ciclo de máquina para realizar la tarea varía en función de su complejidad.
Mientras más complicado sea el ciclo de máquina, este se tomará más ciclos T en realizarlo.
Si suponemos que el mico trabaja con un reloj de 4MHz, cada ciclo T durará 250 nanosegundos.
Esto es: Un ciclo de búsqueda M1 está compuesto de 4 ciclos T( este ciclo es más largo porque es necesario la decodificación de instrucciones) un ciclo de lectura a la memoria tiene 3 ciclos T.
RESUMIENDO:
Las instrucciones se hacen de ciclos de máquinas, los cuales son compuestos por ciclos T. Cada 1er byte de una instrucción es un byte de un código de operación, tal que el Z-80 siempre realiza al menos un ciclo M 1 en la ejecución de cualquier instrucción . Ciclos de máquina hay varios pero un ciclo T es único, es una transición lógica de 250ns en vez de 4Mhzdel cero lógico al 1 lógico a 0 lógico.
INTERRUPCIONES
En el contexto de la informática, una interrupción (del inglés interrupt request, en español «petición de interrupción») es una señal recibida por el procesador de una computadora, para indicarle que debe «interrumpir» el curso de ejecución actual y pasar a ejecutar código específico para tratar esta situación.
Una interrupción es una suspensión temporal de la ejecución de un proceso, para pasar a ejecutar una subrutina de servicio de interrupción, la cual, por lo general, no forma parte del programa, sino que pertenece al sistema operativo o al BIOS. Una vez finalizada dicha subrutina, se reanuda la ejecución del programa.
Las interrupciones son generadas por los dispositivos periféricos habilitando una señal del CPU (llamada IRQ del inglés "interrupt request") para solicitar atención del mismo. Por ejemplo. Cuando un disco duro completa una lectura solicita atención al igual que cada vez que se presiona una tecla o se mueve el ratón.
La primera técnica que se empleó para esto fue el polling, que consistía en que el propio procesador se encargara de sondear los dispositivos periféricos cada cierto tiempo para averiguar si tenía pendiente alguna comunicación para él. Este método presentaba el inconveniente de ser muy ineficiente, ya que el procesador consumía constantemente tiempo y recursos en realizar estas instrucciones de sondeo.
El mecanismo de interrupciones fue la solución que permitió al procesador desentenderse de esta problemática, y delegar en el dispositivo periférico la responsabilidad de comunicarse con él cuando lo necesitara. El procesador, en este caso, no sondea a ningún dispositivo, sino que queda a la espera de que estos le avisen (le "interrumpan") cuando tengan algo que comunicarle (ya sea un evento, una transferencia de información, una condición de error, etc.).
Tipos de interrupciones
Atendiendo a la fuente que las produce, las interrupciones pueden clasificarse de la siguiente forma:
• Interrupciones de hardware. Estas son asíncronas a la ejecución del procesador, es decir, se pueden producir en cualquier momento independientemente de lo que esté haciendo el CPU en ese momento. Las causas que las producen son externas al procesador y a menudo suelen estar ligadas con los distintos dispositivos de entrada o salida.
• Excepciones. Son aquellas que se producen de forma síncrona a la ejecución del procesador y por tanto podrían predecirse si se analiza con detenimiento la traza del programa que en ese momento estaba siendo ejecutado en la CPU. Normalmente son causadas al realizarse operaciones no permitidas tales como la división entre 0, el desbordamiento, el acceso a una posición de memoria no permitida, etc.
• Interrupciones por software. Las interrupciones por software son aquellas generadas por un programa en ejecución. Para generarlas, existen distintas instrucciones en el código máquina que permiten al programador producir una interrupción, las cuales suelen tener nemotécnicos tales como INT (por ejemplo, en DOS se realiza la instrucción INT 0x21 y en Unix se utiliza INT 0x80 para hacer llamadas de sistema).
- Interrupciones de hardware:
Las interrupciones de hardware son aquellas interrupciones que se producen como resultado de, por lo general, una operación de E/S. No son producidas por ninguna instrucción de un programa sino por las señales que emiten los dispositivos periféricos para indicarle al procesador que necesitan ser atendidos.
Cuando el microprocesador accede a un periférico (disco duro, puerto de comunicación...), puede transcurrir algún tiempo antes de que los datos sean obtenidos o transmitidos. La solución más simple es esperar hasta recibir los datos o hasta que se haya efectuado la transmisión (polling), pero esta solución bloquea todos los programas en ejecución, y eso no puede admitirse en un sistema multitarea. Por ello, en los sistemas modernos se prefiere un funcionamiento mediante interrupciones, ya que éstas permiten mejorar la productividad del procesador, de forma que este último puede ordenar una operación de entrada o salida y, en lugar de tener que realizar una espera activa, se puede dedicar a atender a otro proceso o aplicación hasta que el dispositivo esté de nuevo disponible, siendo dicho dispositivo el encargado de notificar al procesador mediante la línea de interrupción que ya está preparado para continuar o terminar la operación de entrada o salida.
- Excepciones:
Las excepciones son un tipo de interrupción sincrónica típicamente causada por una condición de error en un programa, como por ejemplo una división entre 0 o un acceso inválido a memoria en un proceso de usuario. Normalmente genera un cambio de contexto a modo supervisor para que el sistema operativo atienda el error. Así pues, las excepciones son un mecanismo de protección que permite garantizar la integridad de los datos almacenados tanto en el espacio de usuario como en el espacio kernel. Cuando el Sistema Operativo detecta una excepción intenta solucionarla, pero en caso de no poder simplemente notificará la condición de error a la aplicación/usuario y abortará la misma.
- Interrupciones por software:
Las interrupciones por software, también denominadas llamadas al sistema, son aquellas generadas por un programa mientras este está ejecutándose. En general, actúan de la siguiente manera: Un programa en ejecución llega a una instrucción que requiere del sistema operativo para alguna tarea, por ejemplo para leer un archivo en el disco duro (cuando un programa necesita un dato exterior, se detiene y pasa a cumplir con las tareas de recoger ese dato). En ese momento por tanto llama al sistema y se interrumpe virtualmente hasta recibir respuesta, en el ejemplo anterior hasta que no se haya leído el disco y el archivo esté en memoria principal. Durante esa espera las instrucciones que se ejecutarán no serán del programa, sino del sistema operativo. Una vez éste termine su rutina ordenará reanudar la ejecución del programa autointerrumpido en espera. Por último la ejecución del programa se reanuda.
Un ejemplo es la interrupción 16H que se invoca desde el D O S o desde un programa de aplicación el código de barrido se obtiene del buffer del teclado .
MODOS DE DIRECCIONAMIENTO
Los modos de direccionamiento son las diferentes maneras de especificar un operando dentro de una instrucción en lenguaje ensamblador.
Un modo de direccionamiento especifica la forma de calcular la dirección de memoria efectiva de un operando mediante el uso de la información contenida en registros y/o constantes, contenida dentro de una instrucción de la máquina o en otra parte.
Tipos de direccionamiento
-Implícito
En este modo de direccionamiento no es necesario poner ninguna dirección de forma explícita, ya que en el propio código de operación se conoce la dirección de el/los operando/s al (a los) que se desea acceder o con el/los que se quiere operar.
Supongamos una arquitectura de pila, las operaciones aritméticas no requieren direccionamiento explícito por lo que se ponen como: - add - sub ...
Porque cuando se opera con dos datos en esta arquitectura se sabe que son los dos elementos del tope de la pila. Ejemplo de una pila
1 2 3 4 5 6 - pila top() es 1 ntop() es 2
Donde top() representa el tope de la pila y ntop() el siguiente al tope de la pila y son estos argumentos con los que se opera al llamar a una orden en concreto.
-Inmediato
En la instrucción está incluido directamente el operando.
En este modo el operando es especificado en la instrucción misma. En otras palabras, una instrucción de modo inmediato tiene un campo de operando en vez de un campo de dirección. El campo del operando contiene el operando actual que se debe utilizar en conjunto con la operación especificada en la instrucción. Las instrucciones de modo inmediato son útiles para inicializar los registros en un valor constante.
Cuando el campo de dirección especifica un registro del procesador, la instrucción se dice que está en el modo de registro.
Su valor es fijo, por lo que se suele utilizar en operaciones aritméticas o para definir constantes y variables. Como ventaja, no se requiere acceso adicional a memoria para obtener el dato, pero el tamaño del operando está limitado por el tamaño del campo de direccionamiento.
Las desventajas principales son que el valor del dato es constante y el rango de valores que se pueden representar está limitado por el tamaño de este operando.
Ejemplo: MOV A,#17H
-Directo
El campo de operando en la instrucción contiene la dirección en memoria donde se encuentra el operando.
En este modo la dirección efectiva es igual a la parte de dirección de la instrucción. El operando reside en la memoria y su dirección es dada directamente por el campo de dirección de la instrucción. En una instrucción de tipo ramificación el campo de dirección especifica la dirección de la rama actual.
Si hace referencia a un registro de la máquina, el dato estará almacenado en este registro y hablaremos de direccionamiento directo a registro; si hace referencia a una posición de memoria, el dato estará almacenado en esta dirección de memoria (dirección efectiva) y hablaremos de direccionamiento directo a memoria. Estos modos de direccionamiento tienen una forma muy simple y no hay que hacer cálculos para obtener la dirección efectiva donde está el dato. El tamaño del operando, en el caso del direccionamiento directo a registro, dependerá del número de registros que tenga la máquina; en el direccionamiento directo a memoria, dependerá del tamaño de la memoria.
Ejemplo: MOV A,17H
-Indirecto
El campo de operando contiene una dirección de memoria, en la que se encuentra la dirección efectiva del operando.
Si hace referencia a un registro de la máquina, la dirección de memoria (dirección efectiva) que contiene el dato estará en este registro y hablaremos de direccionamiento indirecto a registro; si hace referencia a una posición de memoria, la dirección de memoria (dirección efectiva) que contiene el dato estará almacenada en esta posición de memoria y hablaremos de direccionamiento indirecto a memoria.
La desventaja principal de este modo de direccionamiento es que necesita un acceso más a memoria que el directo. Es decir, un acceso a memoria para el direccionamiento indirecto a registro y dos accesos a memoria para el direccionamiento indirecto a memoria; por este motivo este segundo modo de direccionamiento no se implementa en la mayoría de las máquinas.
Ejemplo: MOV A,@17H
-Absoluto:
El campo de operando contiene una dirección en memoria, en la que se encuentra la instrucción. Y no se cancela.
-De registro:
Sirve para especificar operandos que están en registros.
En este modo, los operandos están en registros que residen dentro de la CPU.
- Indirecto mediante registros
El campo de operando de la instrucción contiene un identificador de registro en el que se encuentra la dirección efectiva del operando.
En este modo el campo de la dirección de la instrucción da la dirección en donde la dirección efectiva se almacena en la memoria. El control localiza la instrucción de la memoria y utiliza su parte de dirección para acceder a la memoria de nuevo para leer una dirección efectiva. Unos pocos modos de direccionamiento requieren que el campo de dirección de la instrucción sea sumado al control de un registro especificado en el procesador. La dirección efectiva en este modo se obtiene del siguiente cálculo:
Dir. efectiva = Dir. de la parte de la instrucción + Contenido del registro del procesador...
-De desplazamiento:
Combina el modo directo e indirecto mediante registros.
- De pila:
Se utiliza cuando el operando está en memoria y en la cabecera de la pila.
Este direccionamiento se basa en las estructuras denominadas Pila (tipo LIFO), las cuales están marcados por el fondo de la pila y el puntero de pila (*SP). El puntero de pila apunta a la última posición ocupada. Así, como puntero de direccionamiento usaremos el SP.
El desplazamiento más el valor del SP nos dará la dirección del objeto al que queramos hacer referencia. En ocasiones, si no existe C. de desplazamiento solo se trabajara con la cima de la pila.
Como es un modo de direccionamiento implícito, solo se utiliza en instrucciones determinadas, las más habituales de las cuales son PUSH (poner un elemento en la pila) y POP (sacar un elemento de la pila).
Este tipo de direccionamiento nos aporta flexibilidad pero por el contrario, es mucho más complejo que otros tipos estudiados más arriba.
- Relativo a un registro base:
Consiste, al igual que el indirecto a través de registro, en calcular la dirección efectiva (EA, effective address) como la suma del contenido del registro base y un cierto desplazamiento (offset) que siempre será positivo. Esta técnica permite códigos reentrantes y acceder de forma fácil y rápida a posiciones cercanas de memoria. Este modo de direccionamiento es muy usado por los ensambladores cuando se llaman a las funciones (para acceder a los parámetros almacenados en la pila).
- Relativo a un registro índice:
Es similar al direccionamiento relativo a un registro base, excepto que es el contenido del registro índice el que indica el desplazamiento que se produce a partir de una dirección de memoria que se pasa también como argumento a la orden que utiliza este modo de direccionamiento. Aunque en esencia son dos modos equivalentes. La EA se calcula como la suma del contenido del registro índice y una dirección de memoria.
- Indexado respecto a una base:
Se trata de una combinación de los dos anteriores y consiste en calcular la dirección efectiva como:
- Relativo al contador de programa:
Consiste en dirección una posición de memoria usando como registro base al contador de programa (PC), el funcionamiento es análogo al direccionamiento respecto a registro base con la salvedad de que, en este caso, el offset puede ser también negativo.
- Indexado con autoincremento/autodecremento:
Es un modo de direccionamiento análogo al indexado, explicado anteriormente.
La única diferencia es que permite un incremento o decremento de la dirección final o el registro índice según los siguientes casos:
• Indexado con autopreincremento: Incrementa el registro índice primero (se incrementa un valor, según el tamaño del objeto direccionado) y luego calcula la EA al igual que el direccionamiento indexado.
• Indexado con autoposincremento: Calcula la dirección efectiva y después incrementa esta.
• Indexado con autopredecremento: Decrementa el registro índice y después calcula la dirección efectiva.
• Indexado con autoposdecremento: Calcula la dirección efectiva y después decrementa esta.
- Instrucción de salto con direccionamiento absoluto:
Consiste en cargar en el PC el valor que se especifica, por ejemplo: jmp 0xAB ----> Carga 0xAB en PC
- Instrucción de salto con direccionamiento relativo:
Es parecida a la especificada anteriormente la diferencia es que el salto es relativo al PC, pongamos un ejemplo: supongamos que PC vale = 0x0A, si nosotros interpretamos la instrucción jr +03, saltaremos tres posiciones posteriores a PC (también podría ser -03 y serían posiciones anteriores). Pero, ¡cuidado! si esa instrucción estaba en la posición 0x0A la dirección de PC a incrementar será la inmediatamente posterior (ya que PC se incrementa automáticamente después de leer la instrucción), por lo que quedaría:
PC = 0x0B ---> nuevo PC = 0x0B+0x03 = 0x0E, con lo que el PC quedaría como 0x0E.
- Direccionamiento paginado:
En el paginado la memoria se encuentra actualmente dividida en páginas (bloques de igual longitud).
Para obtener las direcciones se necesita:
• Indicador de página (IP): en un registro específico o de propósito general de la máquina.
• Dirección de la palabra (DP): en el campo CD de la instrucción.
Así, concatenando ambas partes se obtiene la dirección completa.
El problema viene cuando queremos referenciar un dato al que no podemos acceder de forma relativa (p.e. porque los registros base no puedan alcanzar dicha posición aun con el direccionamiento absoluto. Sin embargo, sólo una pequeña parte de la memoria se puede acceder (64 kilobytes, si el desplazamiento es de 16 bits).
El desplazamiento de 16 bits puede parecer muy pequeño en relación con el tamaño de la memoria de los equipos actuales (esta es la razón por la 80386 se expandió a 32 bits). Podría ser peor ya que: los servidores IBM System/360 sólo tienen un signo de 12 bits de desplazamiento. Sin embargo, el principio de localización se aplica en un corto espacio de tiempo, la mayoría de los elementos de datos que un programa quiere acceder están bastante cerca uno del otro.
Este modo de direccionamiento está estrechamente relacionado con el modo de direccionamiento absoluto.
Ejemplo 1: Dentro de una subrutina, un programador estará principalmente interesado en los parámetros y las variables en los atributos del objeto actual.
INSTRUCCIONES
Un programa en lenguaje ensamblador consiste en un conjunto de enunciados. Los dos tipos de enunciados son:
(1) Instrucciones, tal como MOV y ADD, que el ensamblador traduce a código objeto.
(2) Directivas, que indican al ensamblador que realice una acción específica, como definir un elemento de dato.










