Ejemplo sencillo

Ejemplo de separar numero pares de impares

                        .model small
.stack 100h      ;tamaño de la pila
.data
tabla1 Db   39h,45h,33h,52h,28h
impar db    5 dup (?)  ; espacios en memoria para guardar los valores de la tabla
par                 db   5 dup (?)
.code
INICIO: mov ax,seg tabla1     ; iniciar segmento desde la tabla1
mov ds,ax
mov si,offset tabla1   ; posicionar apuntador a la tabla
mov BX,offset IMPAR
mov Di,offset PAR
mov cx,5
Definir_p:         MOV AX,0000H
mov al,[si]
AND AL,0FH
SUB AL,08H
CMP AL,00H
JZ PAR_N
MOV AL,[SI]  ;los corchetes son para mover donde lo que esta apuntando SI a AL
AND AL,0FH
SUB AL,06H
CMP AL,00H
JZ PAR_N
MOV AL,[SI]
AND AL,0FH
SUB AL,04H
CMP AL,00H
JZ PAR_N
MOV AL,[SI]
AND AL,0FH
SUB AL,02H
CMP AL,00H
JZ PAR_N
JMP IMPAR_N
RETORNO: INC SI
LOOP DEFINIR_P
JMP FIN
PAR_N: MOV DL,[SI]
MOV [DI],DL
INC DI
JMP RETORNO
IMPAR_N: MOV DH,[SI]
MOV [BX],DH
INC BX
JMP RETORNO
FIN:              MOV AX,4C00H   ; salida del sistema
INT 21H
END INICIO
END


 Esto puede ayudar un poco son varios vídeos



Conjunto de intrucciones

El Conjunto de Instrucciones del Procesador

      La siguiente es una lista de las instrucciones para la familia de procesadores 8086, clasificadas por categorías. Aunque la lista parece enorme, muchas de las instrucciones rara vez se necesitan.

Aritméticas

• ADC: Suma con acarreos
• ADD: Suma números binarios
• DEC: Decrementa en 1
• DIV: División sin signo
• IDIV: Divide con signo (enteros)
• IMUL: Multiplica con signo (enteros)
• INC: Incrementa en 1
• MUL: Multiplica sin signo
• NEG: Negación
• SBB: Resta con el bit prestado
• SUB: Resta valores binarios

Conversión ASCII-BCD

• AAA: Ajuste ASCII después de sumar
• AAD: Ajuste ASCII antes de dividir
• AAM: Ajuste ASCII después de multiplicar
• AAS: Ajuste ASCII después de restar
• DAA: Ajuste decimal después de sumar
• DAS: Ajuste decimal después de restar

Corrimiento de bit

• RCL: Rota a la izquierda a través del acarreo
• RCR: Rota a la derecha a través del acarreo
• ROL: Rota a la izquierda
• ROR: Rota a la derecha
• SAL: Corrimiento algebraico a la izquierda
• SAR: Corrimiento algebraico a la derecha
• SHL: Corrimiento lógico a la izquierda
• SHR: Corrimiento lógico a la derecha
• SHLD/SHRD: Corrimiento en doble precisión (80386 y posteriores)

Comparación

• BSF/BSR: Exploración de bit (80386 y posteriores)
• BT/BTC/BTR/BTS: Prueba bit (80386 y posteriores)
• CMP: Compara
• CMPS: Compara cadenas de caracteres
• TEST: Prueba bits

Transferencia de datos

• LDS: Carga el registro del segmento de datos
• LEA: Carga una dirección efectiva
• LES: Carga el registro de segmento extra
• LODS: Carga una cadena
• LSS: Carga el registro del segmento de la pila
• MOV: Mueve datos
• MOVS: Mueve cadenas
• MOVSX: Mueve con signo-extendido
• MOVZX: Mueve con cero-extendido
• STOS: Almacena una cadena
• XCHG: Intercambia
• XLAT: Traduce

Operaciones con banderas

• CLC: Limpia la bandera de acarreo
• CLD: Limpia la bandera de dirección
• CLI: Limpia la bandera de interrupción
• CMC: Complementa la bandera de acarreo
• LAHF: Carga AH de las banderas
• POPF: Remueve banderas de la pila
• PUSHF: Agrega banderas a la pila
• SAHF: Almacena el contenido de AH en las banderas
• STC: Establece la bandera de acarreo
• STD: Establece la bandera de dirección
• STI: Establece la bandera de interrupción

Entrada/Salida

• IN: Introduce un byte o una palabra
• OUT: Saca un byte o una palabra

Operaciones lógicas

• AND: Conjunción lógica (y)
• NOT: Negación lógica (no)
• OR: Disyunción lógica (o)
• XOR: Disyunción exclusiva

Ciclos

• LOOP: Repetir el ciclo hasta que se complete
• LOOPE/LOOPZ: Repetir el ciclo mientras sea igual/mientras sea cero
• LOOPNE/LOOPNZ: Repetir el ciclo mientras no sea igual/mientras no sea cero

Control del procesador

• ESC: Escape
• HLT: Introduce un estado de detención
• LOCK: Bloquea el bus
• NOP: No operar
• WAIT: Pone al procesador en estado de espera

Operaciones con la pila

• POP: Remueve una palabra de la pila
• POPA: Remueve todos los registros generales (80286 y posteriores)
• PUSH: Agrega a la pila
• PUSHA: Agrega todos los registros generales (80286 y posteriores)

Operaciones con cadenas

• CMPS: Compara cadenas
• LODS: Carga cadena
• MOVS: Mueve cadena
• REP: Repite una cadena
• REPE/REPZ: Repite mientras sea igual/mientras sea cero
• REPNE/REPNZ: Repite mientras no sea igual/mientras no sea cero
• SCAS: Explora una cadena
• STOS: Almacena una cadena

Transferencia (condicional)

• INTO: Interrumpe si hay desbordamiento
• JA/JNBE: Bifurca (salta) si es mayor o salta si no es menor o igual
• JAE/JNB: Salta si es mayor o igual o salta si no es menor
• JB/JNAE: Salta si es menor o salta si no es mayor o igual
• JBE/JNA: Salta si es menor o igual o salta si no es mayor
• JC/JNC: Salta si hay acarreo o salta si no hay acarreo
• JCXZ: Salta si CX es cero
• JE/JZ: Salta si es igual o salta si es cero
• JG/JNLE: Salta si es mayor o salta si no es menor o igual
• JGE/JNL: Salta si es mayor o igual o salta si no es menor
• JL/JNGE: Salta si es menor o salta si no es mayor o igual
• JLE/JNG: Salta si es menor o igual o salta si no es mayor
• JNE/JNZ: Salta si no es igual o salta si no es cero
• JNP/JPO: Salta si no hay paridad o salta si la paridad es impar
• JO/JNO: Salta si hay desbordamiento o salta si no hay desbordamiento
• JP/JPE: Salta si hay paridad o salta si la paridad es par
• JS/JNS: Salta si el signo es negativo o salta si el signo es positivo

Transferencia (incondicional)

• CALL: Llama a un procedimiento
• INT: Interrupción
• IRET: Interrupción de regreso
• JMP: Salto incondicional
• RET: Regreso
• RETN/RETF: Regreso cercano o regreso lejano

Conversión de tipo

• CBW: Convierte byte a palabra
• CDQ: Convierte palabra doble a palabra cuádruple (80386 y posteriores)
• CWD: Convierte palabra a palabra doble
• CWDE: Convierte una palabra a una palabra doble extendida

Interrupciones

Interrupciones

      Algunas veces el flujo ordinario de un programa debe ser interrumpido para procesar eventos que requieren una respuesta rápida. El hardware de un computador provee un mecanismo llamado interrupción para manipular estos eventos. Por ejemplo cuando se mueve el ratón la interrupción de hardware del ratón es el programa actual para manejar el movimiento del ratón (para mover el cursor del mouse, etc) Las interrupciones hacen que el control se pase a un manipulador de interrupciones. Los manipuladores de interrupciones son rutinas que procesan la interrupción. A cada tipo de interrupción se le asigna un numero entero. En el comienzo de la memoria física una tabla de vectores de interrupción que contiene la dirección del segmento de los manipuladores de la interrupción. El numero de la interrupción es esencialmente un indice en esta tabla.

Interrupciones internas de hardware

Las interrupciones internas son generadas por ciertos eventos que surgen durante la ejecución de un programa.

Este tipo de interrupciones son manejadas en su totalidad por el hardware y no es posible modificarlas.

Un ejemplo claro de este tipo de interrupciones es la que actualiza el contador del reloj interno de la computadora, el hardware hace el llamado a esta interrupción varias veces durante un segundo para mantener la hora actualizada.

Aunque no podemos manejar directamente esta interrupción (no podemos controlar por software las actualizaciones del reloj), es posible utilizar sus efectos en la computadora para nuestro beneficio, por ejemplo para crear un "reloj virtual" actualizado continuamente gracias al contador del reloj interno. Únicamente debemos escribir un programa que lea el valor actual del contador y lo traduzca a un formato entendible para el usuario.


Interrupciones externas de hardware

Las interrupciones externas las generan los dispositivos periféricos, como pueden ser: teclado, impresoras, tarjetas de comunicaciones, etc. También son generadas por los co-procesadores.

No es posible desactivar a las interrupciones externas.

Estas interrupciones no son enviadas directamente a la UCP, sino que se mandan a un circuito integrado cuya función es exclusivamente manejar este tipo de interrupciones. El circuito, llamado PIC 8259A, si es controlado por la UCP utilizando para tal control una serie de vías de comunicación llamadas puertos.

Interrupciones de software

Las interrupciones de software pueden ser activadas directamente por el ensamblador invocando al número de interrupción deseada con la instrucción INT.

El uso de las interrupciones nos ayuda en la creación de programas, utilizándolas nuestros programas son más cortos, es más fácil entenderlos y usualmente tienen un mejor desempeño debido en gran parte a su menor tamaño.

Este tipo de interrupciones podemos separarlas en dos categorías: las interrupciones del sistema operativo DOS y las interrupciones del BIOS.

La diferencia entre ambas es que las interrupciones del sistema operativo son más fáciles de usar pero también son más lentas ya que estas interrupciones hacen uso del BIOS para lograr su cometido, en cambio las interrupciones del BIOS son mucho más rápidas pero tienen la desventaja que, como son parte del hardware son muy específicas y pueden variar dependiendo incluso de la marca del fabricante del circuito.

Interrupciones mas usuales
  • Int 21H (interrupción del DOS)
  • Int 10H (interrupción del BIOS)
  • Int 16H (Interrupción del BIOS)
Interrupción 21H

Propósito: Llamar a diversas funciones del DOS.

Sintaxis: Int 21H

Esta interrupción tiene varias funciones, para accesar a cada una de ellas es necesario que el el registro AH se encuentre el número de función que se requiera al momento de llamar a la interrupción.

Funciones para desplegar información al vídeo.
  • 02H Exhibe salida
  • 09H Impresión de cadena (vídeo)
  • 40H Escritura en dispositivo/Archivo

Funciones para leer información del teclado.

  • 01H Entrada desde teclado
  • 0AH Entrada desde teclado usando buffer
  • 3FH Lectura desde dispositivo/archivo

Funciones para trabajar con archivos.

En esta sección únicamente se expone la tarea específica de cada función, para una referencia acerca de los conceptos empleados refierase a la unidad 7, titulada: "Introducción al manejo de archivos".

Método FCB

  • 0FH Abrir archivo
  • 14H Lectura secuencial
  • 15H Escritura secuencial
  • 16H Crear archivo
  • 21H Lectura aleatoria
  • 22H Escritura aleatoria

Handles

  • 3CH Crear archivo
  • 3DH Abrir archivo
  • 3EH Cierra manejador de archivo
  • 3FH Lectura desde archivo/dispositivo
  • 40H Escritura en archivo/dispositivo
  • 42H Mover apuntador de lectura/escritura en archivo

Interrupción 10H

Propósito: Llamar a diversas funciones de vídeo del BIOS.

Sintaxis: Int 10H
Esta interrupción tiene diversas funciones, todas ellas nos sirven para controlar la entrada y salida de vídeo, la forma de acceso a cada una de las opciones es por medio del registro AH.

Funciones comunes de la interrupción 10H.(algunas de las funciones de esta interrupción)

  • 02H Selección de posición del cursor
  • 09H Escribe atributo y carácter en el cursor
  • 0AH Escribe carácter en la posición del cursor
  • 0EH Escritura de caracteres en modo alfanumérico
Interrupción 16H

Propósito: Manejar la entrada/salida del teclado.

Sintaxis: Int 16H

Veremos dos opciones de la interrupción 16H, estas opciones, al igual que las de otras interrupciones, son llamadas utilizando el registro AH. 

Funciones de la interrupción 16H

  • 00H Lee un carácter de teclado
  • 01H Lee estado del teclado
Código para limpiar pantalla

       MOV AX,0600H ;RECORRER TODO LA PANTALLA
       MOV BH,07H ;ATRIBUTO FONDO NEGRO LETRAS BLANCAS
       MOV CX,0000H ;POSICIÓN IZQUIERDA SUPERIOR
       MOV DX,184FH ;POSICIÓN DERECHA INFERIOR
       INT 10H ;INTERRUPCIÓN 

Ensamblar, Enlazar y Ejecutar un programa en Lenguaje Ensamblador.

Ensamblar

     Consiste en la traduccion del codigo fuente(archivo.asm) en codigo objeto ( archivo .obj) y la generacion de un archivo intermedio. Cuando se ensambla se crean dos extensiones .obj y .lst.

     Para enlazar un programa en caso de ser por medio de doxbox se entra en la carpeta de donde se encuentra el ensamblador y el linkeador (enlazador)


Luego de abrir la carpeta TD se coloca el siguiente comando para ensamblar el codigo TASM /zd/zi nombre y le dan enter no les debe arrojar errores ni nada si por alguna razón les arroja un error les dirá la linea en la cual da el error y hasta que no lo corrijan no lo ensamblara 


Enlazar

    El programa para enlazar toma el codigo objeto (.obj) generado por el ensamblado y le añade los encabezados apropiados para crear otro archivo que va hacer el ejecutable y crea las extensiones .exe y .map 

      Para linkearlo se escribe el siguiente comando TLINK /v/s nombre y enter 


Ejecutar

     Para ejecutar, el programa crea un psp inmediatamente antes de que el programa este cargado en memoria.

       Para ver la ejecucion del programa paso a paso y lo que va haciendo en cada instruccion se entra al turbo debugger se coloca td nombre y entre y abre una pantalla asi


Para ejecutar paso a paso F7, para cambiar de pantalla de las cuarto que sales F6, para ejecutar el programa completo F9  y para ver lo que hace el programa si se usaron interrupciones de texto y de video solo se coloca el nombre y enter mas adelante se hablara de las interrupciones

Requerimientos de lenguaje ensamblador

Ensambladores y Compiladores

      Primero identificamos dos clases de lenguajes de programación: de alto nivel y de bajo nivel. Los programadores que escriben en un lenguaje de alto nivel, como C y Pascal, codifican comandos poderosos, cada uno de los cuales puede generar muchas instrucciones en lenguaje de máquina. Por otro lado, los programadores que escriben en un lenguaje ensamblador de bajo nivel codifican instrucciones simbólicas, cada una de las cuales genera una instrucción en lenguaje de máquina. A pesar del hecho de que codificar en un lenguaje de alto nivel es más productivo, algunas ventajas de codificar en lenguaje ensamblador son:

• Proporciona más control sobre el manejo particular de los requerimientos de hardware.
• Genera módulos ejecutables más pequeños y más compactos.
• Con mayor probabilidad tiene una ejecución más rápida.

      Una práctica común es combinar los beneficios de ambos niveles de programación: codificar el grueso de un proyecto en un lenguaje de alto nivel y los módulos críticos (aquellos que provocan notables retardos) en lenguaje ensamblador. 

       Sin importar el lenguaje de programación que utilice, de todos modos es un lenguaje simbólico que tiene que traducirse a una forma que la computadora pueda ejecutar. Un lenguaje de alto nivel utiliza un compilador para traducir el código fuente a lenguaje de máquina (técnicamente, código objeto). Un lenguaje de bajo nivel utiliza un ensamblador para realizar la traducción. Un programa enlazador para ambos niveles, alto y bajo, completa el proceso al convertir el código objeto en lenguaje ejecutable de máquina.

Palabras Reservadas

     Ciertas palabras en lenguaje ensamblador están reservadas para sus propósitos propios, y son usadas sólo bajo condiciones especiales. Por categorías, las palabras reservadas incluyen

•  Instrucciones, como MOV y ADD, que son operaciones que la computadora puede ejecutar
•  Directivas, como END o SEGMENT, que se emplean para proporcionar comandos al ensamblador
•  Operadores, como FAR y SIZE, que se utilizan en expresiones
•  Símbolos predefinidos, como ©Data y @Model, que regresan información a su programa.

El uso de una palabra reservada para un propósito equivocado provoca que el ensamblador genere un mensaje de error. El apéndice C muestra una lista de las palabras reservadas del lenguaje ensamblador.

Modos de Direccionamiento.

     El 8086 ofrece una multitud de vías para direccionar la información: registro a registro, direccionamiento inmediato, direccionamiento directo y varios tipos diferentes de direccionamiento indirecto. Cada modo tiene
siempre un operando fuente y uno destino. El operando destino está ubicado a la izquierda de la coma; y el fuente a la derecha. Adicionalmente, los modos directo e indirecto involucran el uso de un registro de segmento.

Direccionamiento Registro.

      Es aquel en el cual la operación se lleva a cabo entre los contenidos de dos registros. Por ejemplo, la
instrucción
                        mov AX,BX

      Indica que el contenido del registro BX sea copiado en el registro AX.

Direccionamiento Inmediato.

     En este modo de direccionamiento, uno de los operandos está presente en el o los bytes siguientes al código de operación. Por ejemplo, la instrucción

                       add AX,3064h

     Indica que el número 3064h sea sumado al contenido del registro AX y el resultado almacenado en dicho registro.

Direccionamiento Directo.

     EL 8086 implementa el direccionamiento directo a memoria, sumando un desplazamiento de 16 bits, indicado por los dos bytes que siguen al código de operación, al contenido del registro de segmento de datos. La suma es pues, la posición de memoria direccionada. Por ejemplo, la instrucción

                      mov AH,TABLA

   Señala que el contenido de la posición de memoria cuya dirección está indicada por el identificador TABLA, sea copiado en el registro AH.

Direccionamiento Indirecto.

     El modo de direccionamiento indirecto es el más difícil de comprender, pero también el más poderoso. Existen cuatro métodos de direccionamiento indirecto: indirecto a registro, relativo a base, indexado e indexado a base.

Indirecto a Registro.

      En el modo de direccionamiento indirecto a registro, la dirección de memoria donde se encuentra uno de los operando es indicado a través del contenido de los registros BX, BP, SI o DI. La instrucción

                   mov AX,[DI]

      Establece que el contenido de la palabra de memoria cuya dirección está indicada por el contenido del
registro DI, sea copiado en el registro AX.

Relativo a Base.

      El direccionamiento a la memoria de datos, relativo a base simplemente usa el contenido del registro BX o BP como base para la posición efectiva de memoria. La instrucción

          mov CL,[BP]+DESP

     Copia el contenido de la posición de memoria cuya dirección está determinada por la suma del contenido de BP y DESP, en el registro CL.

Indexado.

       El direccionamiento indexado directo está permitido especificando los registros SI o DI como índices. Empleando este modo de direccionamiento es posible acceder a los elementos de un vector. La instrucción 

          sub AH,MATRIZ[SI]

    Resta del contenido del registro AH, el valor contenido en la posición de memoria especificada por la suma del desplazamiento indicado por el identificador MATRIZ y el contenido del registro SI.

Indexado a Base.

    Resulta de la combinación de los modos de direccionamiento Relativo a Base e Indexado Directo. La
instrucción

         mov DH,VECTOR[BX][DI]

     Señala que el contenido de la posición de memoria cuya dirección viene indicada por la suma de los contenidos de los registros BX y DX y del desplazamiento establecido por el identificador VECTOR, sea copiado en DH.



Directivas (mas usadas)

EQU: Define nombres simbólicos que representan valores u otros valores simbólicos. Las dos formas son:
  •           Nombre EQU expresión.
  •           Nuevo_nombre EQU viejo_nombre

Una vez definido un nombre mediante EQU, no se puede volver a definir.

ASSUME: Sirve para indicar al ensamblador qué registro de segmento corresponde con un segmento determinado. Cuando el ensamblador necesita referenciar una dirección debe saber en qué registro de segmento lo apunta.
  • Sintaxis: ASSUME reg_segm: nombre [, reg_segm:nombre...]

donde el nombre puede ser de segmento o de grupo, una expresión utilizando el operador SEG o la palabra NOTHING, que cancela la selección de registro de segmento hecha con un ASSUME anterior.

.MODEL modelo: Debe estar ubicada antes de otra directiva de segmento. El modelo puede ser uno de los siguientes:
  • TINY: Los datos y el código juntos ocupan menos de 64 KB por lo que entran en el mismo segmento. Se utiliza para programas .COM. Algunos ensambladores no soportan este modelo.
  • SMALL: Los datos caben en un segmento de 64 KB y el código cabe en otro segmento de 64 KB. Por lo tanto todo el código y los datos se pueden acceder como NEAR.
  • MEDIUM: Los datos entran en un sólo segmento de 64 KB, pero el código puede ser mayor de 64 KB. Por lo tanto, código es FAR, mientras que los datos se acceden como NEAR.
  • COMPACT: Todo el código entra en un segmento de 64 KB, pero los datos no (pero no pueden haber matrices de más de 64 KB). Por lo tanto, código es NEAR, mientras que los datos se acceden como FAR.
  • LARGE: Tanto el código como los datos pueden ocupar más de 64 KB (pero no pueden haber matrices de más de 64 KB), por lo que ambos se acceden como FAR.
.STACK [size]: Define el segmento de pila de la longitud especificada. Si no se indica el tamaño, se reservan 1024 bytes.

.CODE [name]: Define el segmento de código cuando es empleada la directiva .MODEL

.DATA: Define un segmento de datos inicializados. Previamente debe ser usada la directiva .MODEL para especificar el modelo de memoria. L segmento es puesto en un grupo llamado Dgroup junto con los segmentos definidos por las directivas .Stack, .Const y .Data?

Ciclos de Maquina

     Cuando un microprocesador ejecuta una instrucción, éste realiza una serie de operaciones o tareas básicas llamadas ciclos de máquina. Estas tareas que involucran a las componentes internas del CPU, algunas veces a la memoria o a los puertos de entrada y salida, son coordinadas con las señales de interfaz generadas en la unidad de control en una secuencia ordenada.

Requerimientos de software de la PC

Características del sistema operativo

      El DOS es un sistema operativo que proporciona acceso general e independiente de los dispositivos a los recursos de la computadora. Los dispositivos que permite incluyen teclados, pantallas y unidades de disco. Por "independencia de dispositivos" debe entender que no es preciso dirigirse específicamente a los dispositivos, ya que el DOS y sus controladores de dispositivos pueden manejar las operaciones a nivel de dispositivo.

Organización del DOS

Los tres componentes principales del DOS son IO.SYS, MSDOS.SYS y COMMAND.COM.
    El IO.SYS realiza las funciones de inicialización en el momento del arranque y también contiene importantes funciones de E/S y controladores de dispositivos que dan el soporte de E/S básico en el BIOS de ROM. Este componente está almacenado en disco como un archivo de sistema oculto y es conocido como IBMBIO.COM en el PC-DOS.

      El MSDOS.SYS actúa como el núcleo (kernel) del DOS y se ocupa de la administración de archivos, de memoria y de entrada/salida. Este componente está almacenado en disco como un archivo de sistema y en el PC-DOS se conoce como IBMDOS.COM.

       COMMAND.COM es un procesador de comandos o shell que actúa como la interfaz entre el usuario y el sistema operativo. Muestra la indicación del DOS, monitorea el teclado y procesa los comandos del usuario, como borrado de un archivo o carga de un programa para su ejecución.

El Proceso de arranque

    Encender la computadora provoca una "inicialización" (algunos le llaman "arranque en frío"). El procesador introduce un estado de restauración, limpia todas las localidades de memoria (es decir, coloca cero en todas ellas), realiza una verificación de paridad de la memoria y asigna al registro CS la dirección del segmento FFFF[0]H y al registro IP el desplazamiento cero. Por tanto, la primera instrucción a ejecutarse está en la dirección formada por la pareja CS:IP, que es FFFFOH, la cual es el punto de entrada al BIOS en ROM.
        La rutina de BIOS que inicia en FFFFOH verifica los diferentes puertos para identificarlos
e inicializa los dispositivos que están conectados a la computadora. Después el BIOS establece dos
áreas de datos:

1. Una tabla de servicios de interrupción, que inicia en memoria baja en la localidad O y
contiene las direcciones de las interrupciones que ocurren.

2. Un área de datos de BIOS que inicia en la localidad 40[0], que está estrechamente relacionada
con los dispositivos conectados.

     A continuación el BIOS determina si está presente un disco que contenga los archivos de sistema del DOS y, en caso de que así sea, accesa el cargador de arranque desde ese disco. Este programa carga los archivos de sistema 10.SYS y MSDOS.SYS desde el disco hacia la memoria y transfiere el control al punto de entrada del IO.SYS, el cual contiene los controladores de dispositivos y otro código específico del hardware. El IO.SYS se reubica él mismo en memoria y transfiere el control al MSDOS.SYS. Este módulo inicializa las tablas internas del DOS y la porción del DOS de la tabla de interrupciones. También lee el archivo CONFIG.SYS y ejecuta sus comandos. Finalmente, el MSDOS.SYS pasa el control al C0MMAND.COM, el cual procesa el archivo AUTOEXEC.BAT, muestra su indicación y monitorea las entradas dadas desde el teclado.

Interfaz DOS-BIOS

      El BIOS contiene un conjunto de rutinas en ROM para dar soporte a los dispositivos. El BIOS prueba e inicializa los dispositivos conectados y proporciona los servicios que son usados para la lectura y escritura desde los dispositivos. Una tarea del DOS es hacer interfaz con el BIOS cuando exista una necesidad de accesar estas facilidades.
Cuando un programa usuario solicita un servicio del DOS, éste podría transferir la solicitud al BIOS, el cual a su vez accesa el dispositivo solicitado. Sin embargo, algunas veces un programa hace la petición directamente al BIOS, específicamente para servicios del teclado y de la pantalla. Y en otras ocasiones -aunque es raro y no recomendable- un programa puede pasar por alto tanto al DOS como al BIOS para accesar un dispositivo directamente. 

Sistema operativo

    Un sistema operativo es el software o programa más importante que se ejecuta en un computador, nos permite usarlo y darle órdenes para que haga lo que necesitamos. Son importantes, porque te permiten interactuar y darle órdenes al computador. Sin un sistema operativo el computador es inútil. 

Program Conter

     El registro almacena la dirección de la siguiente instrucción que el procesador debe ejecutar.


Stack pointer

     Apuntador de pila de 16 bits esta asociado con el registro SS, apunta a un área especifica de la memoria que sirve para almacenar datos bajo la estructura LIFO( ultimo en entrar, primero en salir)


Introducción al hardware de la PC (continuacion)

Registro de apuntador de instrucciones

      El registro apuntador de instrucciones (IP) de 16 bis contiene el desplazamiento de dirección de la siguiente instrucción que se ejecuta. El IP está asociado con el registro CS en el sentido de que el IP indica la instrucción actual dentro del segmento de código que se está ejecutando actualmente. Por lo común, usted no refiere el registro IP en un programa, pero, para probar un programa, sí puede cambiar su valor por medio del programa DEBUG del DOS. Los procesadores 80386 y posteriores tienen un IP ampliado de 32 bits, llamado EIP.
        En el ejemplo siguiente, el registro CS contiene 25A4[0]H y el IP contiene 412H. Para encontrar la siguiente instrucción que será ejecutada, el procesador combina las direcciones en el CS y el IP:

       Segmento de dirección en el registro CS: 25A40H
             Desplazamiento de dirección en el registro IP: + 412H
Dirección de la siguiente instrucción: 25E52H

Registros apuntadores

      Los registros SP (apuntador de la pila) y BP (apuntador base) están asociados con el registro SS y permiten al sistema accesar datos en el segmento de la pila.

Registro SP. El apuntador de la pila de 16 bits está asociado con el registro SS y proporciona un valor de desplazamiento que se refiere a la palabra actual que está siendo procesada en la pila. Los procesadores 80386 y posteriores tienen un apuntador de pila de 32 bits, el registro ESP. El sistema maneja de manera automática estos registros.
       En el ejemplo siguiente, el registro SS contiene la dirección de segmento 27B3[0]H y el SP, el desplazamiento 312H. Para encontrar la palabra actual que está siendo procesada en la pila, la computadora combina las direcciones en el SS y el SP:
Dirección de segmento en el registro SS: 27B30H
                                            Desplazamiento en el registro SP:            +  312H
                                            Dirección en la pila:                                 27E42H

Registro BP. El BP de 16 bits facilita la referencia de parámetros, los cuales son datos y direcciones transmitidos vía la pila. Los procesadores 80386 y posteriores tienen un BP ampliado de 32 bits llamado el registro EBP.

Registros índice

      Los registros SI y DI están disponibles para direccionamiento indexado y para sumas y restas.

Registro SI. El registro índice fuente de 16 bits es requerido por algunas operaciones con cadenas (de caracteres). En este contexto, el SI está asociado con el registro DS. Los procesadores 80386 y posteriores permiten el uso de un registro ampliado de 32 bits, el ESI.

Registro DI. El registro índice destino también es requerido por algunas operaciones con cadenas de caracteres. En este contexto, el DI está asociado con el registro ES. Los procesadores 80386 y posteriores permiten el uso de un registro ampliado de 32 bits, el EDI.

Registros de propósito general

     Los registros de propósito general AX, BX, CX y DX son los caballos de batalla del sistema. Son únicos en el sentido de que se puede direccionarlos como una palabra o como una parte de un byte. El último byte de la izquierda es la parte "alta", y el último byte de la derecha es la parte "baja". Por ejemplo, el registro CX consta de una parte CH (alta) y una parte CL (baja), y usted puede referirse a cualquier parte por su nombre. Las instrucciones siguientes mueven ceros a los registros CX, CH y CL, respectivamente.

     Los procesadores 80386 y posteriores permiten el uso de todos los registros de propósito general, más sus versiones ampliadas de 32 bits: EAX, EBX, ECX y EDX. Para poder usar los registros extendidos se debe especificar en el programa el procesador a usar porque sino arrojara un error en los registros

Registro AX. El registro AX, el acumulador principal, es utilizado para operaciones que implican entrada/salida y la mayor parte de la aritmética. Por ejemplo, las instrucciones para multiplicar, dividir y traducir suponen el uso del AX. También, algunas operaciones generan código más eficiente si se refieren al AX en lugar de a los otros registros.

Registro BX. El BX es conocido como el registro base ya que es el único registro de propósito general que puede ser un índice para direccionamiento indexado. También es común emplear el BX para cálculos.

Registro CX. El CX es conocido como el registro contador. Puede contener un valor para controlar el número de veces que un ciclo se repite o un valor para corrimiento de bits, hacia la derecha o hacia la izquierda. El CX también es usado para muchos cálculos.

Registro DX. El DX es conocido como el registro de datos. Algunas operaciones de entrada/salida requieren su uso, y las operaciones de multiplicación y división con cifras grandes suponen al DX y al AX trabajando juntos.

Registro de banderas

    De los 16 bits del registro de banderas, nueve son comunes a toda la familia de procesadores 8086, y sirven para indicar el estado actual de la máquina y el resultado del procesamiento. Muchas instrucciones que piden comparaciones y aritmética cambian el estado de las banderas, algunas de cuyas instrucciones pueden realizar pruebas para determinar la acción subsecuente. En resumen, los bits de las banderas comunes son como sigue:

OF (overflow, desbordamiento). Indica desbordamiento de un bit de orden alto (más a la izquierda) después de una operación aritmética.

DF (dirección). Designa la dirección hacia la izquierda o hacia la derecha para mover o comparar cadenas de caracteres.

IF (interrupción). Indica que una interrupción externa, como la entrada desde el teclado, sea procesada o ignorada.

TF (trampa). Permite la operación del procesador en modo de un paso. Los programas depuradores, como DEBUG, activan esta bandera de manera que usted pueda avanzar en la ejecución de una sola instrucción a un tiempo, para examinar el efecto de esa instrucción sobre los registros y la memoria.

SF (signo). Contiene el signo resultante de una operación aritmética (0 = positivo y 1 = negativo).

ZF (cero). Indica el resultado de una operación aritmética o de comparación (0 = resultado diferente de cero y 1 = resultado igual a cero). 

AF (acarreo auxiliar). Contiene un acarreo externo del bit 3 en un dato de ocho bits, para aritmética especializada.

PF (paridad). Indica paridad par o impar de una operación en datos de ocho bits de bajo orden (más a la derecha).

CF (acarreo). Contiene el acarreo de orden más alto (más a la izquierda) después de una operación aritmética; también lleva el contenido del último bit en una operación de corrimiento o de rotación.

        Las banderas están en el registro de banderas en las siguientes posiciones:


      Las banderas más importantes para la programación en ensamblador son O, S, Z y C, para operaciones de comparación y aritméticas, y D para operaciones de cadenas de caracteres. Los procesadores 80286 y posteriores tienen algunas banderas usadas para propósitos internos, en especial las que afectan al modo protegido. Los procesadores 80386 y posteriores tienen un registro extendido de banderas conocido como Eflags.

Y por ultimo para cerrar este capitulo hay que saber las conversiones mas básicas hexadecimal, binaria, decimal y octal.

Decimal:

       Los números con base 10 están compuestos de 10 posibles dígitos (0-9). Cada dígito de un numero tiene una potencia de 10 asociada con el, basada en su posición en el numero. Por ejemplo:


Binario
       Los números en base dos están compuestos de dos posibles dígitos (0 y 1). Cada dígito de un numero tiene una potencia de 2 asociada con el basada en su posición en el numero. Por ejemplo:

Hexadecimal

    Los numero hexadecimales tienen base 16. Los hexadecimales (o hex) se pueden usar como una representación resumida de los n´umeros binarios. Los números hexadecimales tienen 16 dígitos posibles. Esto crea un problema ya que no hay símbolos para estos dígitos adicionales después del nueve. Por convención se usan letras para estos dígitos adicionales. Los 16 dígitos hexadecimales son: 0-9 y luego A, B, C, D, E, F. El dígito A equivale a 10 en decimal, B es 11 etc. Cada dígito de un numero hexadecimal tiene una potencia de 16 asociada con el. Por ejemplo:


Octal

     El sistema numérico en base 8 se llama octal y utiliza los dígitos del 0 al 7.Tiene la ventaja de que no requiere utilizar otros símbolos diferentes de los dígitos. Sin embargo, para trabajar con bytes o conjuntos de ellos, asumiendo que un byte es una palabra de 8 bits, suele ser más cómodo el sistema hexadecimal, por cuanto todo byte así definido es completamente representable por dos dígitos hexadecimales.



Introducción al hardware de la PC

     Un programa en lenguaje ensamblador consiste en uno o más segmentos para definir datos y almacenar instrucciones de máquina y un segmento llamado stack (o pila) que contiene direcciones almacenadas.  

Bit

     La memoria del computador se compone de unidades de almacenamiento llamadas bits, que tienen dos estados posibles (representados por 0 y 1), es decir, sirven para almacenar números expresados en binario. La palabra bit proviene de la contracción binary digit (dígito binario). Así pues, todo lo que reside en la memoria del computador (códigos de instrucción y datos) están expresados por números binarios, a razón de un dígito binario por bit.

Bytes
    
      Los bits de la memoria se agrupan en bytes (u octetos), a razón de 8 bits por byte. Un byte es realmente la unidad de direccionamiento, es decir, podemos referirnos a cada byte mediante un número que es su dirección.

    La cantidad de memoria de un computador se mide en Kilobytes (cuya abreviatura es Kbyte, Kb o simplemente K), siendo:

                  1K = 1024 bytes

     Un byte puede almacenar números binarios de hasta ocho dígitos, lo cual corresponde a un rango de valores en decimal desde 0 hasta 255 inclusive.




Nibble

    La agrupación de los cuatro bits (superiores o inferiores) de un byte se llama nibble. Por lo tanto, un byte contiene dos nibbles. El que corresponde a los bits 0 al 3 se llama nibble inferior y el que corresponde a los bits 4 al 7 nibble superior.

     El nibble es una unidad de trabajo mucho más cómoda que el bit. En cada nibble se almacena un dígito
hexadecimal.


Caracteres ASCII.

  En los sistemas de numeración estudiados en apartados anteriores solamente es posible representar información numérica. Pero en muchos sistemas digitales, tanto de control como de proceso de datos, es necesario representar información alfabética y además algunos signos especiales, lo que ha dado lugar a la existencia de códigos alfanuméricos.

     De entre los diversos códigos alfanuméricos existentes, ha sido definido como código internacional el ASCII (American Standard Code for Information Interchange). En el mismo se representan todos los caracteres numéricos y alfabéticos así como ciertos caracteres de control, existiendo un código para cada carácter.

El Procesador

    Un elemento importante del hardware de la PC es la unidad del sistema, que contiene una tarjeta de sistema, fuente de poder y ranuras de expansión para tarjetas opcionales. Los elementos de la tarjeta de sistema son un microprocesador Intel (o equivalente), memoria de sólo lectura (ROM) y memoria de acceso aleatorio (RAM).
     El cerebro de la PC y compatibles es un microprocesador basado en la familia 8086 de Intel, que realiza todo el procesamiento de datos e instrucciones. Los procesadores varían en velocidad y capacidad de memoria, registros y bus de datos. Un bus de datos transfiere datos entre el procesador, la memoria y los dispositivos externos.

La familia de microprocesadores 80x86

8088/80188:  Estos procesadores tienen registros de 16 bits y un bus de datos de 8 bits, y pueden direccionar hasta un millón de bytes en memoria interna. Los registros pueden procesar dos bytes al mismo tiempo, mientras que el bus de datos sólo puede transferir un byte a la vez. El 80188 es un 8088 con mayor potencia por la adición de unas cuantas instrucciones. Ambos procesadores corren en lo que se conoce como modo real, esto es, un programa a la vez.

8086/80186: Estos procesadores son similares a los 8088/80188, pero tienen un bus de datos de 16 bits y corren más rápido. El 80186 es un 8086 más potente con unas cuantas instrucciones adicionales.

80286: Este procesador puede correr más rápido que los anteriores y direccionar hasta 16 millones de bytes. Puede correr en modo real o en modo protegido para multitareas.

80386: Este procesador tiene registros de 32 bits y un bus de datos de 32 bits, y puede direccionar hasta cuatro mil millones de bytes en memoria. Puede correr en modo real o en modo protegido para multitareas.

80486: Este procesador también tiene registros de 32 bits y un bus de datos de 32 bits (aunque algunos clones tienen un bus de datos de 16 bits) y está diseñado para mejorar el desempeño. Puede correr en modo real o en modo protegido para multitareas.

Unidad de ejecución y unidad de interfaz del bus




Memoria 

     El programa o secuencia de instrucciones, que debe seguir la máquina para realizar el procesamiento de los datos, está almacenado en una parte de la memoria, denominada memoria o segmento de instrucciones para diferenciarla del resto de la misma, que se emplea para guardar datos y resultados en forma temporal.
    La información, que recibe la memoria a través del bus de direcciones, es un conjunto de bits lógicos, tantos como líneas tenga el bus, que seleccionan la posición de memoria a la que se accede. El decodificador de direcciones se encarga de elegir una posición de la matriz de la memoria, descodificando la información que ha llegado por el bus de direcciones. Como generalmente la memoria está constituida físicamente por mas de un chip, será tarea del decodificador de direcciones habilitar al chip correspondiente.
    La microcomputadora posee dos tipos de memoria interna: memoria de acceso aleatorio (RAM) y memoria de sólo lectura (ROM). Los bytes en memoria se numeran en forma consecutiva, iniciando con 00, de modo que cada localidad tiene un número de dirección único.

Memoria ROM

     La memoria ROM (Read Only Memory) o memoria de sólo lectura también permite el acceso directo a cada uno de los elementos que la componen, pero la información en ella contenida puede ser leída pero no alterada. Debido a que conserva la información, aún en el caso de ausencia de energía, se usa para almacenar las rutinas de mas bajo nivel, que sirven para el arranque del sistema.

Memoria RAM

     La memoria RAM (Random Access Memory) o memoria de acceso al azar debe su nombre al hecho de permitir el acceso a cualquiera de las localidades de memoria en forma directa,pero su característica más importante es la de que la información contenida en cada una de las localidades puede ser leída y/o alterada. En ella se va a almacenar, por lo tanto, el sistema operativo y los programas del usuario, así como la información temporal que estos manejen.
  A la memoria RAM se le suele llamar memoria volátil, por el hecho de que la información en ellas almacenada, se pierde en ausencia de energía.

Buses

      Los buses no son más que los conductores que interconectan cada una de la partes que componen al
computador. A través de ellos viaja información que según su función permite clasificarlos en tres tipos: bus
de Datos, bus de Direcciones y bus de Control.

Bus de datos

     El bus de datos se encarga de transferir información entre el CPU, la memoria y los periféricos. Es bidireccional, ya que la información puede fluir en ambos sentidos, es decir, desde o hacia el microprocesador.

Bus de direcciones

   El bus de direcciones permite seleccionar la localidad de memoria o el periférico que el CPU desea accesar. Este bus es unidireccional ya que la información a través de él siempre fluye desde el microprocesador.

Bus de control

     En el Bus de Control se encuentran las diferentes señales encargadas de la sincronización y control del
sistema. Su naturaleza es unidireccional aun cuando existen señales que salen del microprocesador así como
otras que entran al microprocesador. Ejemplos de las señales de control son:

               WR (escritura)
               RD (lectura)
               WAIT (espera)
               READY (listo), etc.

Segmentos 
    Un segmento en modo real puede ser de hasta 64K. Se puede tener cualquier número de segmentos; para direccionar un segmento en particular basta cambiar la dirección en el registro del segmento apropiado. Los tres segmentos principales son los segmentos de código, de datos y de la pila.

Segmento de código

     El segmento de código (CS) contiene las instrucciones de máquina que son ejecutadas. Por lo común, la primera instrucción ejecutable está en el inicio del segmento, y el sistema operativo enlaza a esa localidad para iniciar la ejecución del programa. Como su nombre indica, el registro del CS direcciona el segmento de código. Si su área de código requiere más de 64K, su programa puede necesitar definir más de un segmento de código.

Segmento de datos

   El segmento de datos (DS) contiene datos, constantes y áreas de trabajo definidos por el programa. El registro del DS direcciona el segmento de datos. Si su área de datos requiere de más de 64K, su programa puede necesitar definir más de un segmento de datos.

Segmento de la pila

    En términos sencillos, la pila contiene los datos y direcciones que usted necesita guardar temporalmente o para uso de sus "llamadas" subrutinas. El registro del segmento de la pila (SS) direcciona el segmento de la pila.

y hay un cuarto segmento que es el segmento extra

Segmento extra

     El segmento extra (ES), puede ser usado para almacenar información. Es frecuentemente usado para
operaciones de transferencia de contenidos de bloques de memoria. Las instrucciones para
manipulación de cadenas del 80x86, emplean este segmento.

Registros

   Los registros del procesador se emplean para controlar instrucciones en ejecución, manejar direccionamiento de memoria y proporcionar capacidad aritmética. Los registros son direccionables por medio de un nombre. Los bits, por convención, se numeran de derecha a izquierda, como en:
... 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Registros de segmento

       Un registro de segmento tiene 16 bits de longitud y facilita un área de memoria para direccionamiento conocida como el segmento actual. Como hemos dicho, un segmento se alinea en un límite de párrafo y su dirección en un registro de segmento supone cuatro bits 0 a su derecha.

Registro CS. El DOS almacena la dirección inicial del segmento de código de un programa en el registro CS. Esta dirección de segmento, más un valor de desplazamiento en el registro de apuntador de instrucción (IP), indica la dirección de una instrucción que es buscada para su ejecución. Para propósitos de programación normal, no se necesita referenciar el registro CS.

Registro DS. La dirección inicial de un segmento de datos de programa es almacenada en el registro DS. En términos sencillos, esta dirección, más un valor de desplazamiento en una instrucción, genera una referencia a la localidad de un byte específico en el segmento de datos.

Registro SS. El registro SS permite la colocación en memoria de una pila, para almacenamiento temporal de direcciones y datos. El DOS almacena la dirección de inicio del segmento de pila de un programa en el registro SS. Esta dirección de segmento, más un valor de desplazamiento en el registro del apuntador de la pila (SP), indica la palabra actual en la pila que está siendo direccionada. Para propósitos de programación normal, no se necesita referenciar el registro SS.

Registro ES. Algunas operaciones con cadenas de caracteres (datos de caracteres) utilizan el registro extra de segmento para manejar el direccionamiento de memoria. En este contexto, el registro ES está asociado con el registro DI (índice). Un programa que requiere el uso del registro ES puede inicializarlo con una dirección de segmento apropiada.

Registros FS y GS. Son registros extra de segmento en los procesadores 80386 y posteriores.





Ejemplo sencillo

Ejemplo de separar numero pares de impares                         .model small .stack 100h      ;tamaño de l...