Sie sind auf Seite 1von 57

ANTOLOGIA

“MICROPROCESADORES”

Compilador: Ing. Juan Carlos González


UNIDAD I

1. Introducción al microprocesador y a la computadora

1.1 La computadora personal basada en microprocesadores

Como parte del principio básico del conocimiento de todo estudiante informático, es
fundamental tener el conocimiento de la historia de las computadoras, ya que en ella se aprecia la
evolución de las unidades de procesamiento de la información.

A continuación se enumeran las generaciones de la computadora, así como sus características


principales, que pueden variar de uno a otro autor:

1. Primera generación abarca de 1946-1957, valvulas de vacío como característica principal.


2. Segunda generación abarca de 1958-1963, transistores como característica.
3. Tercera generación abarca de 1964-1971, circuitos integrados la característica principal.
4. Cuarta generación abarca de 1972-1980, microprocesadores como característica principal
para el procesamiento de datos.
5. Quinta generación abarca de 1981 a la fecha, VLSI característica de procesamiento.

Es a partir de la cuarta generación en donde comenzamos con lo que nos compete:


Microprocesadores.

Cuarta generación1

El nacimiento de las microcomputadoras tuvo lugar en los Estados Unidos, a partir de la


comercialización de los primeros microprocesadores (Intel 8008,8080) a comienzos de la década de
1970.

Durante la década de 1970 se impusieron dos tendencias: la de los sistemas Apple, y después
comenzó la verdadera explosión comercial masiva, con la introducción, en 1981, de la Personal
Computer (PC) de IBM.

Esta maquina (basada en microprocesador Intel 8088) tenia características interesantes, sobre
todo porque su nuevo sistema operativo estandarizado (MS-DOS, Microsoft Disk Operating System)
tenía una capacidad mejorada de graficacion, la hacían más atractiva y más fácil de usar.

1
http://www.pchardware.org/historia/cuarta.php
Existe una familia completa de sistemas de computadoras personales, que se conocen con las
nomenclaturas XT, AT y PS/2.

1971 Microprocesador Intel 8008. Circuito de alta integración que luego daría inicio a las
microcomputadoras.
1975 Aparece la microcomputadora Apple. Aparece el microprocesador Zilog Z80. Inicia el
auge de la microcomputación.
1981 IBM lanza la computadora personal, luego conocida como PC-XT
1984 IBM ofrece la computadora personal PC-AT, basada en el microprocesador Intel 80286.
1988 IBM presenta la serie de computadoras personales PS/2, algunas de las cuales emplean
el microprocesador 80386. Surge una gran cantidad de computadoras con ese y otros procesadores
similares.
1991 Microprocesador de muy alto rendimiento: Intel 80486, Motorola 68040, Sparc, tecnología
RISC, etc. Microprocesador Power PC (Performace Optimization With Enhanced RISC PC) resultado
de alianza de Apple, IBM y Motorola.
1993 Intel lanza al mercado el procesador 80586 conocido como Pentium.

En la actualidad los circuitos integrados son capaces de contener secciones completas de la


computadora, o a veces la computadora en su totalidad (excluyendo los medios de almacenamiento y
comunicación).

En las
computadoras actuales el
criterio de las ayudas
para la comunicación
sigue siendo básicamente
el mismo que en la
tercera generación. Claro
que ha habido mejoras
importantes. Pero no
podríamos considerar que
justifica un cambio de
denominación a una
nueva generación.
1.2 Sistemas numéricos

Los sistemas numéricos son una importante pieza en la informática, debido a que el lenguaje
binario tiene una función imprescindible, así como el sistema hexadecimal. Por ello mencionaré solo
éstos dos sistemas numéricos en esta redacción.

Además del sistema decimal existen otras bases de notación posicional que son empleadas en
los sistemas digitales como:
● Binario o base 2 que consta de solo dos símbolos 0 y 1.
● Octal o base 8 consta de ocho símbolos (0, 1, 2, 3, 4, 5, 6, 7) y es una representación corta
del binario y por ejemplo 111101110​(2) = 756​(8)​. Para las máquinas es mas fácil trabajar con
unos y ceros que representarían voltaje o no voltaje mientras que para nosotros es mas
cómodo decir solo 756 en lugar de todo el número binario.
● Hexadecimal o base 16 consta de 16 símbolos (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F), es
la representación corta más usada del binario y Ejemplo 111101111010​(2)​ = F7A​(16)​.

1.3 Formato de datos de la computadora2

Los datos por lo general son una mezcla de tipos. Se utiliza una representación Uniforme de
todos los tipos de datos. Los datos de entrada a una computadora se transforman en la
representación uniforme al ser utilizados y almacenados por la PC. A esta representación uniforme o
formato universal se le llama PATRÓN DE BITS.

Un bit es la unidad más pequeña de datos que puede almacenarse en una computadora;
puede ser ya sea 0 o 1 (cero o uno). Un bit representa el estado de un dispositivo que puede tomar
uno de dos estados. Por ejemplo un interruptor eléctrico. Actualmente las computadoras utilizan
varios dispositivos binarios de dos estados para almacenar datos.

Un patrón de bits con una longitud de 8 se llama BYTE. Este término es también utilizado para
medir el tamaño de la memoria o de otros dispositivos de almacenamiento.

Los datos pueden ser representados en diversas formas, y todas ellas las agrupamos en bytes.

2
https://www.uv.mx/personal/llopez/files/2011/09/Herencia-de-Ciencias.pdf
UNIDAD II

2. El microprocesador y su arquitectura

2.1 Arquitectura interna3

Llamamos arquitectura interna del microprocesador a la distribución física de sus componentes.


Los primeros microprocesadores se crearon de acuerdo a la arquitectura de Von Neumann.

En 1965 Gordon Moore predijo que el número de transistores que incorpora un


microprocesador se duplicaría cada 18/24 meses. A dicha afirmación se le conoce como Ley de
Moore y prácticamente se ha cumplido hasta nuestros días.

Procesadores mononúcleo Procesadores Multinúcleo

Elementos de un microprocesador
● Unidad de control. Busca las instrucciones en memoria principal y las pasa al decodificador
para ejecutarlas.

3
dit.gonzalonazareno.org/moodle/mod/resource/view.php?id=1761
● Decodificador de instrucciones. Interpreta y ejecuta las instrucciones.
● Unidad aritmético-lógica (ALU). También llamado coprocesador matemático. Se encarga de
realizar las operaciones aritméticas (suma, resta, ...) y lógicas (AND,OR, ...) con números
enteros.
● Unidad de coma flotante (FPU). Realiza las operaciones de coma flotante (números reales).
● Memoria caché. Es una memoria volátil que se utiliza para acelerar los accesos del
procesador a la memoria principal.
● Bus frontal (Front Side Bus, FSB). También conocido como bus principal o bus de sistema.
Es el canal que comunica el procesador con la placa base (northbridge). En los procesadores
actuales recibe nombres como Quick Path Interconnect (Intel) o Hypertransport (AMD).
Aunque los fabricantes lo llamen de distinta forma se trata del mismo bus → Bus de sistema,
es decir, conecta el procesador y el northbridge.
● Bus trasero (Back Side Bus, BSB). Es el nombre que se daba al canal de comunicación entre
el procesador y la memoria caché L2 cuando ésta no estaba integrada en el núcleo.

2.2 Direccionamiento de memoria en tiempo real4

El modo real (también llamado modo de dirección real en los manuales de Intel) es un modo de
operación del 80286 y posteriores CPUs compatibles de la arquitectura x86. El modo real está
caracterizado por 20 bits de espacio de direcciones segmentado (significando que solamente se
puede direccionar 1 MB de memoria), acceso directo del software a las rutinas del BIOS y el
hardware periférico, y no tiene conceptos de protección de memoria o multitarea a nivel de hardware.
Todos los CPUs x86 de las series del 80286 y posteriores empiezan en modo real al encenderse el
computador; los CPUs 80186 y anteriores tenían solo un modo operacional, que era equivalente al
modo real en chips posteriores. Puesto que una especificación de diseño primaria de los
microprocesadores x86 es que sean completamente compatibles hacia atrás con el software escrito
para todos los chips x86 antes de ellos, el chip 286 fue hecho para iniciarse en ‘ modo real ‘ – es
decir, en un modo que tenía apagadas las nuevas características de protección de memoria, de
modo que pudieran correr sistemas operativos escritos para microprocesadores más viejos. Al día de
hoy, incluso los más recientes CPUs x86 se inician en modo real al encenderse, y pueden correr el
software escrito para cualquier chip anterior.Bajo el modo real no existe ningún mecanismo para
tener varias tareas ejecutándose concurrentemente, aunque si se pueden tener varios programas
cargados en memoria al mismo tiempo, pero inactivos.

En el modo real se puede lograr un pequeño grado de multitarea si interceptamos algunos de


los vectores de interrupción que se ejecutan periódicamente, como el temporizador, e insertamos una

4
https://quice85.wordpress.com/asignaturas-impartidas/arquitectura-de-computadoras-i/
rutina de usuario bajo esa interrupción. Como puede verse, este tipo de multitarea no tiene ni punto
de comparación con la que ofrece el modo protegido del 80386.En el modo real no se puede
controlar que un programa, por ejemplo, no pueda acceder a una zona específica de memoria. Un
programa en modo real puede acceder a cualquier dirección de memoria direccionable por el
procesador, con lo que un programa maligno puede modificar estructuras del sistema operativo o
redireccionar vectores de interrupción y tener un control total sobre el sistema.Debido a esta escasa
protección que se ofrece en el modo real, aparecen los temibles virus informáticos y otros programas
malignos. Tras conocer el modo protegido y haber trabajado con él, me atrevo a afirmar que es
imposible realizar un virus para un sistema operativo que trabaje en modo protegido, siempre y
cuando ese sistema operativo no deje ninguna puerta de entrada libre al usuario para controlar el
sistema.Todas las interrupciones hardware y software son controladas por el procesador en el modo
real leyendo de una tabla de interrupciones que se encuentran en las primeras posiciones de
memoria física. Cuando se produce una interrupción, se lee de la tabla anterior la dirección donde
encontrar su rutina de tratamiento. Como cualquier programa puede acceder a cualquier dirección de
memoria, puede manipular este área de memoria e interceptar diversos vectores de interrupción y
apuntarlas a rutinas propias, con lo que cualquier programa puede controlar el sistema según desee.

2.3 Introducción al direccionamiento de memoria en modo protegido5

El direccionamiento de memoria en modo protegido (a partir del 80286 y posteriores) permite


acceder a datos y programas localizados por encima y dentro del primer megabyte de memoria. Para
direccionar esta sección extendida el sistema de memoria se requiere un cambio en el esquema de
direccionamiento de segmento más desplazamiento usado en el modo real. Cuando los datos y
programa se direccionan la memoria extendida, se sigue utilizando la dirección de desplazamiento
para acceder a la información en el segmento de memoria. Una diferencia consiste en la dirección del
segmento ya que no existe en modo protegido. En lugar de una dirección de segmento, el registro de
segmento contiene un SELECTOR que elige un descriptor de una tabla.El descriptor especifica la
ubicación del segmento en memoria, su longitud y sus derechos de acceso. Dado que el registro de
segmento y la dirección de desplazamiento aún acceden a la memoria, las instrucciones del modo
protegido son idénticas a las de modo real. De hecho, la mayoría de los programas escritos para
funcionar en modo real funcionarán sin cambios en el modo protegido.La diferencia entre los dos
modos es la forma en que el microprocesador interpreta el registro de segmento para acceder al
segmento de memoria. Otra diferencia, en los 80386 y posteriores, es que en modo protegido la
dirección de desplazamiento puede ser un número de 32 bits en vez de utilizar uno de 16 bits como
en modo real. Es por esto que puede direccionar hasta 4 Gb de longitud.

5
https://quice85.wordpress.com/asignaturas-impartidas/arquitectura-de-computadoras-i/
El SELECTOR, ubicado en el registro del segmento, elige uno de 8192 descriptores en una de
las dos tablas de descriptores. El DESCRIPTOR especifica la ubicación, la longitud y los derechos de
acceso del segmento de memoria, aunque no directamente como en el modo real. Por ejemplo, en el
modo real, si CS=0008H, el segmento de código inicia en la localidad 00080H. En modo protegido,
este número de segmento puede direccionar cualquier localidad de memoria en todo el sistema para
el segmento de código.Existen dos tablas de descriptores utilizadas con los registros de segmentos:
una contiene descriptores globales y otra, descriptores locales. Los descriptores globales contienen
las definiciones de los segmentos que se aplican a todos los programas, mientras que los
descriptores locales son generalmente exclusivos de una aplicación. Podríamos llamar descriptor de
sistema a un descriptor global, y descriptor de aplicación a uno local. Cada tabla de descriptores
contendrá 8192 entradas, por lo tanto una aplicación podría disponer en cualquier momento de
16.384 descriptores. Puesto que un descriptor describe un segmento de memoria, esto permite que
puedan ser descriptos hasta 16.384 segmentos de una aplicación.

2.4 Paginación de memoria6

La paginación es uno de los esquemas de manejo de memoria en donde un computador puede


almacenar y recuperar datos de un dispositivo de almacenamiento secundario para su uso en la
memoria principal. En el esquema de manejo de memoria de paginación, el sistema operativo
recupera datos desde un dispositivo de almacenamiento secundario en bloques de un mismo tamaño
llamados páginas. La principal ventaja de paginación sobre la segmentación de memoria es que
permite al espacio de dirección física de un proceso ser no contiguo. Antes de la paginación, los
sistemas debían poner programas en almacenamiento de forma contigua, lo que causaba varios
problemas de almacenamiento y fragmentación.

El método básico para implementar paginación


consiste en dividir la memoria física en bloques de
tamaño fijo llamados frames (marcos) y dividir la memoria
lógica en bloques de mismo tamaño llamados pages
(páginas). Cuando un proceso se va a ejecutar, sus
páginas son cargadas en cualquier marco de la memoria
de almacenamiento secundario. Este esta dividido en
bloques de tamaño fijo del mismo tamaño de los marcos
en memoria.

6
http://wiki.inf.utfsm.cl/index.php?title=Paginaci%C3%B3n
Hardware de paginación

El tamaño de página (como el marco de


página) es definido por hardware. El tamaño de
una pagina es típicamente una potencia de 2,
variando entre 512 B y 16 MB por pagina,
dependiendo de la arquitectura del
computador. La selección de una potencia de 2
como tamaño de página hace la traducción de
una dirección lógica a un número de página y
offset de página algo fácil. Si el tamaño del
espacio de dirección lógica es 2^m y el tamaño
de página 2^n unidades de dirección (bytes o
palabras), entonces los m-n bits de mayor orden de la dirección lógica designan el número de página,
y los n bits de menor orden designan el offset de página.

Cualquier dirección generada por la CPU es divida en dos partes: un número de página (p) y
un offset de página (d). El número de página es usado como índice en una tabla de página. La tabla
de página contiene las direcciones base de cada página en la memoria física. Esta dirección base es
combinada con el offset de página para definir la dirección de memoria física que es enviada a la
unidad de memoria.

Bueno, ya hemos revisado el concepto de paginación y como funciona, En esta sección


explicaremos como se implementa, y es en este punto en donde debemos mencionar a "la Tabla de
Página". La tabla de página es una Estructura de datos usada por el sistema de memoria virtual, en
un sistema operativo para almacenar la relación entre una dirección virtual en la memoria y la
direcciones físicas. Veamos dicha explicación en una imágen:
UNIDAD III

3. Modos de direccionamiento

3.1 Modo de direccionamiento de datos7

Se les llama modos de direccionamiento a las distintas formas de combinar los operandos
según el acceso que se hace a memoria. Dicho de otra manera, un modo de direccionamiento será
una forma de parámetro para las instrucciones. Una instrucción que lleve un parámetro, por lo tanto,
usará un modo de direccionamiento, que dependerá de cómo direccionará (accesará) al parámetro;
una instrucción de dos parámetros, combinará dos modos de direccionamiento.

Direccionamiento implícito
Depende solamente de la instrucción, es decir, la instrucción no lleva parámetros.
Particularmente en instrucciones que no accesan memoria, o bien que tienen una forma específica
de accesarla.
Ejemplos: PUSHF, POPF, NOP

Modo registro
Usa solamente registros como operandos. Es el más rápido, pues minimiza los recursos
necesarios (toda la información fluye dentro del EU del CPU)
Ejemplo: MOV AX, BX

Modo inmediato
Tiene dos operandos: un registro y una constante que se usa por su valor. El valor constante
no se tiene que buscar en memoria, pues ya se obtuvo al hacer el “fetch” de la instrucción.
Ejemplo: MOV AH, 9

Modo directo
Uno de los operandos involucra una localidad específica de memoria. El valor constante se
tiene que buscar en memoria, en la localidad especificada. Es más lento que los anteriores, pero es
el más rápido para ir a memoria, pues ya “sabe” la localidad, la toma de la instrucción y no la tiene
que calcular.
Ejemplo: MOV AH, [0000]
MOV AH, Variable

7
https://silvamondragon.wordpress.com/2010/11/29/4-2-3-modos-de-direccionamiento/
Estas dos instrucciones serían equivalentes, si Variable está, por ejemplo, en la localidad 0 de
memoria. En la forma primitiva del lenguaje de máquina, como el primer ejemplo, se tiene que indicar
“mover a AH el contenido (indicado por los corchetes), de la localidad 0 de los datos (lo de los datos
es implícito). El lenguaje Ensamblador, sin embargo, nos permite la abstracción del uso de variables,
pero como una variable tiene una localidad determinada en memoria, para el procesador funciona
igual. La única diferencia consiste en que el programador no tiene que preocuparse por la dirección,
ese manejo lo hace automáticamente el Ensamblador.

Modo indirecto
Se usan los registros SI, DI como apuntadores. El operando indica una localidad de memoria,
cuya dirección (sólo la parte desplazamiento) está en SI o DI. Es más lento que los anteriores, pues
tiene que “calcular” la localidad.
Ejemplos:MOV AL, [SI]
MOV BL, ES:[SI] ; Aquí se dice que se usa un “segment override”, donde se indica que en vez
de usar el segmento de datos por defecto, se use en su lugar como referencia el segmento extra.

Modo indexado de base


Formato: [BX o BP + SI o DI (opcionales) + constante (opcional)]
BX o BP indica una localidad base de la memoria

A partir de BX o BP, se puede tener un desplazamiento variable y uno constante. La diferencia


es el segmento sobre el que trabajan por defecto:
BX por defecto en el segmento de datos
BP por defecto en el segmento de pila.

Ejemplos:
MOV AX, [BX]
MOV DX, [BX+2]
MOV CX, [BX+DI]
MOV DL, [BX+SI+3]

3.2 Modos de direccionamiento de memoria de programa8

Los microcontroladores AVR RISC AT90S8515 soportan modos de direccionamiento


poderosos y eficaces para el acceso a la memoria de programa (FLASH) y memoria de datos
(SRAM, archivo de Registro y memoria de I/O). Esta sección describe los diferentes modos de

http://www.sc.ehu.es/sbweb/webcentro/automatica/web_avr/archivos/Manual_AT90S8515/Arquitectur
a/modos_direccionamiento.htm
direccionamiento soportados por la arquitectura AVR. En las figuras, OP es el código de
funcionamiento de la palabra (word) de la instrucción. Para simplificar, no todas las figuras muestran
la situación exacta de los bits de direccionamiento.

Registro Directo, Registro simple RD

Figura. Direccionamiento directo de registro simple


El operando está contenido en el registro d (Rd).

Registro Directo, dos registros Rd y Rr

Figura. Direccionamiento de registro directo, dos registros


Los operandos están contenidos en los registros r (Rr) y d (Rd). El resultado es almacenado en
el registro d (Rd).
I/O Directo

Figura. Direccionamiento directo de I/O


La dirección del operando está contenida en seis bits de la palabra (word) de la instrucción. n
es el destino o dirección de registro fuente.

Dato directo

Figura. Direccionamiento directo de datos


Una dirección de datos de 16 bit está contenida en los 16 LSBs de una instrucción de 2-word.
Rd/Rr especifican el destino o registro fuente.
Dato indirecto con desplazamiento

Figura. Dato indirecto con desplazamiento


La dirección del operando es el resultado del contenido de los registros Y o Z sumada a la
dirección contenida en seis bits de la palabra (word) de la instrucción.

Dato indirecto

Figura. Direccionamiento indirecto de datos


La dirección del operando es el contenido del registro X, Y o del Z.
Dato indirecto con pre-decremento

Figura. Direccionamiento indirecto de datos con pre-decremento


El registro X, Y o el Z es decrementado antes de la operación. La dirección del operando es el
contenido decrementado del registro X, Y o Z.

Dato indirecto con post-incremento

Figura. Direccionamiento indirecto de datos con post-incremento


El registro X, Y o el Z se incrementa después de la operación. La dirección del operando es el
contenido del registro X, Y o Z previo al incremento.
Direccionamiento de una Constante usando la Instrucción LPM

Figura. Direccionamiento de una constante de memoria código

La dirección del byte constante está especificada por el contenido del registro Z. Los 15 MSBs
seleccionan la dirección de la palabra (0 - 4K), el LSB selecciona el byte bajo si está borrado (LSB =
0) o el byte alto si está a set (LSB = 1).

3.3 Modos de direccionamiento de memoria de la pila9

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.

9
https://es.wikipedia.org/wiki/Modos_de_direccionamiento#De_pila
UNIDAD IV

4. Instrucciones para mover datos

4.1 Recapitulación de MOV

La instrucción MOV copia datos de un operando de origen a un operando de destino. Esta


instrucción, conocida como transferencia de datos, se utiliza en casi todos los programas. Su formato
básico muestra que el primero operando es el destino y el segundo es el origen:
MOV destino, origen

El contenido del operando de destino cambia, pero el del operando de origen no. El movimiento
de datos de derecha a izquierda es similar a la instrucción de asignación en C++ o Java:
destino = origen;

MOV es bastante flexible en el uso de sus operandos, siempre y cuando se observen las
siguientes reglas:

● Ambos operandos deben ser del mismo tamaño.


● Ambos operandos no pueden ser operandos de memoria.
● CS, EIP e IP no pueden ser operandos de destino.
● Un valor inmediato no puede moverse a un registro de segmento.

He aquí́ una lista de las variantes generales de MOV, excluyendo los registros de segmento:

● MOV reg,reg
● MOV mem,reg
● MOV reg,mem
● MOV mem,imm
● MOV reg,imm

4.2 Push/Pop

Una operación push de 32 bits decrementa el apuntador de la pila por 4 y copia un valor a la
ubicación en la pila a la que apunta el apuntador.
La pila en tiempo de ejecución siempre crece hacia abajo en la memoria, siguiendo el principio
de “ultimo en entrar, primero en salir”. Antes de la operación push, ESP 00001000h; después de
push, ESP 00000FFCh.

Una operación pop elimina un valor de la pila y lo copia a un registro o ubicación de memoria.
Después de sacar el valor de la pila, el apuntador de la pila se incrementa para apuntar a la siguiente
ubicación más alta en la pila.

La pila, después de meter 00000001 y 00000002.


Sacar un valor de la pila en tiempo de ejecución.

4.3 Dirección efectiva de carga

4.4 Transferencia de datos de cadenas

La operación de copiar datos de un lugar a otro es la operación más simple y a la vez


importante. Las instrucciones de transferencia de datos necesitan que se especifiquen el original
(fuente u origen) y el lugar donde se desea la copia (destino).

Esta especificación variará según sean estos lugares que pueden estar en tres sitios:
● registros del procesador
● memoria
● cima de pila.

Si el acceso es a una dirección de memoria habrá que especificarla de forma explícita, si se


trata de la cima de pila normalmente la especificación será implícita, lo mismo ocurrirá si se trata del
acumulador.
4.5 Instrucciones variadas de transferencia de datos

Por ejemplo, la instrucción POP saca un dato de la cima de pila modificando el valor del
apuntador de pila, lo que significa que, si bien no destruye físicamente el dato fuente, anula su
validez.

En general, el dato a transferir podríamos definirlo como una terna con las siguientes
componentes:
● Dirección
● Tipo
● Valor

Normalmente la componente del dato que se transfiere es el valor pero existen instrucciones
especiales para transferir las demás componentes, en especial la dirección. La extracción de la
dirección de un dato se hace necesaria para facilitar la relocalización de los programas.

4.6 Prefijo de sustitución de segmento

El Prefijo del Segmento de Programa (PSP) es una estructura de datos usada en el sistema
DOS para almacenar el estado de un programa, al cargar un programa.COM o.EXE esta estructura
es creada en el segmento 00H mientras que el programa mismo en el 100H.

El PSP contiene distintos campos con una posición asignada a cada uno:
4.7 Detalles acerca del ensamblador

Los lenguajes ensambladores a veces pueden ser portables a través de diferentes sistemas
operativos en el mismo tipo de CPU. Las convenciones de llamadas entre los sistemas operativos
con frecuencia difieren ligeramente o en nada. y con cuidado es posible ganar portabilidad en el
lenguaje ensamblador, usualmente al enlazar con una biblioteca de lenguaje C que no cambia entre
sistemas operativos. Un simulador de conjunto de instrucciones (que idealmente sería escrito en
lenguaje ensamblador) puede, en teoría, procesar el código objeto/binario de cualquier ensamblador)
para lograr la portabilidad incluso a través de plataformas (con una sobrecargue no mayor que la de
un interpretador de bytecode típico). Esto es esencialmente lo que logra el micro código cuando una
plataforma de hardware cambia internamente.
UNIDAD V

5. Instrucciones aritméticas y lógicas

5.1 Suma, resta y comparación10

El microprocesador dispone de una unidad aritmética-lógica que le permite realizar una serie
de operaciones, tanto aritméticas, como lógicas. Las aritméticas incluyen la suma y resta con o sin
acarreo, incremento y decremento de un registro, comparaciones, ajuste decimal, complemento y
negación. Las lógicas incluyen las operaciones que se realizan con los operadores "AND", "OR" y
"XOR".

Antes de adentrarnos en el estudio de las instrucciones concretas, daremos una serie de


definiciones útiles:

SUMA SIN ACARREO:


Consiste en sumar al contenido del registro "A" un número y obtener el resultado en el registro
"A". El indicador de acarreo no se tiene en cuenta para esta operación. Su esquema sería:
A ← A+n

SUMA CON ACARREO:


Exactamente igual que la anterior, pero se suma también el indicador de acarreo del registro
"F". De esta forma, sepuede incluir en la suma el acarreo procedente de una suma anterior. Su
esquema sería:
A ← A+n+CF

RESTA SIN ACARREO:


Consiste en restar un número del contenido del registro "A", y obtener el resultado en este
mismo registro. El indicador de acarreo no interviene en la operación. Se consideran números
negativos los superiores a 127 (7Fh) de la forma que se explicó en el capítulo relativo a los sistemas
de numeración; es decir, el número 255 (FFh) se considera "-1", el 254 (FEh) se considera "-2" y así
sucesivamente, hasta 128 (80h) que se considera "-128". El paso de 127 a 128 o viceversa se indica
poniendo a "1" el flag de "overflow" (P/V) del registro "F". Su esquema sería:
A ← A-n

10
http://curso-cm.speccy.org/fr_cap6.html
RESTA CON ACARREO:
Igual que el anterior, salvo que también se resta el indicador de acarreo (CF) del registro "F".
Su esquema sería:
A ← A-n-CF

INCREMENTO:
Consiste en sumar uno al contenido de un registro que se especifica en la instrucción. Su
esquema es:
R ← R+1

Donde "R" representa un registro cualquiera de 8 a 16 bits. Si se trata de un registro doble (de
16 bits) se incrementa el registro de orden bajo (por ejemplo, en el "BC" se incrementa "C"), y si ello
hace que este pase a valer "0", se incrementa también el de orden alto.

DECREMENTO:
Es la inversa de la anterior, consiste en restar uno al contenido de un registro. Su esquema es:
R ← R-1

Si se trata de un registro doble, se decrementa el de orden bajo y, si esto hace que pase a
valer 255 (FFh), se decrementa también el de orden alto.

Si el registro incrementado o decrementado es de 8 bits, resultan afectados los indicadores del


registro "F".

COMPARACIONES:
Estas instrucciones permiten comparar el contenido del acumulador con un número. Para ello,
se resta el número del contenido del acumulador, pero el resultado no se almacena en ninguna parte,
simplemente, se alteran determinados flags del registro "F", lo que nos indica si el número era menor,
igual o mayor que el contenido del acumulador. Si era igual, se pone a "1" el flag "Z" (indicador de
"cero"). Si el número era mayor, se pone a "1" el flag "S" (indicador de "signo").

AJUSTE DECIMAL:
Esta instrucción realiza un ajuste del contenido del acumulador para que, en vez de estar
comprendido entre "00h" y "FFh", lo esté entre "00h" y "99h". Si se produce acarreo, se indica
mediante el flag correspondiente. Para realizar esta operación se toma en cuenta el estado de los
indicadores de "acarreo" (C) y "semi-acarreo" (H). Su finalidad es la de permitir realizar operaciones
en "BCD" (Decimal Codificado en Binario).
COMPLEMENTO:
Consiste en realizar un "complemento a 1" del acumulador, es decir, cambiar los "unos" por
"ceros" y los "ceros" por "unos".

NEGACIÓN:
Consiste en realizar un "complemento a 2" del acumulador, es decir, realizar un "complemento
a 1" y, luego, sumarle "1". Lo que se obtiene es el "negativo" del número que teníamos en el
acumulador. El efecto es el mismo que si restáramos el acumulador de "cero", es decir:
A ← 0-A

EL FLAG DE ACARREO:
Existen dos instrucciones que afectan al indicador de acarreo del registro "F", es posible
ponerlo a "1" o "complementarlo" (ponerlo a "1" si era "0" y viceversa). No se ha previsto una
instrucción para poner a "0" el flag de acarreo, dado que esto se puede conseguir haciendo un "AND"
o un "OR" del acumulador consigo mismo.

5.2 Multiplicación y división11

Compuerta AND

La compuerta lógina AND puede ser llamada tambien compuerta "Y" ( i ). La salida será "1" si
las entradas A "Y" B están en "1".

Símbolo de la compuerta "AND":

Tabla de verdad de las compuertas "AND":

Entrada A Entrada B Salida

0 0 0

0 1 0

1 0 0

1 1 1

11
http://www.proyectoelectronico.com/compuertas-logicas/compuertas-logicas-and-nand.html
5.3 Aritmética BCD y ASCII12

La necesidad de representar más caracteres condujo a la IBM a desarrollar el sistema


EBCDIC; el cual se pronuncia “EB-si-dic”, significa Código de Intercambio de Decimales Codificados
en Binarios Extendidos (Extented Binary Coded Decimal Interchange Code).

El código EBCDIC es un código de ocho bits que define 256 símbolos. EBCDIC todavía se
emplea en mainframes y sistema de rango medio de IBM, pero rara vez se encuentra en
computadoras personales.

Para cuando se estaban desarrollando las computadoras pequeñas, el Instituto Nacional


Estadounidense de Normas (American Nacional Standars Institute:ANSI) había entrado en acción
para definir normas para computadoras.

Código EBCDIC

12
http://franck03.wixsite.com/arquitecturafranceli/343-aritmtica-con-bcd-y-ascii
ASCII. La solución de ANSI para representar símbolos con bits de datos fue el juego de
caracteres ASCII. ASCII significa Código Estándar Estadounidense para el Intercambio de
Información (American Standard Code for Information Interchange). Actualmente, el juego de
caracteres ASCII es el más común. Los caracteres del 0 al 31 son caracteres de control; del 32 al 64
son caracteres especiales y números; del 65 al 96 son letras mayúsculas y unos cuantos símbolos;
del 97 al 127, son letras minúsculas, y unos pocos símbolos comunes. Ya que el ASCII, un código de
siete bits, especifica caracteres sólo hasta 127, hay muchas variaciones que especifican diferentes
juegos de caracteres para los códigos del 128 al 255. La norma ISO (Organización Internacional de
Normas: International Standards Organization) expandió el juego de caracteres ASCII para ofrecer
diferentes juegos de caracteres para diferentes grupos de idiomas. ISO 8859-1, por ejemplo, cubre
los idiomas de Europa occidental. Sin embargo, hay muchos otros juegos de caracteres para otros
idiomas que usan un alfabeto diferente.

Con dos bytes, un carácter Unicode podría ser cualquiera de más de 65536 caracteres o
símbolos diferentes, suficiente para cada carácter y símbolo en el mundo, incluyendo los vastos
juegos de caracteres chinos, coreanos y japoneses y aquellos que se encuentran en textos clásicos e
históricos conocidos. Si un juego de caracteres único estuviera disponible para cubrir todos los
idiomas en el mundo entero, los programas y datos de computadora serían intercambiables. Debido a
que esto es ciertamente una meta que vale la pena, posiblemente un día se dé el esfuerzo conjunto
para reemplazar ASCII por Unicode. Muchos editores de software, incluyendo Microsoft , Netscape y
Accent, animan a sus desarrolladores a usar Unicode en sus programas.

Conocer el manejo de los caracteres ASCII para la presentación en pantalla de los resultados.
● Practicar el uso de ajustes para las operaciones aritméticas en modo decimal.
● 1 Computadora con el programa EMU8086.
5.4 Instrucciones lógicas básicas

Denotaremos la proposiciones simples como p, q, r, etc. y definiremos 4 operaciones básicas,


correspondientes a la negación "no", la conjunción "y", la disyunción "o" y la implicación ("") .

La negación: Dada una proposición p, su negación no(p) es aquella proposición que es falsa
cuando p es verdadera y, es verdadera cuando p es falsa.

La conjunción: Dadas las proposiciones p, q. La conjunción p y q es aquella proposición que


sólo es verdadera, cuando ambas son verdaderas. En cualquier otro caso es falsa.

La disyunción : Dadas las proposiciones p, q. La disyunción p o q es aquella proposición que


sólo es falsa, cuando ambas son falsas. En cualquier otro caso es verdadera.

La implicación : Dadas las proposiciones p, q. La implicación pq es aquella proposición que


sólo es falsa, cuando p es verdadera y q es falsa. En cualquier otro caso es verdadera.

5.5 Desplazamiento (shift) y desplazamiento cíclico (rotate)

Instrucción LSL, Logical Shift Left


Esta instrucción desplaza todos los bits de Rd un lugar a la izquierda. El bit 0 es borrado y el bit
7 es cargado en la bandera de carry del registro SREG. Esta operación es equivalente a multiplicar
por 2 valores con signo y sin signo.

Operación:

Instrucción LSR, Logical Shift Right


Esta instrucción desplaza todos los bits de Rd un lugar a la derecha. El bit 7 es borrado y el bit
0 es cargado en la bandera de carry del registro SREG. Esta operación es equivalente a dividir para
2 valores sin signo.

Operación:
Instrucción ROL, Rotate Left trough Carry
Esta instrucción desplaza todos los bits de Rd un lugar a la izquierda. La bandera del carry en
SREG pasa al bit 0 de Rd. El bit 7 desplazado a la bandera de carry del registro SREG. Esta
operación combinada con LSL es equivalente a multiplicar por 2 valores multi-byte con signo y sin
signo.

Operación:

Instrucción ROR, Rotate Right trough Carry


Esta instrucción desplaza todos los bits de Rd un lugar a la derecha. La bandera del carry en
SREG pasa al bit 7 de Rd. El bit 0 desplazado a la bandera de carry del registro SREG. Esta
operación combinada con LSR o ASR es equivalente a dividir pora 2 valores multi-byte sin signo y
con signo respectivamente.

Operación:

5.6 Comparaciones de cadenas13

Veamos distintas formas de comparar y de ordenar cadenas de texto en java, según lo que nos
interese en cada momento.

13
http://chuwiki.chuidiang.org/index.php?title=Comparar_cadenas_de_texto
Comparar con ==
En java se pueden comparar cadenas de texto de varias maneras. La primera y más directa, es
comparando con el ==. Esta comparación no compara las cadenas, sino si la instancia es la misma.
Así, por ejemplo:
String cadena1 = new String("Hola");
String cadena2 = new String("Hola");
if (cadena1 == cadena2)
{
...
}
da false, las cadenas no son iguales, ya que son dos instancias -dos news- distintos.

El compilador de java es listo y si hacemos


String cadena1 = "Hola";
String cadena2 = "Hola";
if (cadena1 == cadena2)
{
...
}
daría true, ya que el compilador ve que tiene dos veces la misma cadena y crea una única
instancia para ella -sólo hace internamente un new-.

Comparar con equals()


Para comparar realmente las cadenas y no si son o no la misma instancia, se usa el método
equals().
String cadena1 = new String("Hola");
String cadena2 = new String("Hola");
if (cadena1.equals(cadena2))
{
...
}
esto daría true siempre que ambas cadenas tengan el mismo texto dentro. Es posible hacer
cosas como esta:
String cadena2 = new String("Hola");
if ("Hola".equals(cadena2))
{
...
}
es decir, podemos usar directamente el método equals() sobre una cadena de texto literal, sin
necesidad de tener variable. Esto es útil para evitar comparar primero si la cadena es null antes de
llamar a equals(). Es decir, evita hacer esto:
String cadena2 = new String("Hola");
if (cadena2!=null)
if (cadena2.equals("Hola"))
{
...
}

Comparar sin importar mayúsculas (ignore case)


Para comparar dos cadenas sin importar si los caracteres están en mayúscula o minúscula, se
utiliza el método equalsIgnoreCase() de la clase String:
String a = "hola";
String b = "HOLA";

// son iguales
if (a.equalsIgnoreCase(b)) {
System.out.println("a y b son iguales");
}
UNIDAD VI

6. Instrucciones de control de programa

6.1 El grupo de saltos14

Se utilizan para realizar un salto, es decir, para transferir el control a un punto del programa donde
seguirá la ejecución del mismo, pero perdiendo toda posibilidad de retornar de forma controlada la
ejecución del programa al punto de llamada.

No se aconseja su utilización porque crean un código difícil de leer y mantener, estando su uso muy
restringido en programación estructurada.

Podemos hablar de dos tipos de sentencias de salto:


● Salto condicional: alteran la secuencia de ejecución de un programa sólo y exclusivamente
en el caso de que una condición específica sea cierta.
● Salto incondicional: alteran la secuencia de ejecución de un programa siempre al no ir
acompañadas de una condición de límite en determinadas ocasiones la realización del salto
a otra parte del programa

6.2 Control de flujo de programa

Alternativa simple
Se evalúa una condición, ejecutándose un grupo de sentencias si el resultado es “verdadero”, y
no ejecutándose este grupo de sentencias si el resultado es “falso”.

14
http://informatica.iesvalledeljerteplasencia.es/wordpress/instrucciones-de-control/
Alternativa doble
Se evalúa la condición, ejecutándose un grupo de sentencias si el resultado es “verdadero”, y
ejecutándose otro grupo alternativo de sentencias si el resultado es “falso”.

6.3 Procedimientos

Este tipo de instrucciones también son conocidas como bucles, ciclos o lazos. Lo que hacen es
que mientras se verifique una condición, un segmento del algoritmo o programa se repita
consecutivamente.

En cada repetición del bucle (o iteración) se evalúa la expresión de control del bucle (o
condición), que determinará si continuamos realizando otra iteración o bien salimos definitivamente
del bucle.

Podemos distinguir tres tipos de bucles, dependiendo de que la condición de control del bucle
se evalúe antes o después de cada iteración, y de que se pueda fijar de antemano o no el número de
iteraciones a realizar.
6.4 Introducción a las interrupciones

6.5 Instrucciones varias de control de la máquina

El bucle “mientras”
Se utiliza cuando se desea que un bucle de instrucciones se ejecute mientras una condición
sea cierta.
Características del bucle “mientras”:

● Permite repetir un bloque de instrucciones de 0 a n veces.


● La condición se evalúa antes de ejecutar el bucle, por lo que si la condición es falsa a la
entrada del bucle, éste no se ejecutará ninguna vez.
● Mientras la condición sea cierta, el bucle se repetirá, por lo que debemos incluir dentro del
cuerpo del bucle alguna sentencia que en determinadas condiciones llegue a hacer falsa la
condición del bucle para poder salir del mismo, ya que de lo contrario no terminaría nunca y
nos enfrentaríamos a un bucle infinito.

El bucle “repetir mientras”


Es similar al bucle “mientras” con la diferencia de que la condición se evalúa después de
ejecutar el cuerpo del bucle.
Características del bucle “repetir mientras”:
● Permite repetir un bloque de instrucciones de 1 a n veces.
● La condición se evalúa después de ejecutar el bucle, por lo que independientemente de
cómo sea la condición, éste se ejecutará siempre al menos una vez.
● Mientras la condición sea cierta, el bucle se repetirá, debiendo incluir dentro del cuerpo del
bucle alguna sentencia que en determinadas condiciones llegue a hacer falsa la condición
del bucle para poder salir del mismo.

El bucle “desde”:
Se utiliza cuando se desea que un bucle se ejecute repetidamente un número determinado de
veces que se conoce por anticipado.
Características del bucle “desde”:
● Comienza siempre realizando la asignación del valor inicial a la variable de control o índice
del bucle. Siempre la primera iteración del bucle se realizará con la variable índice al valor
inicial.
● Las acciones especificadas en el cuerpo del bucle se ejecutarán (a menos que el valor final
sea mayor que el inicial) y al finalizar el cuerpo del bucle, automáticamente la variable índice
incrementa en el valor establecido (hay lenguajes que no permiten establecer valores para el
incremento distintos a la unidad).
● Si el nuevo valor de la variable índice no excede del valor final, se ejecutarán de nuevo las
instrucciones y se procederá a un nuevo incremento de la variable índice, repitiéndose todo
esto hasta que el valor de la variable índice supere al valor final establecido.
● En algunos lenguajes existe la posibilidad de utilizar bucles desde con decremento en cada
iteración. En este caso se debe establecer un valor inicial para la variable índice mayor que
el valor final.
UNIDAD VII

7. Lenguajes ensambladores

7.1 Uso del lenguaje ensamblador15

El uso del lenguaje ensamblador le permite


al programador indicarle al computador
exactamente cómo llevar a cabo una tarea
específica usando la menor cantidad de
instrucciones.

El lenguaje ensamblador es usualmente


utilizado en las siguientes circunstancias:
● Obtener acceso a funciones de bajo nivel del procesador para realizar tareas que no son
soportadas por los lenguajes de alto nivel.
● Escribir manejadores de dispositivos para comunicarse directamente con hardware especial,
tales como tarjetas de red.

7.2 Lenguaje ensamblador con Visual

El lenguaje de ensamblado sirve para muchos propósitos, como mejorar la velocidad del
programa, reducir la memoria necesaria y supervisar el hardware.

La palabra clave __asm invoca el ensamblador alineado y puede aparecer siempre que una
instrucción de C o C++ sea válida.No puede aparecer por sí sola.

7.3 Objetos de ensamblador separados16

PROCESOS
resultado = a + b

15
https://sites.google.com/site/ellenguajeensamblador/home/introduccion/uso-y-aplicaciones
16

https://asm86.wordpress.com/2012/05/19/proceso-subrutina-funcion-y-metodo-son-cosas-diferentes/
Primero veamos lo que es un proceso. de acuerdo con los manuales de Intel. Un proceso es un
grupo de instrucciones que cumplen una tarea determinada. Por ejemplo en ensamblador para sumar
2 números primero hay que recibir las posiciones de memoria en las que se encuentran, cargar el
primero de ellos en el acumulador. Sumarle al acumulador el contenido de la segunda celda de
memoria y luego guardar el resultado en la celda de memoria donde debe de almacenarse el
resultado. Esto en un procesador actual son unas 5 instrucciones (aunque la suma en si es solo una).
Ahora bien, la computadora ejecuta una tras otra las instrucciones que se le dan sin tener la menor
idea de lo que está haciendo. Eso de agrupar el código lineal en procesos es tan solo para que los
programadores humanos lo entiendan. Y la computadora va a ejecutar esas instrucciones hasta que
reciba la orden de detenerse.

Los grandes códigos muy rara vez son lineales. Y en los códigos muy grandes es común que
se necesite llamar a los mismos procedimientos muchas veces. Para eficientizar el uso de la
memoria y la reutilización de código a alguien se le ocurrió que esos fragmentos de instrucciones se
podían guardar en un lugar separado de la línea principal de ejecución del programa. De modo que
cuando se necesitara ejecutar ese grupo específico de instrucciones tan solo había que hacer que la
ejecución del código saltara hacia ese sitio y que al terminar regresará al punto exacto a donde se
había dado el salto. Esto lo puede hacer porque cuando se le dice que tiene que dar ese salto el
sistema guarda la posición donde se encuentra y luego tan solo la lee para regresar a donde estaba.
Como si tuviéramos una cuerda a la que le amarramos un extremo al sitio donde empezamos para
poder regresar con tan solo seguirla. Este sistema es tan viejo como las primeras computadoras de la
década de los 50 aunque hay rumores extraoficiales que existían computadoras primitivas de tiempos
de la Segunda Guerra que eran capaces de hacer esto. Ahora veamos como esta manera de llamar
trozos de código separados en cualquier momento ha evolucionado con el paso de la tecnología.

Subrutinas:
GOSUB suma

El primer intento de organizar el código de programación fueron las subrutinas. Una subrutina
era un grupo de instrucciones que se escribía al final del código principal justo después de la
instrucción que indicaba el fin del programa. Aunque en algunos casos había quien las mezclaba con
el propio flujo del programa principal y las aislaba por medio de saltos incondicionales. En el caso del
antiguo BASIC se usaba la instrucción GoSub seguida del nombre de la subrutina. Cuando el código
llegaba a esta parte primero guardaba la posición donde iba y luego saltaba a la subrutina. Ya en la
subrutina, la última instrucción era RETURN. Cuando el procesador llegaba ahí hacía un salto hacia
la dirección que había guardado previo al salto y seguía su camino en la linea principal del programa.
En ensamblador, este proceso fue copiado directamente con instrucciones como CALL y RET.
CALL hace lo mismo que GoSub, guarda la posición en la que se encuentra y luego salta a donde se
encuentra la subrutina. Cuando llega a RET tan solo toma la posición desde la que saltó y continúa
su camino como si nada hubiera pasado. Aquí la clave es el STACK. Como ya saben el STACK es
una zona de la memoria donde se guardan datos de manera que el último en entrar es el primero en
salir. Esto permite que las subrutinas llamen a su vez a todas las subrutinas que quieran y que el
CPU siempre pueda regresar al punto del programa del que la primera de ellas fue llamada.

Las subrutinas fueron muy útiles y todavía se siguen usando para programas pequeños y
aislados. Aunque conforme el código si fue haciendo mas y mas estructurado mostraron serias
desventajas. La primera de ellas fue que trabajaban directamente con los datos del programa
principal, de modo que si uno quería reutilizarlas en otro programa debía copiar también cualquier
estructura de datos, información o pieza de código con la que interactuara. Para que una subrutina
fuera verdaderamente portable no debía de interactuar con ningúna variable o estructura ajena a si
misma. Algunos programadores astutos escribieron subrutinas con una sección propia de la memoria
de esa misma subrutina y evitaron su ejecución por medio de un salto. El problema con esto era que
ya no se podía llamar a las subrutinas de manera tan libre como antes y la recursión (una rutina que
se llama a si misma) resultaba imposible. Era necesario que cada que se llamara a una subrutina se
creara un espacio de memoria en el que pudiera hacer lo que quisiera sin alterar el resto del
programa y que cuando terminara este mismo espacio desapareciera. Además de que había que
tener control sobre la información que esta subrutina regresara. Y fue así como nacieron las
funciones.

Funciones:
resultado = suma(a, b);

Como respuesta a las debilidades de las subrutinas se crearon las funciones. Una función es
en esencia una subrutina que se comporta del mismo modo que lo hace una función matemática.
Como supongo que quienes leen mis escritos no saben nada de cálculo voy a explicarles. Una
función matemática recibe un grupo de argumentos, hace una serie de cálculos con ellos y regresa
un único resultado. Tanto las funciones matemáticas como las de programación toman una serie de
números a los que llaman argumentos y devuelven un único resultado. Una función que no recibe
ningún argumento, que tampoco retorna un resultado y que de preferencia tampoco tiene un espacio
para datos internos es idéntica a una subrutina.

Ahora veamos como se implementa una función en ensamblador. Lo primero que tenemos que
entender es que las funciones tienen su propio espacio de memoria que toman prestado cuando son
llamadas y que devuelven cuando terminan de ejecutarse. Este espacio lo tomamos del STACK y
formamos lo que llaman un Stack Frame. Un Stack Frame es una sección de la memoria gestionada
por el STACK donde guardamos variables internas y recibimos argumentos externos. El tema del
Stack Frame requiere mas de una entrada para explicarlo en su totalidad así que no voy a entrar en
detalles. En ensamblador lo primero que hacemos antes de llamar a la función es introducir al
STACK los argumentos del último al primero usando la instrucción PUSH. Una vez hecho esto
llamamos a la función con CALL. Ya en el cuerpo de la función lo primero que hacemos es definir el
stack frame guardando el apuntador base del stack y creando un espacio de direcciones virtuales (ya
se que esto se oye muy complicado pero no es imposible) en el que el Stack Frame tiene de un lado
los argumentos de entrada, luego la posición en la que va a regresar, luego los datos del stack frame
anterior y al final el espacio para variables locales. Luego sigue el código de la función. En el cual
debemos de trabajar solamente con los datos del stack frame y evitar relacionarlos con cualquier
variable o estructura de datos externa. Solo así podemos garantizar que la función sea independiente
y reutilizable en otros proyectos.

Para terminar la función tenemos que destruir el Stack Frame que creamos al principio. Esto es
sencillamente un llamado a la instrucción LEAVE seguida de un RET con un argumento extra igual a
la cantidad de bytes que ocuparon los argumentos de entrada. La instrucción LEAVE deshace el
stack frame de manera automática y aunque se supone que trabaja con la instrucción ENTER. Yo en
lo personal nunca he visto que ENTER se use.

Por cierto. Para que una función sea considerada como tal debe de retornar un único valor
numérico. Como este valor numérico no puede ser guardado en ninguna parte por el código de la
función lo que se hace es lo siguiente. Antes de ejecutar las instrucciones que destruyen el Stack
Frame guardamos en el registro acumulador el valor de retorno de la función. De modo que cuando
la función termine de ejecutarse y el CPU vuelva al código del que fue llamada. En el registro
acumulador se encuentra el resultado de la función. De este modo podemos guardarlo en donde
queramos, procesarlo o simplemente ignorarlo y seguir con el programa. El como hacer funciones en
ensamblador verdaderamente portables es un tema del que un día voy a hacer una serie de
entradas. Pues se trata de un tema complejo pero muy importante que debe de ser dominado.

Pero como era de esperarse, las funciones no son la solución para todo. Pues con la llegada
de la programación orientada a objetos o simplemente OOP surgió la necesidad de asociar las
funciones con eso que llaman objetos. Antes una función podía ser llamada desde cualquier lugar por
cualquier código. Pero cuando se programa orientado a objetos cada función es ejecutada por un
objeto o interviene un objeto en particular. La única manera de lograr esta lealtad entre las funciones
y los objetos fue la creación de lo que los jóvenes programadores de la época actual conocen como
Métodos.
Métodos:
resultado = Calculadora.suma(a, b);

Los métodos son como las funciones en cuanto a estructura interna pero se diferencian de
estas en que solo pueden ser ejecutadas por el objeto al que pertenecen. Y es en los métodos en
donde se ve la verdadera diferencia entre un objeto y una simple estructura de datos. En el ejemplo
del subtítulo. El método suma solo puede ser ejecutado por una instancia del objeto llamado
Calculadora. Las ventajas de esto es que (dicen los que defienden la OOP) se tiene mayor control de
quién está haciendo que cosa. Personalmente a mi me parece un desperdicio irresponsable de
memoria, burocracia excesiva y una sobrecarga peligrosa en la gestión interna de la memoria del
sistema operativo. La única ventaja que hasta ahora le he encontrado a la OOP es que es muy facil
modelar sistemas muy grandes en papel antes de sentarse a programar.

En fin, en la OOP cuando queremos que algo se haga debemos de averiguar que objeto es
capaz de hacer aquello que queremos, crear una instancia y darle la orden de que haga lo que
queremos. El sistema tiene que asegurarse de que no sea posible llamar al método sin pasar primero
por el objeto. Piensen en un jefe que le ordena a sus trabajadores especializados que hagan labores
en lugar de hacerlos él mismo. Ahora veamos como se hace en ensamblador para echar a andar un
sistema de llamada que usa objetos y métodos.

Un método en ensamblador es idéntico a una función excepto por una cosa: Uno de sus
parámetros lo relaciona directamente con el objeto al que pertenece. En el resto de sus componentes
internos es igual a una función. La diferencia mas grande en los métodos no radica en el método en
sí sino en el sistema que los manda ejecutar. Ahora veamos un poco de como se define un objeto.

En programación se define objeto como una entidad abstracta moldeada a partir de una clase
que tiene un conjunto de atributos y métodos propios que bien pueden ser privados, públicos o
protegidos. En ensamblador un objeto es una simple estructura de datos cuya primera mitad guarda
datos propios como cualquier otro conjunto de variables y la segunda mitad contiene las posiciones
de memoria donde se guardan los métodos que tiene derecho a ejectuar. Algunos sistemas tienen
estructuras internas que gobiernan a los objetos o que simplifican su estructura interna. Por ejemplo
en ciertos modelos de programación basados en Windows existe una tabla intermedia que asocia los
objetos con los métodos para mejorar la seguridad. Creo que la mayoría de los que leen esto ya
saben todo esto así que no voy a profundizar mas. Ahora veamos lo interesante que es ver como se
maneja un sistema de métodos orientados a objetos en ensamblador.

Cuando queremos llamar un método perteneciente a un objeto desde ensamblador. Lo primero


que debemos de hacer es crear una instancia del objeto. Para lo cual llamamos a la función
constructora que recibe una serie de argumentos entre los cuales destaca la posición de memoria
donde el objeto va a ser creado. Lo creamos e identificamos el valor que asocia el método con el
objeto. Una vez encontrado este valor hacemos la llamada al método como si fuera una función. Por
desgracia no hay una forma general de hacer esto y cada sistema tiene sus propias reglas para
manejar los objetos y los métodos. En tiempos del MS-DOS Borland tenía la suya. Windows en los
tiempos del modelo objeto componente COM tenía el suyo y los sistemas basados en iOS tienen su
sistema propio. Por suerte es muy raro que tengamos que construir uno de estos sistemas desde
cero como cuando comenzaron las funciones. Casi siempre el propio sistema operativo tiene su
manera de gestionar todo esto. Casi siempre…

En fin, personalmente llamo procedimiento a cualquier grupo de instrucciones que llevan a


cabo una sola tarea y llamo subrutina o función a un segmento de código “llamable” dependiendo del
manejo de los argumentos y el humor del que amaneza ese dia. El término Método solo lo uso en
relación con sistemas orientados a objetos. Lo que no deben de olvidar es que no importa que tan
extraña sea la moda vigente en programación. Si corre en una computadora puede programarse en
ensamblador. No piensen que programación orientada a objetos solo es Java o C++. Siempre se
puede combinar la velocidad y control del Ensamblador con cualquier rareza intelectual que se ponga
de moda en los ambientes tecnológicos. Y aunque no es sencillo, el resultado bien lo vale. Pues solo
cuando programan en ensamblador la computadora va a hacer lo que ustedes le ordenan. De lo
contrario, ustedes tendrán que hacer lo que les ordene la computadora. O en el peor de los casos, el
inventor del software con el que tienen que trabajar para ganarse la vida en sus trabajos honrados.

7.4 C17

El lenguaje de programación en C, es un lenguaje conocido como de alto nivel. Una de las


características del lenguaje de programación en C, es que es un lenguaje estructurado, lo que
permite generar código claro y sencillo, ya que esta basado en la modularidad.

El lenguaje de programación en C, esta estructurado en tres partes fundamentales, las cuales


son, una librería estándar, un programa compilador y un preprocesador.

7.5 C++

Es un lenguaje imperativo orientado a objetos derivado del C. C++ es un lenguaje de


programación diseñado a mediados de los años 1980 por Bjarne Stroustrup. La intención de su
creación fue el extender al lenguaje de programación C.

17
http://www.lenguajes-de-programacion.com/programacion-en-c.shtml
7.6 Lenguaje de programación C#18

El lenguaje Visual C# es actualmente uno de los lenguajes de programación más populares,


ya que es un lenguaje de para el desarrollo de sistemas d el propósito general. En los últimos
tiempos C y C++ han sido los lenguajes más utilizados en el desarrollo de aplicación una aplicación
es. ambos lenguajes proporcionan al programador el nivel de abstracción preciso para abordar el
desarrollo de cualquier aplicación por compleja que sea, así como mecanismos de bajo nivel para
utilizar las característica más avanzadas de las plataformas sobre las que se desarrolla resalta largo
comparado con otros lenguajes como Visual Basic, que ofrecen además de facilidad, cuando la
flexibilidad de los desarrolladores de C y C++ requieren. La solución que Microsoft da a este
problema des el lenguaje denominado C#. Se trata de un lenguaje moderno orientado a objetos que
permite desarrollar una amplia gama de aplicaciones para la nueva plataforma Microsoft. Net, la cual
se caracteriza por proporcionar utilidades y servicios para sacar un provecho total tanto de la
informática como de las comunicaciones.

Definición

Microsoft.Net se trata de un entorno de desarrollo multilenguaje diseñado por Microsoft para


simplificar la construcción, distribución y ejecución de aplicaciones para Internet. Tiene
fundamentalmente tres componentes: una máquina virtual (CLR: Common Language Runtime= que
procesa código escrito en un lenguaje intermedio ) MSIL: Microsoft Intermediante Language, una
biblioteca de clases )biblioteca. NET Framework= y ASP.NET que proporciona los servicios
necesarios para crear aplicaciones Web.

Visual C# es uno de los lenguajes de programación de alto nivel que pertenecen al paquete
.NET otros lenguajes son Visual Basic, C/C++. Con él se pueden escribir tanto programas
convencionales como para Internet.

El paquete .NET incluye un compilador (programa traductor= de C# que produce un código


escrito en un lenguaje intermedio, común para todos los lenguajes de dicha plataforma, que será el
que la máquina virtual ejecutará) esto es, cada lenguaje de la plataforma tiene su compilador que
produce código correspondiente a un único lenguaje: MSIL.

Por lo tanto, MSIL es un lenguaje máquina que no es específico de ningún procesador, sino de
la máquina virtual de .NET En realidad se trata de un lenguaje de más alto nivel que otros lenguajes

18
http://informaticabachilleratoitea.blogspot.mx/p/visual-c.html
máquina: trata directamente con objetos y tiene instrucciones para cargarlos, guardarlos, iniciarlos,
invocar a sus métodos, así como para realizar operaciones aritméticas y lógicas, para controlar el
flujo de ejecución, etc. A su vez, la máquina virtual posee un recolector de basura (para eliminar los
objetos cuando no estén referenciados) y proporciona traductores del lenguaje intermedio a código
nativo para cada arquitectura soportada; se trata de compiladores JIT (Just in Time: al instante).

Una característica importante del por que utilizamos el lenguaje C#, es que es un lenguaje de
programación orientado a objetos (POO). Además es fácil de aprender. Tiene un tamaño pequeño
que favorece el desarrollo y reduce las posibilidades de cometer errores; a la vez es potente y
flexible.
UNIDAD VIII

8. Programación del microprocesador

8.1 Programación modular

La programación modular es uno de los métodos más conocidos para resolver un problema es
dividirlo en problemas más pequeños, llamados subproblemas. De esta manera, en lugar de resolver
una tarea compleja y tediosa, resolvemos otras más sencillas y a partir de ellas llegamos a la
solución. Esta técnica se usa mucho en programación ya que programar no es más que resolver
problemas, y se le suele llamar diseño descendente, metodología del divide y vencerás o
programación top-down.

Es evidente que si esta metodología nos lleva a tratar con subproblemas, entonces también
tengamos la necesidad de poder crear y trabajar con subprogramas para resolverlos. A estos
subprogramas se les suele llamar módulos, de ahí viene el nombre de programación modular. En
Pascal disponemos de dos tipos de módulos: los procedimientos y las funciones.

Veamos un ejemplo de cómo emplear el diseño descendente para resolver un problema.


Supongamos que un profesor quiere crear un programa para gestionar las notas de sus alumnos.
Quiere que dicho programa le permita realizar tareas tales como asignar notas, cambiar notas, ver
las notas según distintas calificaciones, etc. A continuación tines un esquema que representa una de
las posibles divisiones del problema en módulos.

Ventajas
● Ventajas de la Programación Modular:
● Simplifica el diseño.
● Disminuye la complejidad de los algoritmos.
● Disminuye el tamaño total del programa.
● Ahorra en tiempo de programación porque promueve la reusabilidad del código.
● Favorece el trabajo en equipo.
● Facilita la depuración y prueba.
● Facilita el mantenimiento.
● Permite la estructuración de librerías específicas.

8.2 Uso del teclado y la pantalla19

Acceso a la pantalla

La mayoría de los programas residentes que necesitan mostrar algún tipo de información, o
bien recoger datos de la pantalla, lo hacen accediendo directamente a la memoria de vídeo, aún
cuando también es posible utilizar el DOS o la BIOS, siempre que sea seguro hacerlo.

Sin embargo, antes de proceder con cualquier operación de visualización o captura de


información, un elemento que se ha de tener en cuenta es si el modo actual de vídeo es el que
nosotros esperamos, puesto que no podemos asumir que el programa residente va a ser activado
siempre estando en modo texto o bien siempre en un determinado modo gráfico.

El primer paso que habrá de dar nuestro programa será determinar el modo actual de vídeo,
para lo cual utilizaremos el byte situado en 0040h: 0049h, que contiene el código correspondiente a
dicho modo. En el caso de que el modo de vídeo sea el adecuado, procederemos según sea
necesario, en caso contrario, si el programa residente no puede funcionar en el modo actual, se dará
un aviso al usuario, por ejemplo mediante un pitido.

Salvaguarda del contenido de la pantalla

En caso de que el programa residente necesite visualizar algo en pantalla, antes de hacerlo
deberá salvaguardar distintos parámetros, como el contenido actual de la memoria de vídeo, la
posición del cursor y, en caso de que se trate de un modo gráfico, también el registro de la paleta de
color y cualquier otro parámetro que vaya a ser modificado.

Para determinar la dirección de memoria correspondiente a la página de vídeo que se está


visualizando en un determinado momento en pantalla, leeremos el contenido de la palabra que se
encuentra en 0 0 4 Oh: 0 0 4En. Esta indica el desplazamiento a partir de segmento inicial de vídeo.
También podemos conocer el tamaño de dicha página, en bytes, dato que se almacena en la palabra
que se encuentra en la dirección 0040h:004Ch.

19
Charte Ojeda, Francisco (2009). Lenguaje ensamblador. España. Ed. Anaya
Salvaguardar el contenido de una página de vídeo en modo de texto es fácil, ya que
generalmente sólo son necesarios 4000 bytes, pero si el modo actual es un modo gráfico, el tema se
complica, ya que puede ser necesario un bloque de memoria mucho más extenso, que en el
momento en que el programa residente es activado puede o no estar disponible. En casos como éste
una opción al problema es utilizar un archivo en disco, o bien acceder a la memoria extendida que
tenga el sistema con el fin de almacenar temporalmente el contenido de la pantalla y restituirlo
posteriormente, usando para ello los servicios descritos en el capítulo previo.

Aunque no es una técnica muy habitual, un programa residente puede cambiar el modo de
vídeo en que se encontraba en ese momento el programa interrumpido. En este caso hay que tener
en cuenta que dicho programa puede estar usando otras zonas de la memoria de vídeo, por ejemplo
para almacenar varias páginas de texto, que seguramente se verán destruidas al cambiar de modo.
Para evitar problemas como éste sería necesario salvaguardar toda la memoria de vídeo, así como
todos los parámetros mencionados anteriormente de posición y forma del cursor, paleta de color, etc

Estado del teclado

A pesar de no tener la importancia que tienen los parámetros de vídeo, también el teclado
cuenta con una serie de indicadores que pueden ser modificados durante la ejecución del programa
residente y que deberían ser restituidos antes de devolver el control al programa interrumpido.

Cuando el programa residente se activa, la tecla de bloqueo de mayúsculas, inserción o


bloqueo de números pueden encontrarse en un determinado estado, que puede ser modificado por el
usuario mientras interactúa con el programa residente, por ejemplo para facilitar un nombre de
archivo.

Aunque no se trate de parámetros de gran interés, el programa residente al activarse puede


obtener el estado de las teclas mencionadas, simplemente leyendo el byte situado en la dirección
0040h:0017h, en el que los bits 4 a 7 contienen el estado de las teclas de bloqueo de
desplazamiento, bloqueo de números, bloqueo de mayúsculas e inserción, respectivamente. Este
byte puede ser restaurado posteriormente, antes de devolver el control, de tal forma que el programa
interrumpido se encuentre con el mismo estado que tenía previamente.

Activación por teclado

Si bien ya conocemos la mayor parte de los elementos a tener en cuenta en el diseño de un


programa residente, aún no hemos aprendido a utilizar la interrupción de teclado con el fin de que
dicho programa sea activado mediante una combinación de teclas, en lugar de hacerlo mediante una
interrupción. Se ha dejado este apartado casi para el final con el objetivo de que, al iniciar el
desarrollo de nuestro primer programa residente útil, pudiésemos tener todos los puntos precisos en
cuenta, evitando así cualquier problema que pudiese surgir.

El teclado de un PC cuenta en su interior con una matriz de contactos y un pequeño integrado,


habitualmente un 8741, 8742 o alguno compatible, que es el encargado, entre otras funciones, de
transmitir al ordenador lo que se denomina sean code o código de la tecla que se ha pulsado. Este
código no tiene nada que ver con el código ASCII de un carácter, de hecho algunas de las teclas no
tienen tal correspondencia. Es el controlador de teclado, normalmente el programa KEYB del DOS, el
que se encarga de traducir cada código de teclado a su correspondiente código ASCII, en caso de
que esto sea necesario.

Cada vez que el controlador de teclado detecta el cierre de un contacto, o lo que es lo mismo,
la pulsación de una tecla, genera la IRQ1, cuyo resultado será la ejecución del actual gestor de la
interrupción 9h. El gestor habitual de esta interrupción lee el código, a través del puerto 6Oh, y lo
almacena en la cola circular de teclado, poniéndolo así a disposición del sistema operativo y los
programas dicha información.

8.3 Conversiones de datos20

La finalidad de la mayoría de las aplicaciones estaría muy limitada si cada vez que finalizasen
se perdiera toda la información sobre la que han estado operando. La solución, lógicamente, pasa
por almacenar dicha información en un medio persistente, como puede ser un disco o disquete.

El acceso a los archivos desde DOS puede efectuarse por medio de dos sistemas diferentes.
El primero, y más antiguo, consiste en utilizar los FCB (File Control Block), unas estructuras de datos
que contienen todo lo concerniente al archivo que va a manipularse. Ésta es una técnica incómoda y,
tal como se ha dicho, bastante anticuada, de los días del DOS LO.

La técnica alternativa es la que forman los servicios basados en manejadores de archivo o file
handles. Es una técnica mucho más cómoda de uso, ya que no tenemos que preocuparnos de
detalles de bajo nivel.

El único inconveniente es que no puede utilizarse en versiones de DOS previas a la 2.0, una
limitación que realmente no es tal puesto que difícilmente nadie usa en la actualidad una versión de
DOS previa a la 6.2 o 5.0.

20
Charte Ojeda, Francisco (2009). Lenguaje ensamblador. España. Ed. Anaya
En este capítulo se van a tratar aquellas funciones de la interrupción 21h que tienen que ver
con el tratamiento de los archivos basándose en el uso de manejadores de archivos.

Para facilitar el nombre de los archivos con los que se desea trabajar se emplearán cadenas
ASCIIZ, es decir, secuencias de caracteres conteniendo el nombre, si es preciso camino y extensión,
y terminadas con un byte 0.

8.4 Archivos de disco21

El ensamblador puede usar archivos fuente que contengan caracteres ASCII estándar.
Considere que no todos los procesadores de texto escriben archivos en disco usando solamente los
caracteres ASCII estándar. Antes de ensamblar un programa verifique que esté en código ASCII.

Para ensamblar el programa:


A>MASM PROGRAMA;
MICROSOFT ® MACRO ASSEMBLER VERSION 5.10
COPYRIGHT © MICROSOFT CORP 1981, 1988. ALL RIGHTS RESERVED
49822 + 219323 BYTES SYMBOL SPACE FREE
0 WARNING ERRORS
0 SEVERE ERRORS
A>
El ensamblador crea un archivo intermedio *.OBJ el cual contiene nuestro programa e
información adicional usada por otro programa llamado LINKER <encadenador>.

Encadenar al archivo *.OBJ

A>LINK ARCHIVO;
Microsoft ® Overlay Linker Versión 3.64
copyright © Microsoft corp. 1983-1988. All rights reserved
LINK: warning L4021: No Stack Segment

Hemos creado nuestro archivo *.EXE. Ahora sí necesitamos crear nuestra versión
*.COM. El archivo EXE2BIN.EXE del DOS convierte un archivo EXE a un archivo
BIN.
A>EXE2BIN ARCHIVO ARCHIVO.COM
A>

21
http://www.ittux.edu.mx/sites/default/files/MICROCOMPUTADORAS_AL_DETALLE.pdf
UNIDAD IX

9. Especificaciones del hardware

9.1 Distribución de terminales y funciones de cada terminal22

El P1C16C84 está fabricado en tecnología CMOS, consume baja potencia, y es


completamente estático (si el reloj se detiene, los datos de la memoria no se pierden). El 16F84 tiene
las mismas características, pero posee memoria FLASH, esto hace que tenga menor consumo de
energía, y como si fuera poco tiene mayor capacidad de almacenamiento.

El encapsulado más común para estos microcontroladores es el DIP (Dual In line Pin) de 18
pines, (el nuestro...), y utiliza un reloj de 4 MHz (cristal de cuarzo). Sin embargo, hay otros tipos de
encapsulado, por ejemplo, el encapsulado tipo surface mount (montaje superficial) es mucho +
pequeño.

Terminales del microcontrolador y sus respectivas funciones:

Ésta sería la disposición de sus terminales y sus respectivos nombres...

Patas 1, 2, 3, 17 y 18 (RA0-RA4/TOCKI): Es el PORT A. Corresponden a 5 líneas


bidireccionales de E/S (definidas por programación). Es capaz de entregar niveles TTL cuando la
alimentación aplicada en VDD es de 5V ± 5%. El pin RA4/TOCKI como entrada puede programarse
en funcionamiento normal o como entrada del contador/temporizador TMR0.

Pata 4 (MCLR / Vpp): Es una pata de múltiples aplicaciones, es la entrada de Reset (master
clear) si está a nivel bajo y también es la habilitación de la tensión de programación cuando se está
programando el dispositivo. Cuando su tensión es la de VDD el PIC funciona normalmente.

Patas 5 y 14 (VSS y VDD): Son respectivamente las patas de masa y alimentación. La tensión
de alimentación de un PIC está comprendida entre 2V y 6V aunque se recomienda no sobrepasar los
5.5V.

22
http://perso.wanadoo.es/luis_ju/pic/pic02.html
Patas 6, 7, 8, 9, 10, 11, 12, 13 (RB0-RB7): Es el PORT B. Corresponden a ocho líneas
bidireccionales de E/S (definidas por programación). Pueden manejar niveles TTL cuando la tensión
de alimentación aplicada en VDD es de 5V ± 5%. RB0 puede programarse además como entrada de
interrupciones externas INT.

Patas 15 y 16 (OSC1/CLKIN y OSC2/CLKOUT): Corresponden a los pines de la entrada


externa de reloj y salida de oscilador a cristal respectivamente.

9.2 Buses23

Bus de datos Informática El bus (o canal) es un sistema digital que transfiere datos entre los
componentes de un ordenador o entre ordenadores. Está formado por cables o pistas en un circuito
impreso, dispositivos como resistores y condensadores además de circuitos integrados.

Bus de expansión: conjunto de líneas de comunicación encargado de llevar el bus de datos, el


bus de dirección y el de control a la tarjeta de interfaz (entrada, salida) que se agrega a la tarjeta
principal.

Bus del sistema: todos los componentes de la CPU se vinculan a través del bus de sistema,
mediante distintos tipos de datos el microprocesador y la memoria principal, que también involucra a
la memoria caché de nivel 2. La velocidad de transferencia del bus de sistema está determinada por
la frecuencia del bus y el ancho del mínimo.

El bus de datos son las líneas de comunicación por donde circulan los datos externos e
internos del microprocesador.

El bus de direcciones línea de comunicación por donde viaja la información específica sobre la
localización de la dirección de memoria del dato o dispositivo al que se hace referencia.

El bus de control línea de comunicación por donde se controla el intercambio de información


con un módulo de la unidad central y los dispositivos de entrada, salida, mixtos.

9.3 ready y espera24

23
https://es.slideshare.net/mariovalle/tipos-de-buses-y-microprocesadores
24
https://www.dsi.fceia.unr.edu.ar/images/downloads/digital_II/Temporizacion_8086.pdf
La entrada Ready produce estados de espera para componentes de memoria y E/S más
lentos.
Un estado de espera (Tw) es un período adicional de reloj introducido entre T2 y T3 para
alargar el ciclo de lectura o escritura.
La entrada Ready se muestrea al final de T2 y, de nuevo, en la mitad de Tw. La entrada Ready
en el 8086 tiene algunos requisitos estrictos de temporización. Los requisitos de temporización para
esta operación se cumplen con los circuitos internos de temporización de Ready en el generador de
reloj 8284A.

9.4 Modo máximo y modo mínimo

El microprocesador 8086 puede trabajar en dos modos diferentes: el modo mínimo y el modo
máximo. En el modo máximo el microprocesador puede trabajar en forma conjunta con un
microprocesador de datos numérico 8087 y algunos otros circuitos periféricos.

En el modo mínimo el microprocesador trabaja de forma más autónoma al no depender de


circuitos auxiliares, pero esto a su vez le resta flexibilidad. En cualquiera de los dos modos, las
terminales del microprocesador se pueden agrupar de la siguiente forma:
● Alimentación
● Reloj
● Control y estado
● Direcciones
● Datos
UNIDAD X

10. Interfaz

10.1 De memoria25

Los microprocesadores 8086, 80186, 80286 y 80386SX difieren de los 8088/80188 en tres
aspectos: (1) el bus de datos es de 16 bits, en vez de ocho bits como en el 8088, (2) la terminal IO/M
del 8088 es sustituida por una terminal M/IO, y (3) existe una nueva señal de control llamada
habilitación de bus alto (BHE). El bit de dirección A0 o BLE también es empleado de forma distinta.
Existen algunas otras diferencias entre los 8086/80186 y los 80286/80386SX. Los 80286/80386SX
contienen un bus de direcciones (A23-A0) de 24 bits en lugar del bus de direcciones (A19-A0) de 20
bits de los 8086/80186. Los 8086/80186 contienen una señal M/IO, mientras que el sistema 80286 y
el microprocesador 80386SX contiene las señales de control MRDC y ;WTC en lugar de RD y WR.

Control del bus de 16 bits

El bus de datos de los 8086, 80186, 80286 y 80386SX tiene el doble de ancho que el bus de
los 8088/80188. Este bus de datos más ancho nos enfrenta a un conjunto de problemas que no
habían sido encontrados anteriormente. Los 8086, 80186, 80286 y 80386SX deben ser capaces de
escribir datos a cualquier localidad de 16 bits, o a cualquiera de 8 bits. Esto significa que el bus de
datos de 16 bits debe dividirse en dos secciones separada (bancos) de ocho bits, para que el
microprocesador pueda escribir a cualquiera de las dos mitades (8bits) o a ambas (16 bits). La figura
10-27 muestra los dos bancos de la memoria. Un banco (banco bajo) contiene todas las localidades
de la memoria con números pares, y el otro banco (banco alto) contiene todas las localidades de
memoria con números impares.

10.2 Básica

Una interfaz es el puerto (circuito físico) a travez del que se envían o reciben señales desde un
sistema o subsistemas hacia otros. No existe una interfaz universal, sino que existen diferentes
estándares ( Interfaz USB, interfaz SCSI, etc.) que establecen especicaciones técnicas concretas,
con lo que la interconexión solo es posible utilizando la misma interfaz de origen y destino.

Los objetivos de los dispositivos de entrada y salida se reeren a la comunicación entre un


sistema de procesamiento de información y los agentes humanos u otro sistemas de procesamiento
de información. Las entradas son las señales o datos recibidos por el sistema, y salidas son las

25
https://es.scribd.com/document/222815414/Interfaz-de-memoria-con-los-procesadores-pdf
señales enviadas por este. Estos dispositivos de entrada y de salida son componentes electrónicos
que permiten la transmisión y/o recepción de información de/hacia el ordenador. Como ejemplo, el
ratón y el teclado son dispositivos de salida. Los dispositivos para comunicación entre computadores
son típicamente dispositivos de entrada y salida.

La interfaces de entrada y salida es requerida cuando los dispositivos son ejecutados por el
procesador. La interfaz debe ser necesariamente lógica para interpretar la dirección de los
dispositivos generados por el procesador. Si se intercambian diferentes formatos de datos, la interfaz
debe ser capaz de convertir datos en serie a paralelo y viceversa. La implementación de interfaces a
alto nivel se basa en los sistemas operativos y lenguajes de programación de alto nivel, facilitan el
uso separado de más conceptos y primitivas abstractas de E/S. Por ejemplo: la mayoría de los
sistemas operativos proporcionan aplicaciones con el concepto e chero. Los lenguajes de
programación C y C++, y los sistemas unix, tradicionalmente bastare cheros y dispositivos como
streams, los cuales pueden ser leídos o escritos o ambas cosas.

Las funciones básicas de un sistema de E/S debe poder, como mínimo, direccionar los
diferentes periféricos con los que puede establecer comunicación, establecer un sistema de
comunicación entre el procesador y los controladores, y sincronizar los dispositivos de manera que
no se produzcan inconsistencias errores.

10.3 Bus

En la comunicación física entre el controlador y el procesador existen distintas formas de


interconexión que se pueden dar entre controlador y procesador. Las más destacadas son basadas
en buffer Tri-estado y en las MUX/DEMUX indicando sus ventajas/inconvenientes. Se suele usar más
la alternativa basada en buffer Tri-estado. Pues permite un mejor aprovechamiento de los
dispositivos E/S y la mejor de los mismo al dedicar mayor área de estos en la mejora de prestaciones
y no en el interconexcionado.

En la comunicación en buffer tri-estado se implementan usando un bus compartido y buffer


Tri-estado para cada puerto y evitar así el volcado de información por parte de dos o más periféricos
en el bus. Las características principales de este tipo de interconexión son:
● Facilidad en la expansión por medio de tarjetas o circuiteria especicada.
● Permite conectar en paralelo muchos periféricos.

En la comunicación basada en MUX/DEMUX se emplean MUX y DEMUX para seleccionar el


periférico que podrá usar el bus compartido en un momento dado, impidiendo al resto de dispositivos
acceder a este último. Las características principales de este tipo de interconexión son:
● Escasa posibilidad de expansión.
● Muchas circuitería: suelen dedicar gran parte del área del dispositivo en el cableado del
mismo.

Características de los Buses:


● Un bus es un camino entre dos o más dispositivos
● Se encuentran constituido por varios caminos de comunicación, o líneas
● Cada línea es capaz de transmitir señales binarias representadas por 1 o por 0
● Se pueden usar varias líneas del bus para transmitir dígitos binarios simultáneamente (en
paralelo)
● Los computadores poseen diferentes tipos de buses. El bus que conecta los componentes
principales del computador (procesador, memoria, E/S) se denomina bus del sistema.

El bus está estructurado de la siguiente manera:


● Constituidos usualmente por entre 50 y 100 líneas
● Cada línea se le asigna un signicado en tres grandes grupos:
‣Línea de datos.- Proporcionan un camino para transmitir datos entre los
módulos del sistema. El conjunto de estas líneas se llama bus de datos.
‣Línea de direcciones.- Para designar la fuente o el destino del dato situado en
el bus de datos.
‣Línea de control.- Controlan el acceso y uso de las líneas de datos y de
direcciones.

Das könnte Ihnen auch gefallen