Documentos de Académico
Documentos de Profesional
Documentos de Cultura
COMPUTADORAS II
LENGUAJE DE MÁQUINA Y
ENSAMBLADOR. PROCESADOR Z80.
Departamento de Informática
Esquema de contenidos
El microprocesador
Microprocesador Z80
Características y conexiones del Z80
Estructura interna
Unidad de control (UC)
Unidad aritmética y lógica (UAL)
Registros internos:
Arquitectura de la CPU Registros de uso General y de uso Específico
Microprocesador Z80 Interrupciones
Uso de las interrupciones
Modos de direccionamiento del µP Z80
Pila (Stack)
Implementación de la pila
Funcionamiento de la pila
Ensamblador del Z80
Sintaxis del lenguaje ensamblador
Repertorio de Instrucciones del lenguaje ensamblador del µZ80
Tipos de instrucciones
Es raro encontrar programadores en lenguaje de máquina; la mayoría de los programas actuales se escriben
en un lenguaje de alto nivel.
Tipos de instrucciones
Los tipos de instrucciones que deben incluirse en una computadora, deberán tener un conjunto de
instrucciones que permitieran al usuario formular cualquier tarea de procesamiento de datos. Cualquier
programa escrito en alto nivel debe traducirse a lenguaje de máquina para ser ejecutado. Por tanto, el
repertorio de instrucciones máquina debe ser suficientemente amplio como para expresar cualquiera de las
instrucciones de un lenguaje de alto nivel. Teniendo esto presente, los tipos de instrucciones se pueden
clasificar de la siguiente manera:
Procesamiento de datos: instrucciones aritméticas y lógicas
Almacenamiento de datos: instrucciones de memoria.
Transferencia de datos: instrucciones de E/S.
Control: instrucciones de comprobación (prueba) y de bifurcación.
Las instrucciones aritméticas proporcionan capacidades computacionales para el procesamiento de datos
numéricos. Las instrucciones lógicas (booleanas) operan con los bits de una palabra en lugar de considerarlos
como números, proporcionando por tanto capacidad para el procesamiento de cualquier otro tipo de datos
que el usuario quiera emplear. Estas operaciones se ejecutan, principalmente, sobre datos en los registros de
la CPU. Por lo tanto, deben existir instrucciones de memoria para mover datos entre la memoria y los
registros. Las instrucciones de E-S son necesarias para transferir programas y datos a la memoria y devolver
resultados de los cálculos al usuario. Las instrucciones de prueba se emplean para verificar el valor de una
palabra de datos o el estado de un cálculo. Las instrucciones de bifurcación se usan entonces para saltar a un
conjunto diferente de instrucciones dependiendo de la decisión tomada.
1
Ver sección 1.1. LENGUAJE DE MÁQUINA
1.4. De esta forma, un compaginador es un programa que recibe como datos de entrada un programa en
lenguaje ensamblador y produce como resultado de salida una serie de instrucciones en lenguaje máquina.
1.2.1. El microprocesador
Con los avances tecnológicos y en el campo de la electrónica fue posible que los fabricantes de computadoras
usarán chip para sus procesadores específicamente microprocesadores. Por lo tanto, se llama
microprocesador 2 (µP) a la implementación de una CPU en un solo chip. El primer microprocesador
disponible comercialmente fue fabricado en 1971 por Intel Corporation conocido comercialmente con el
número 4004, era de 4 bits y era un chip de 16 patas.
Una de las características que definen a las computadoras, es el tamaño de la palabra; es decir, el número
de bits que forman la palabra y que utiliza en forma simultánea para realizar ciertos procesos internos. El
tamaño de la palabra de datos es siempre igual al número de líneas que posee el bus de datos.
Otro aspecto que caracteriza a un microprocesador es su capacidad de direccionamiento; es decir, el tamaño
de la memoria que puede direccionar. La cantidad de direcciones se determina por la cantidad de
combinaciones que puede realizarse con n bits: 2n, donde n es el número de líneas del bus de direcciones.
En el caso del microprocesador Z80: es un procesador de 8 bits donde el tamaño de palabra es de 8 bits y 16
bits en el bus de direcciones que le permiten alcanzar 64 KB de espacio de memoria (2n = 216 = 64KB).
El µP Z80 se encuentra encapsulado en formato de 40 terminales, como queda representado en la Figura 1.7,
cuyas funciones son:
A0-A15 es el bus de direcciones, compuesto de 16 bits para alcanzar los 64 Kbytes de espacio de
memoria.
D0-D7 es el bus de datos compuesto de ocho bits, por donde fluyen los datos en ambos sentidos desde
el µP al exterior de este.
WR (Memory Write): este terminal se usa para indicar al exterior la operación de escritura.
RD (Memory Read), este terminal se usa para indicar al exterior la operación de lectura.
MREQ (Mernory Request): indica al exterior que la dirección del bus de direcciones es válida para leer
o escribir (en memoria).
M1 (Machine Cycle One), por este terminal el P indica al exterior el primer tiempo de ejecución de una
2
Se denomina microprocesador al circuito electrónico que procesa la energía necesaria para que el dispositivo electrónico en que
se encuentra funcione, ejecutando los comandos y los programas adecuadamente. La Unidad Central de Procesos (CPU) de una
computadora es un ejemplo de un microprocesador.
El µP Z80 está formado por la unidad de control (UC), la unidad aritmética y lógica (UAL) y por otros
registros específicos. A continuación se realizará una breve descripción:
Unidad de control (UC)
La UC cumple la función de secuenciar las operaciones que debe realizar el sistema. Los componentes de la
Unidad de Control son el decodificador, el reloj y el secuenciador (controlador). El decodificador envía
señales al secuenciador y determina la ejecución de la instrucción.
Además la UC necesita comunicarse con la memoria y los periféricos. Esta comunicación la realiza a través
de buses externos. El µP Z80 posee tres buses:
Bus de datos bidireccional de 8 bits empleado para transmitir datos desde o hacia la memoria y la CPU,
o entre la CPU y un periférico.
Bus de direcciones unidireccional de 16 bits para transmitir las direcciones de las posiciones de memoria
y de los dispositivos conectados al bus.
Bus de control unidireccional para trasmitir las señales de sincronización que dirigen el funcionamiento
de la computadora.
También hay registro asociada a la UC:
Registro de instrucción: su finalidad es almacenar la instrucción que es captada por la CPU durante una
operación de lectura y posteriormente será decodificada y ejecutada.
Registro Contador de Programa (CP): Para buscar la instrucción que debe ser ejecutada a continuación,
la UC tiene un registro de propósito especial que es el contador de programa. Es un registro de 16 bits
que contiene la dirección de la instrucción que actualmente está siendo buscada en la memoria. Al
finalizar la ejecución de una instrucción, el CP contiene la dirección de la primera palabra de la siguiente
instrucción a ejecutar.
Unidad aritmética y lógica (UAL)
La UAL cumple la función de realizar las operaciones aritméticas y lógicas. La configuración de está
responde a una máquina de una dirección y tiene asociados los registros acumulador (A) y el registro de
estado (Flags o F); estos registros se explicarán en detalle más adelante.
Otros registros
Registro de Direcciones: Este registro almacena las direcciones de las celdas de memoria que van a ser
accedidas para realizar una lectura/escritura. Está conectado directamente al bus de direcciones.
Registro de Palabra o registro de datos: Este registro es el encargado de almacenar la información (datos
o instrucciones) que se intercambian con la memoria a través del bus de datos.
Control de interrupciones: recepción reconocimiento de interrupciones por parte del microprocesador.
Registros internos
El µP Z80 cuenta con registros de uso general (disponibles para el usuario para propósitos generales dentro
del programa) y de uso dedicado, que también son empleados por el programa pero con una finalidad
específica. La Figura 1.9 siguiente muestra un esquema de los principales registros.
Registro de Estado o Flags (registro F): Es un registro de 8 bits que al igual que A tiene una imagen, F’.
Su función es la de brindar información respecto del resultado de la ejecución de una instrucción, que
puede ser consultada por el programador por medio de las instrucciones correspondientes.
Dicha información es representada a través de seis de los ocho bits con que cuenta, indicando cada uno
de ellos una condición distinta, de acuerdo a su valor (0-1). En la Figura 1.10 se muestra el significado
de los bits de este registro.
Registro R: Denominado Memory Refresh Register, es también de 8 bits y puede ser usado para acceder
a memorias dinámicas. El contenido de este registro es automáticamente increm entado después de cada
instrucción de búsqueda. Estos ocho bits pueden salir al exterior de P por la parte baja del bus de
direcciones para refrescar continuamente la memoria RAM dinámica a la que se desea acceder.
Los registros I y R no son utilizados por el programador.
Interrupciones
El P Z80 tiene dos entradas de interrupción: la entrada de interrupción no enmascarable NMI y la entrada
de interrupción enmascarable INT.
La interrupción NMI, cuando se haya producido, no puede ser desactivada por programa y será aceptada
siempre que un periférico la solicite. Esta interrupción será, generalmente, reservada para las funciones
más importantes que necesariamente tengan que ser atendidas en el momento de producirse, tal como un
fallo de alimentación, etc.
La interrupción enmascarable INT puede ser permitida o no, según las necesidades, por el programa.
Esto permite al programador no preocuparse de las interrupciones en zonas de su programa que no
requieran de interrupciones. Por supuesto que algún periférico conectado al terminal INT podrá pedir
interrupción en cualquier momento; pero ésta no será atendido si previamente el programa ha bloqueado
la posibilidad de acceso. La petición de interrupción podrá ser atendida siempre que por programa sea
permitida de nuevo. En el interior del propio P existe un biestable denominado IFF que puede ser
alterado por programa usando la instrucción EI (Enable Interrupt) para ponerlo a uno, permitiendo las
interrupciones, y la instrucción DI (Disable Interrupt) para ponerle a cero, bloqueando así la entrada de
interrupciones.
1.2.3. Modos de direccionamiento del P Z80
Los modos de direccionamiento conciernen a todos los medios puestos a disposición del procesador para
acceder a los datos a partir de los operandos de una instrucción. El P accede siempre a la memoria central
generando una dirección: no hay pues nada nuevo a este respecto. Sin embargo, los operandos de una
instrucción no tienen por qué ser una dirección real, sino un número, un indicativo a partir del cual el
procesador calcula la dirección real de la celda de memoria donde se encuentra el dato a tratar.
El P Z80 dispone de ocho modos de direccionamiento; para la descripción de cada uno de ellos se emplearán
instrucciones del repertorio de instrucciones del Z80:
Direccionamiento implícito
El nombre de este direccionamiento se debe a que la instrucción no contiene la dirección del operando .
Algunos ejemplos de este direccionamiento son:
INC HL: Incrementa en 1 el contenido del registro H.
DEC B : Decremento en 1 el registro B y actualiza los indicadores del registro F.
ADD A, B: Suma al acumulador (A) el contenido del registro B.
ADD A, (IX+01h): Suma al Acumulador lo apuntado en la celda de memoria (IX+01h). El resultado
queda en A.
Direccionamiento extendido
Es un direccionamiento muy sencillo, ya que el operando es la dirección real de la celda de memoria
afectada. Se designa con la palabra “extendido” para indicar que este modo de direccionamiento permite
acceder a la totalidad del espacio de memoria. El operando es una palabra de 16 bits.
Algunos ejemplos de este direccionamiento son:
LD A, (C745h): Cargar en el registro A el contenido de la celda de memoria cuya dirección es C745h.
LD (C745h), A: Cargar en el contenido de la celda de memoria: C745h el contenido de A.
Direccionamiento a través de registro
Este modo de direccionamiento está reservado para las operaciones internas del procesador que no
necesitan ningún acceso a memoria principal.
Algunos ejemplos de este direccionamiento son:
LD B, D: Cargar en el registro B el contenido del registro D.
LD A, C: Cargar en el registro A el contenido del registro C.
Direccionamiento indirecto a través de registro
Este modo de direccionamiento no necesita operando. La dirección de la celda de memoria es el
contenido de uno de los pares de registros del Z80: HL, DE o BC. Al estar codificada la dirección en 16
bits, se puede acceder a la totalidad del espacio de memoria. Este modo de direccionamiento es muy útil
para pasar parámetros a las subrutinas.
Algunos ejemplos de este direccionamiento son:
LD A, (DE): Cargar en A el contenido de la celda de memoria cuya dirección está en el registro DE.
LD (HL), A: Cargar en la celda de memoria cuya dirección está en el registro HL el contenido A.
Direccionamiento indexado o relativo a una base
En este modo de direccionamiento el operando es un octeto con signo (-128 a 127)3. El P calcula la
dirección real mediante la suma del operando llamado desplazamiento más el contenido de uno de los
registros índice (IX o IY).
Algunos ejemplos de este direccionamiento son:
LD A, (IX+01h): Cargar en el acumulador el contenido de la celda de memoria apuntada por el registro
IX más el desplazamiento; es decir una posición más.
LD A, (IY+FF h): Cargar en el acumulador el contenido de la celda de memoria apuntada por el registro
IY más el desplazamiento; en este caso una posición menos (debido a que FF representa -1 en C2).
Direccionamiento relativo al PC
En este caso el operando es un desplazamiento (octeto consigo). Este modo de direccionamiento sólo es
utilizado por el PC y permite efectuar bifurcaciones modificando su valor. El procesador realiza la
operación PC = PC +/- desplazamiento. La bifurcación relativa al PC resulta interesante porque es
independiente del lugar de la memoria central en el que se cargue el programa.
Algunos ejemplos de este direccionamiento son:
JR -30d: La instrucción indica volver 30 octetos hacia atrás.
Direccionamiento a través de la página cero
Este modo de direccionamiento es utilizado por el Z80 para una llamada especial a rutinas RESTART.
Esta instrucción fuerza en el PC una dirección de la página cero (los bits de mayor peso se ponen en
cero). El Z80 tiene 8 restarts diferentes bifurcando a rutinas que empiezan en las direcciones 0, 8H, 10,
18H, 28H, 30H, 38H.
Las instrucciones: CALL 10 H (llamada a subrutina) y RST 10H (RESTART).
Son totalmente equivalentes, aunque el CALL y su operando se codifiquen en 3 bytes mientras que el
RST sólo necesite uno.
El RESTART es utilizado para rutinas llamadas con mucha frecuencia debido a la rapidez que
proporciona. Hay que observar que el empleo de esta instrucción está reservado a menudo para el SO y
corresponde a determinadas rutinas ROM. Su utilización no resulta cómoda y no es aconsejable para
principiantes.
3
Rango de representación en C2 cuando n=8bits.
Figura 1.11:
Implementación de la pila.
4
Ver en sección: Repertorio de Instrucciones del lenguaje ensamblador del µZ80, las instrucciones PUSH y POP.
Observe que la lectura no afecta a los valores guardados en la pila. Sólo queda modificado el SP.
La pila se utiliza para la llamada a las rutinas. La manipulación de la memoria pila se consigue a través de
las instrucciones de lenguaje de máquina CALL nn y RET 5. Cuando el procesador encuentra un CALL nn
bifurca a la dirección nn y continúa hasta que encuentra una dirección RET. En ese momento hay que volver
a la instrucción siguiente a la del llamado (nn+1). Esto significa que el procesador ha conservado en algún
sitio esta dirección; este sitio es la pila. El funcionamiento de la pila permite anidar las rutinas de forma casi
ilimitada. En efecto, la última dirección de retorno apilada corresponde al primer RET encontrado (esquema
LIFO). En la Figura 1.12 se muestran implementación de la pila con anidamiento:
Por lo tanto, cada línea del programa representa una instrucción o una directiva. De esta manera las
instrucciones del programa tienen una estructura bien definida. Dicha estructura está compuesta por 4 zonas
bien definidas llamadas campos, como se muestra en la Figura 1.13.
Figura 1.13: Campos o Zonas del programa fuente escrito en lenguaje ensamblador.
5
Ver en sección: Repertorio de Instrucciones del lenguaje ensamblador del µZ80, las instrucciones CALL y RET.
Como en las instrucciones de 8 bits, en las de 16 bits también corresponden las instrucciones de carga:
LOAD (LD); cuya estructura es la siguiente:
Cargar registro de 16 bits: memoria registro
Almacenar registro de 16 bits: registro memoria
Transferir: registro registro
También podemos aclarar que el origen y el destino en las instrucciones están definidos por uno de los
modos de direccionamiento permitidos.
A continuación se muestran algunos ejemplos de esta instrucción:
LD IX, DE24 h ; Cargar el registro IX con la posición de memoria DE24 en hexadecimal.
LD BC, (3CF7 h) ; Almacena en el registro B el dato A4 h y en el registro C el dato 40 h (observación 1).
LD SP, HL ; Transfiere el contenido del registro HL al contenido del registro SP (observación 2).
Observaciones:
1. En este ejemplo se carga en B el dato A4 h que se obtiene de la dirección 3CF7 h; y de la posición de
memoria siguiente 3CF8 h se carga el dato 40 h en el registro C. El modo de direccionamiento de este
ejemplo es direccionamiento extendido.
40 3CF7 h B A4 h 40 h C
A4 3CF8 h
2. En el caso de la transferencia entre registros de 16 bits, solo está permitido cargar el registro SP con los
registros HL, IX o IX.
Instrucciones aritméticas y lógicas
Estas instrucciones se usan para sumar, restar, comparar, AND, OR o XOR entre operandos de 8 bits,
donde uno de los operandos es el registro acumulador. En este grupo también encontramos la suma y la
resta con acarreo que son útiles para operar con números de más de 8 bits. Solo se explicaran las
instrucciones aritméticas.
Instrucciones aritméticas (Sumar - Restar - Incrementar - Decrementar - Comparación)
o ADD A, B ; Sumar al acumulador con el contenido de B.
o SUB A, D ; Restar al acumulador el contenido de D.
y las de incremento o decremento
o INC C ; Incremento en 1 el contenido del registro D (observación 2).
o DEC B ; Decremento en 1 el contenido del registro B (observación 2).
Las instrucciones aritméticas actualizan los indicadores (bits o flags) del registro de estados del µP.
Otra instrucción aritmética muy usada es la instrucción CP (Comparación):
CP operando de 8 bits
La operación que se realiza es un resta: acumulador – operando; pero NO modifica el contenido del
registro acumulador. Está instrucción se usa para SETEAR o ASIGNAR valores a los bits del registro
de estado; es una instrucción muy práctica para testear condiciones en las instrucciones de salto.
Por ejemplo: Si el Acumular tiene el valor 20; entonces CP 0 realizará la operación 20 - 0 = 20; NO
modifica el contenido del acumulador pero SI actualiza los indicadores del registro F (uno de los bits
actualizado es el bit S; S=0 por ser el resultado de la operación positiva).
Observaciones:
3. En el caso del incremento o decremento con registros de 16 bits (por ejemplo: INC BC o DEC HL) NO
se actualizan los indicadores del registro F.
Instrucciones de ruptura de secuencia
En la secuencia de instrucciones de un programa se pueden tomar decisiones y trasladar el control a un
nuevo conjunto de instrucciones. A este grupo de instrucciones los podemos dividir en 2 grupos:
Instrucciones de Salto sin retorno
Los saltos sin retorno trasladan el control a otra dirección de memoria y no retornan al programa
principal. Estos saltos causan la transferencia del control a otra posición de memoria y no guardan el
contenido anterior del PC. Estás pueden ser un salto sin retorno incondicional o condicional:
o Salto sin retorno incondicional: producen el salto sin ninguna condición:
JP nn o JP etiqueta.
o Salto sin retorno condicional: estos saltos establecen las condiciones sobre los indicadores del
registro de estado para decidir si el salto se va a realizar. Estas condiciones pueden ser:
JP C, mn o JP C, etiqueta: bit de acarreo es C=1.
JP NC, mn o JP NC, etiqueta: bit de acarreo es C=0.
JP Z, mn o JP Z, etiqueta: bit Z es Z=1; Z=1 si la última operación realizada dio CERO.
JP NZ, mn o JP NZ, etiqueta: bit Z=0; Z=0 si la última operación realizada dio ≠ CERO.
JP M, mn o JP M, etiqueta: bit S=1 si la última operación realizada dio un NEGATIVO.
JP P, mn o JP P, etiqueta: bit S=0 si la última operación realizada dio un POSITIVO.
JP PO, mn o JP PO, etiqueta: P/V=0; es decir PARIDAD IMPAR o No hay OVERFLOW.
JP PE, mn o JP PE, etiqueta: P/V=1; es decir PARIDAD PAR o Si hay OVERFLOW.
Otra instrucción de salto sin retorno muy usada es la instrucción: DJNZ mn o DJNZ, etiqueta.
Esta instrucción decrementa el registro B y si el resultado es cero salta a mn o a etiqueta, caso contrario
no salta y continua con la próxima instrucción.
Instrucciones de Salto con retorno:
Los saltos con retorno trasladan el control del programa a otra dirección de memoria y luego retornan
al programa que lo invoco. Estás instrucciones se usan para llamar a una subrutinas y retornar de ellas
como se muestra en la Figura 1.14. Las subrutinas son segmentos de programas que se utilizan de forma
recurrente, y con el fin de evitar tener que escribirlas una y otra vez se escribe una sola vez. Cuando es
necesario utilizarla simplemente se la llama desde el programa principal, se ejecuta la subrutina y al
finalizar continúa el programa principal. Si el programa principal requiere intercalar una subrutina la
invoca con la instrucción CALL y para retornar de la subrutina lo realiza con la instrucción RET. Una
vez retornado al programa principal la ejecución continúa a partir de la instrucción ubicada después del
CALL.
Los llamados a las subrutinas realizan la misma acción que las instrucciones JUMP, con la diferencia
que salvaguardan el PC; es decir, recuerdan desde dónde se dio el salto y esto lo hacen almacenando la
dirección de retorno en la memoria pila; luego, en la subrutina, la instrucción de retorno hace que el
registro PC rescate de la pila dicha dirección de retorno.
El µP Z80 emplea para gestionar las llamadas y retornos de las subrutinas las instrucciones PUSH
(apilar) y POP (desapilar) que introducen y extraen datos respectivamente de la memoria pila
administrada por el SP (puntero a pila).
Bibliografía