Sei sulla pagina 1di 61

Tabla de contenidos

Prembulo
1. Generalidades
1.1. Sistemas numricos 1.1.1. Sistema decimal 1.1.2. Sistema binario 1.1.3. Conversin
entre decimal y binario 1.1.4. Operaciones matemticas bsicas en base dos 1.1.5.
Operaciones lgicas 1.1.6. El sistema hexadecimal 1.1.6.1. Conversin entre hexadecimal y
decimal 1.1.6.2. Conversin entre hexadecimal y binario 1.1.7. Representacin de datos
1.1.7.1. Bit 1.1.7.2. Nibble 1.1.7.3. Byte 1.1.7.4. Palabra 1.1.7.5. Palabra doble 1.1.7.6.
Cudruple palabra 1.1.7.7. Mltiplos del byte 1.1.7.8. Nmeros con y sin signo 1.1.7.9.
Nmeros reales 1.1.7.9.1. Inexactitudes en la representacin de los nmeros reales en
binario 1.1.7.10. Little Endian vs Big Endian 1.2. Registros 1.2.1. Registros de propsito
general 1.2.2. Registros de segmento 1.2.3. Registros punteros de pila 1.2.4. Registros
ndices 1.2.5. Puntero de instrucciones o contador de programa 1.2.6. Registro de estado o
de indicadores (flags) 1.2.7 Resumen grfico del conjunto de registros del 8086: 1.2.7.1.
Registros de propsito general 1.2.7.2. Registros Punteros de Pila 1.2.7.3. Registro Puntero
de Instrucciones 1.2.7.4. Registros de Segmento 1.2.7.5. Registros de ndice 1.2.7.6.
Registro de banderas 1.3. Puertos de entrada/salida 1.4. Organizacin de direcciones:
Segmentacin 1.4.1. Modos de direccionamiento 1.4.2. Tipos de direccionamiento 1.4.3. La
pila 1.4.4. Memoria Interna 1.4.5. Memoria Convencional 1.4.6. Segmentos de Ensamblador
1.4.6.1. Alineacin 1.4.6.2. Combinacin 1.4.6.3. Clase 1.4.6.4. Acceder a datos de
Segmento 1.4.6.5. Tipos de Modelos de Memoria 1.4.6.6. Smbolos Predefinidos 1.5.
Programas ejecutables sobre MS-DOS 1.5.1. El PSP 1.5.2. Programas COM 1.5.2.1. Creacin
de un programa COM en ensamblador 1.5.3. Programas EXE 1.6. Diferencias entre las
sintaxis 1.6.1. Diferencias entre NASM y MASM 1.6.1. Diferencias entre NASM y FASM
2. Hola Mundo
2.1. Hola, Mundo!- COM 2.1.1. Sintaxis MASM 2.1.1.1. MundoCM1.asm 2.1.1.2.
MundCM1b.asm 2.1.1.3. MundoCM2.asm 2.1.1.4. MundoCM3.asm 2.1.1.5. MundoCM5.asm
2.1.2. Sintaxis NASM 2.1.2. Sintaxis FASM 2.2. Hola, Mundo!- EXE 2.2.1. Sintaxis MASM
2.2.1.1. MundoXM1.asm 2.2.1.2. SegGrpM1.asm 2.2.1.3. SegtosM1.asm 2.2.2. Sintaxis
NASM 2.2.2.1. MundoXN1.asm 2.2.2.2. SegGrpN1.asm 2.2.2.3. SegtosN1.asm 2.2.3. Sintaxis
FASM 2.2.3.1. MundoXF1.asm 2.2.3.2. SegtosF1.asm
3. Datos
3.1. Datos Simples 3.1.1.Constantes 3.1.2.Caracteres 3.1.3.Enteros Pequeos - Bytes
3.1.4.Enteros - Word 3.1.5.Enteros Dobles - Double Word 3.1.6.Enteros Largos QWord
3.1.7.Enteros Extendidos TWord 3.1.8.Reales Simples 3.1.9.Reales Largos 3.1.10.Reales
Extendidos 3.1.11.Cadenas de Caracteres 3.1.12. Matrices 3.2. Datos Complejos 3.2.1. Tipos
3.2.2. Punteros 3.2.2.1. Punteros a punteros 3.2.2.2. Punteros a matrices 3.2.2.3. Punteros a
estructuras 3.2.2.4. Matrices de punteros 3.2.2.5. Estructuras de punteros 3.2.3. Estructuras
3.2.3.1. Alineacin 3.2.3.2. Punteros a Estructuras 3.2.3.3. Estructuras de Punteros 3.2.3.4.
Matrices de Estructuras 3.2.3.5. Estructuras Anidadas 3.2.4. Uniones 3.2.5. Campos de Bits
(Records) 3.3.Ejercicios
4. Control de flujo
4.1. Saltos 4.1.1. Direcciones Corta, Cercana y Lejana 4.1.2. Etiquetas 4.1.2.1.mbito de las
etiquetas 4.1.2.1.Etiquetas annimas 4.1.2. Saltos incondicionales 4.1.3.1. Saltos Cortos
4.1.3.2. Saltos Cercanos 4.1.3.1. Saltos Lejanos 4.1.4. Instrucciones de testeo 4.1.4.1.La
bandera de acarreo (CF) 4.1.4.2.La bandera de paridad (PF) 4.1.4.3.La bandera auxiliar (AF)
4.1.4.4.La bandera de cero (ZF) 4.1.4.5.La bandera de signo (SF) 4.1.4.6.La bandera de
trazado (TF) 4.1.4.7.La bandera de interrupciones (IF) 4.1.4.8.La bandera de direccin (DF)

4.1.4.9.La bandera de desbordamiento (OF) 4.1.5.Decisiones 4.1.6. Bucles 4.1.7. Saltos


condicionales
5. Procedimientos
5.1. Procedimientos 5.1.1. Utilidades de la directiva PROC 5.1.1.1. Salvaguarda de registros
5.1.1.1. Parmetros 5.1.1.3. VARARG 5.1.1.4. INVOKE 5.1.1.5. Variables Locales 5.1.1.6.
Etiquetas Locales 5.1.2. Llamadas lejanas 5.2. Macros
6. Aritmtica y lgica
6.1. Operaciones matemticas 6.1.1. Las instrucciones "INC" y "DEC" 6.1.2. Suma y resta
6.1.3. Multiplicacin y divisin 6.1.4. Extensin de signo 6.1.5. Rotaciones y
desplazamientos 6.1.5.1. Instrucciones de desplazamiento 6.1.5.2. Instrucciones de rotacin
6.1.6. El nmero opuesto, NEG 6.1.6. Datos BCD 6.1.6.1. BCD desempaquetado 6.1.6.2. BCD
empaquetado 6.1.8. Extra! 6.1.8.1. Nmeros en pantalla 6.1.8.2. Operaciones matemticas
con nmeros grandes 6.2. Coprocesador Matemtico 6.2.1. El coproceso 6.2.2. Constantes
6.2.3. Arquitectura del 8087 6.2.4. La pila 6.2.5. Tipos de datos 6.2.5.1. Enteros 6.2.5.2.
Empaquetados 6.2.5.3. Reales 6.2.5.4. Formato de cada tipo de dato 6.2.6. Directivas de
definicin de datos 6.2.7. El entorno 6.2.7.1. Palabra de estado (1) 6.2.7.2. Palabra de
control (2) 6.2.7.3. Palabra tag (3) 6.2.7.4. Palabras de direcciones (4 a 7) 6.2.8. Tratamiento
de excepciones 6.2.9. Instrucciones y formato de operaciones 6.2.9.1. Formato de pila
clsica 6.2.9.2. Formato de memoria 6.2.9.3. Formato de registro 6.2.9.4. Formato de
registro POP 6.2.10. Coordinando el acceso a memoria 6.2.11. Instrucciones del
coprocesador 6.2.11.1. Instrucciones de transferencia de datos 6.2.11.2. Instrucciones
aritmticas 6.2.11.3. Instrucciones de comparacin 6.2.11.4.Instrucciones de clculo de
funciones trascendentes 6.2.11.5. Instrucciones relativas a constantes 6.2.11.6.
Instrucciones de control del microprocesador 6.2.12.Ejemplo prctico 6.2.13. Diferencias
entre MASM, NASM y FASM 6.3. Ejercicios
7. Datos (2)
7.1. Manejo de matrices 7.1.1. Instrucciones comunes 7.1.1.1. LODS 7.1.1.2. STOS 7.1.1.3.
MOVS 7.1.1.4. SCAS 7.1.1.5. CMPS 7.1.1.6. XLAT 7.1.1.7. Bsqueda de cadenas 7.2. Mtodos
de ordenacin y bsqueda 7.2.1. Mtodos de ordenacin 7.2.1.1. Primer mtodo de la
burbuja 7.2.1.2. Segundo mtodo de la burbuja 7.2.1.3. Mtodo de la burbuja con ndices
7.2.1.4. Mtodo de la ordenacin rpida 7.2.1.5. Ordenacin por mltiples claves 7.2.1.6.
Ordenacin indexada por mltiples claves 7.2.1.6. Visualizacin de trabajos de ordenacin
7.2.1. Mtodos de bsqueda 7.2.2.1. Bsqueda lineal 7.2.2.2. Bsqueda binaria 7.2.2.3.
Bsqueda binaria indexada 7.2.2.4. Bsqueda sobre datos numricos 7.2.2.5. Fonemas
semejantes 7.2.2.6. Insercin y borrado de datos (I) 7.3. Listas 7.3.1. Procedimientos
disponibles para listas en AOE 7.3.1.1. Colas simplemente enlazadas 7.3.1.2. Colas
doblemente enlazadas 7.3.1.3. Pilas simplemente enlazadas 7.3.1.4. Variables necesarias
7.3.1.5. Mensajes de error 7.3.2. Colas simplemente enlazadas 7.3.3.Pilas simplemente
enlazadas 7.3.4. Colas doblemente enlazadas 7.3.5. Pilas doblemente enlazadas 7.3.6. Colas
simplemente enlazadas circulares 7.3.7. Pilas simplemente enlazadas circulares 7.3.8. Colas
doblemente enlazadas circulares 7.3.9. Pilas doblemente enlazadas circulares 7.3.10. Listas
multidimensionales 7.4. rboles 7.4.1. rbol binario 7.4.1.1. Recorrido de rboles binarios
7.4.1.2. rboles binarios de bsqueda
8. La pantalla
8.1. La pantalla 8.1.1. Componentes de una tarjeta de vdeo 8.1.2. Retraso horizontal y
vertical 8.1.3. Programacin del C.R.T.C. 8.1.4. Modos de vdeo 8.1.5. Pginas de vdeo 8.1.6.
Interrupciones software para escribir en memoria de vdeo 8.1.6.1. Interrupciones DOS
8.1.6.2. Interrupciones BIOS 8.1.7. Escritura directa en el bfer de vdeo 8.1.8. La paleta

8.1.8.1. El color 8.1.8.2. Ejemplos 8.1.9. Ejemplos completos en modo texto 8.1.9.1. Copper
bars 8.1.9.2. Foco 8.1.9.3. Caleidoscopio 8.1.9.4. Tetris 8.1.9.5. Depuracin
9. El teclado
9.1. El teclado 9.1.1. Distribucin del teclado 9.1.2. rea de datos del teclado 9.1.3. El bfer
del teclado 9.1.4. Cdigos scan 9.1.5. Interrupcin 21h DOS para el teclado 9.1.5.1. Funcin
1 9.1.5.2. Funcin 6 9.1.5.3. Funcin 7 9.1.5.4. Funcin 8 9.1.5.5. Funcin 0Ah 9.1.5.6.
Funcin 0Bh 9.1.5.7. Funcin 0Ch 9.1.6. Interrupcin 16h BIOS para el teclado 9.1.6.1.
Funcin 0 9.1.6.2. Funcin 1 9.1.6.3. Funcin 2 9.1.6.4. Funcin 3h 9.1.6.4. Funcin 10h
9.1.6.5. Funcin 11h 9.1.6.6. Funcin 12h
10. Ficheros
10.1. Gestin de Ficheros 10.1.1. Estructura fsica del disco 10.1.1.1. rea de Sistema
10.1.1.2. rea de datos 10.1.2. Operaciones de la BIOS para disco 10.1.2.1. Byte de estado
de la BIOS 10.1.3. Operaciones MS-DOS para disco con FCBs 10.1.4. Operaciones MS-DOS
para disco con handles 10.1.4.1. Manejadores de archivos 10.1.4.2. Atributos de archivo
10.1.4.3. Formato de fecha y hora de los archivos 10.1.4.4. Cdigos de error en acceso a
disco 10.1.4.5. Funciones Handle de acceso a disco 10.1.5. Bsqueda de ficheros con MSDOS 10.1.5.1. Estructura de la DTA 10.1.5.2. Funciones de bsqueda de ficheros 10.1.6.
Funciones avanzadas MS-DOS para disco 10.1.7. Los buffers de archivo 10.2. Mtodos de
acceso a los archivos 10.2.1. Acceso secuencial a archivos 10.2.1.1. Creacin y escritura de
archivos 10.2.1.2. Apertura y cierre de archivos 10.2.1.3. Lectura y escritura de datos
10.2.1.4. EOF (End Of File o fin de fichero) 10.2.1.5. Seek (buscar) 10.2.2. Acceso aleatorio a
archivos 10.2.2.1. Escritura de un archivo aleatorio 10.2.2.2. Lectura de un archivo aleatorio
10.2.3. Acceso binario a archivos 10.2.3.1. Escritura de un archivo binario 10.2.3.2. Lectura
de un archivo binario 10.2.4. Otros procesos sobre archivos 10.2.4.1. Borrar ficheros
10.2.4.2. Buscar ficheros 10.2.4.3. Volcar el contenido de un fichero a la pantalla
11. Interrupciones
11.1. Interrupciones 11.1.1. Polling versus Interrupciones 11.1.1.1. Polling 11.1.1.2.
Interrupciones 11.1.1.3. Conclusin 11.1.2. Interrupciones internas o excepciones 11.1.3.
Interrupciones hardware (IRQs) 11.1.4. Interrupciones software 11.1.4.1. Localizacin
11.1.4.2. Ejemplo / traceo 11.1.4.3. Proceso de la interrupcin 11.1.5.Tabla de interrupciones
del sistema 11.1.6. ISRs 11.1.6.1. Preservar contenido de registros 11.1.6.2. Deshabilitar
ejecucin de interrupciones 11.1.6.3. Reservar suficiente espacio de pila 11.1.7. Gestin de
interrupciones 11.1.7.1. Interrupciones para gestin de interrupciones 11.1.7.2. Mtodos
para la gestin de interrupciones 11.1.8. Ejemplos 11.1.8.1. Int 4h 11.1.8.2. Int 21h
11.1.8.3. Int 9h 11.1.8.4. Int 8h 11.1.8.5. Reloj en tiempo real 11.1.8.6. Muestra teclado
11.1.8.7. Hora y fecha actuales 11.1.8.8. Establece rutina propia para interrupcin 11.1.8.9.
Buscar Interrupcin 11.1.9. Interrupcin Multiplex
12. Gestin de la memoria
12.1. Gestin de Memoria 12.1.1. Mapa de la memoria del MS-DOS 12.1.1.1. Tipos de
memoria 12.1.1.1.1. Memoria convencional 12.1.1.1.2. rea de Memoria Superior (Upper
Memory Area UMA) 12.1.1.1.2. Mapa de la Memoria Superior 12.1.1.1.3. Memoria Superior
ROM y RAM 12.1.1.1.4. Memoria Expandida (Expanded Memory EMS) 12.1.1.1.5. Bloques
de Memoria Superior (UMBs) 12.1.1.1.6. ROM Shadowing 12.1.1.1.7. Area de Memoria Alta
(High Memory Area HMA) 12.1.1.1.8. Memoria Extendida 12.1.1.1.9. Memoria Cach
12.1.1.1.10. Memoria CMOS RAM 12.1.2. Bloques de memoria 12.1.2.1. Tipos de bloques de
memoria 12.1.2.1.1. Bloques de memoria del programa 12.1.2.1.2. Bloques de entorno
12.1.2.1.3. Bloques de control de memoria (MCB's) 12.1.2.1.4. Bloques de sistema
12.1.2.1.5. Bloques de datos 12.1.2.1.6. Bloque libre 12.1.2.2. Liberar el espacio de entorno
en programas residentes 12.1.2.3. Redimensionamiento de un bloque de memoria 12.1.2.4.

Asignar espacio de memoria 12.1.3. Llamada a subprocesos y recubrimientos u overlays


12.1.3.1. Carga y ejecucin de subprogramas 12.1.3.2. Carga y ejecucin de overlays 12.2.
TSRs 12.2.1. Interrupciones implicadas 12.2.2. Clasificacin de los TSRs 12.2.3. Problemas
con los TSRs 12.2.3.1. El DOS no es reentrante 12.2.3.2. Acciones crticas en tiempo
12.2.3.3. Reinstalacin 12.2.3.4. Activacin retardada 12.2.3.5. Preservar el contexto
12.2.3.6. Alterar el funcionamiento del sistema 12.2.3.7. La BIOS tampoco es reentrante
12.2.3.8. Tamao y velocidad 12.2.3.9. Reinstalacin y desinstalacin 12.2.4. Ejemplos
12.2.4.1. Reloj residente con reinstalacin 12.2.4.2. Reloj en tiempo real sin reinstalacin
12.2.4.3. Reloj en tiempo real sin reinstalacin y con desinstalacin 12.2.5. La pila y el PSP
12.2.5.1. Definir una pila para la parte residente 12.2.5.2. Cambio del PSP activo 12.2.5.3.
Cambio del DTA (Disk Transfer Area) 12.2.5.4. Ejemplo 12.2.6. Problemas con la reentrada
del DOS 12.2.6.1. Los indicadores InDOS y ErrorMode 12.2.6.2. Indicador en ISR 12.2.6.3.
Ejemplo 12.2.7. Otros aspectos a tener en cuenta 12.2.7.1. Informacin extendida de
errores 12.2.7.2. Int 13h, funciones de acceso a disco 12.2.7.3. Gestin de errores crticos
12.2.7.4. Divisin por cero 12.2.7.4. Control-C y Control-Inter 12.2.8. Salvaguarda del
entorno 12.2.8.1. La pantalla 12.2.8.2. El teclado 12.2.8.3. El ratn 12.2.9. Ejemplos
12.2.9.1. Salvapantallas 12.2.9.2. Salvapantallas con control de varias interrupciones
12.2.9.3. Salvapantallas con foco 12.3. Memoria CMOS 12.3.1. Breve resea histrica
12.3.2. El acceso a la CMOS 12.3.3. Organizacin de la CMOS reloj 12.3.4. Organizacin de
la CMOS no Reloj 12.3.5. Ejemplos 12.3.5.1. Disqueteras instaladas 12.3.5.2. Memoria
instalada 12.3.5.3. Retardo y ratio typematic 12.4. Memoria expandida y extendida 12.4.1.
Lnea A20 12.4.2. Memorias extendida y superior XMS 12.4.2.1. El gestor XMS 12.4.2.
Memoria expandida EMS 12.5. Acceso Directo a Memoria (DMA) 12.5.1. Operacin bsica
del DMA 12.5.2. Definiciones bsicas del DMA 12.5.3. El controlador de DMA 8237 12.5.3.1.
Definicin de las terminales 12.5.3.2. Registros internos 12.5.3.3. Comandos de software
12.5.3.4. Programacin de los registros de direccin y de cuenta 12.5.3.5. Canales y puertos
12.5.3.6. Mensajes de error 12.5.3.7. Ejemplo
13. Recursividad
13.1. Recursividad 13.1.1. Ejemplos de definiciones recursivas 13.1.1.1. Nmeros naturales
13.1.1.2. Estructuras de rbol 13.1.1.3. La funcin factorial f(n) = n! 13.1.2. Potencia de la
recursin 13.1.3. Tipos de objetos recursivos 13.1.3.1. Recursividad algortmica 13.1.3.2.
Recursividad en datos 13.1.4. Recursividad algortmica 13.1.5. Ejemplos de recursividad
13.1.5.1. Recursividad de cola sin parmetros 13.1.5.2. Recursividad de cola con parmetros
13.1.5.3. Recursividad interna sin parmetros 13.1.5.4. Recursividad interna con parmetros
13.1.5.5. Recursividad en datos 13.1.6. Cundo no utilizar la recursin 13.1.6.1. Clculo del
factorial de un nmero con recursividad 13.1.6.2. Clculo del factorial de un nmero sin
recursividad 13.1.7. Cundo utilizar la recursin 13.1.7.1. Mtodo recursivo 13.1.7.2. Mtodo
no recursivo 13.1.8. Algoritmos de rastreo inverso 13.1.8.1. El problema de las ocho reinas
14. La impresora
14.1. Impresora 14.1.1. Operaciones bsicas de interrupcin 14.1.2. Caracteres comunes de
control de impresora 14.1.2.1. Tabulacin horizontal 14.1.2.2. Avance de lnea (LF) 14.1.2.3.
Retorno de carro 14.1.2.4. Avance de pgina (FF) 14.1.3. Ejemplos
15. El ratn
15.1. El ratn 15.1.1. Definiciones bsicas del ratn 15.1.2. Operaciones comunes del ratn
15.1.3. Mtodos de control del ratn 15.1.3.1. Control del ratn mediante sondeos sucesivos
15.1.3.2. Control del ratn mediante manejo de interrupciones 15.1.4. Otras funciones
interesantes del ratn 15.1.4.1. Modificacin del aspecto del cursor del ratn 15.1.4.2.
Constriccin del movimiento del cursor del ratn
16. El joystick

16.1. Joystick 16.1.1. Breve historia del Joystick 16.1.2. Estructura del Joystick 16.1.3.
Conector del Joystick 16.1.4. Cmo trabaja el hardware del puerto del joystick 16.1.4.1.
Entrada analgica de resistencia (posicin del joystick) 16.1.4.2. Entrada de conmutadores
(botones del joystick) 16.1.5. Cmo programar el joystick analgico 16.1.5.1. Funciones
BIOS 16.1.5.2. Lectura directa del puerto de juegos
17. Control del tiempo
17.1. El tiempo 17.1.1. Usando interrupciones 17.1.2. Accediendo a la informacin de la
BIOS directamente 17.1.3. Interceptando la interrupcin 1Ch o 8h 17.1.4. Usando el refresco
de pantalla 17.1.5. Multiretardo 17.1.6. Programacin del PIT 17.1.6.1. Canales del PIT
17.1.6.1.1. El canal 0 17.1.6.1.2. El canal 1 17.1.6.1.3. El canal 2 17.1.6.2. El registro de
modo/comando en el puerto 43h 17.1.6.3. Cmo programar el canal 0 a una frecuencia
diferente 17.1.6.4. Riesgos a tener en cuenta 17.1.6.5. Otra forma de usar el PIT
18. El sonido en el PC
18.1. El altavoz del PC 18.1.1. El sonido 18.1.1.1. Problemas del sonido 18.1.1.2. Ejemplo
18.1.2. El sonido sobre el PC 18.1.3. Funcionamiento del altavoz del PC 18.1.3.1. Control
directo del altavoz 18.1.3.2. Control del altavoz mediante el temporizador 18.1.4. Notas
musicales 18.1.5. Melodas 18.1.6. Melodas de fondo 18.1.7. Msica digital por el altavoz
18.1.7.1. Ficheros de sonido digital 18.1.7.2. Formato de fichero wav 18.1.7.3. Otros
formatos de sonido digital 18.1.7.3.1. Formato MOD 18.1.7.3.2. Formato S3M 18.1.7.3.3.
Formato XM 18.1.7.3.4. Formato MID y MID+Audio 18.1.7.4. Programas para la creacin de
canciones y formatos musicales 18.1.7.4.1. Trackers 18.1.7.4.2. Secuenciadores 18.1.7.4.3.
Trackers de ejemplo 18.2. Sound Blaster
19. Interfaces con lenguajes de alto nivel (HLL)
19.1. Interfaces del ensamblador 19.1.1. Elementos que intervienen en la interfaz 19.1.2. La
interfaz 19.1.2.1. El control del flujo 19.1.2.2. El acceso a los datos 19.1.3. Seguridad 19.2.
Subrutinas y enlace 19.2.1. Linkado 19.2.1.1. PUBLIC nombre 19.2.1.2. EXTRN nombre: tipo
19.2.2. Fin del mdulo principal 19.2.3. Ensamblado y linkado 19.3. Interfaz con Pascal
19.3.1. Tipos de Interfaz con Turbo Pascal 19.3.1.1. Interfaz interna 19.3.1.1.1. Parmetros
en los procedimientos 19.3.1.1.2. Ejemplos 19.3.1.2. Interfaz externa 19.3.1.2.1. Ejemplos
19.3.2. Virtual Pascal y Free Pascal 19.4. Interfaz con C 19.4.1. Comunicacin entre C y
ensamblador 19.4.2. Ejemplos 19.4.3. Pelles C 19.4.3.1. Ejemplos 19.4.3. Tiny C 19.4.3.1.
Ejemplos 19.5 Interfaz con Basic 19.5.1. Ejemplos 19.5.1.1. Interfaz interna 19.5.1.2.
Interfaz externa 19.5.1.3. Creacin de Quick Libraries 19.5.2. Visual Basic y Rapid QBasic
19.6. Mdulos en ensamblador 19.6. Depurar
20. Programacin Windows
20.1. Programacin Windows 20.1.1. Antes de empezar 20.1.1.1. Definiciones bsicas
20.1.1.1.1. La pila (registro SS) 20.1.1.1.2. Los registros de bandera 20.1.1.2. Cuentas
previas 20.1.1.3. Instalacin de paquetes 20.1.1.4. RADs para ensamblador 20.1.1.5.
Inclusin de definiciones y bibliotecas 20.1.1.6. Los programas que vamos a ver 20.1.2.
Programas de consola Windows 20.1.3. Primer programa Windows con ventanas 20.1.4.
Primera ventana Windows 20.1.4.1. Ventana simple Windows 20.1.4.2. Ventana con resource
externo Windows 20.1.4.3. Ventana con resource interno Windows 20.1.5. Texto en la
ventana Windows 20.1.5.1. Texto con DrawText 20.1.5.2. Texto con CreateWindowEx,
posicin libre 20.1.5.3. Texto customizado 20.1.5.4. Texto con gdi 20.1.5.5. Texto con
resources 20.1.5.6. Hiperenlace con resources externos 20.1.6.6. Hiperenlace con resources
internos 20.1.7. Dibujo en la ventana Windows 20.1.7.1. Caleidoscopio con gdi y
WinMain.msg_loop 20.1.7.2. Caleidoscopio con gdi y WndProc.TIMER 20.1.7.3. Ejemplo de
grficos con gdi 20.1.7.4. Ejemplo de grficos con gdi 20.1.7.5. BMP con resource en
Windows 20.1.7.6. Cargando un BMP en nuestra ventana 20.1.8. Objetos en nuestra

ventana 20.1.8.1. Botones en Windows y mensaje no modal 20.1.8.2. Botones en Windows y


mensaje modal 20.1.8.3. Botones, checkbox, radiobuttons, info en resource 20.1.9.
Diferentes tipos de botones con y sin imgenes 20.1.9.1. Texto customizado en botn
20.1.9.2. Botones con doble imagen, customizacin de cursor sobre botn 20.1.10. Ejemplos
de menes en Windows 20.1.10.1. Men simple 20.1.10.2. Men con iconos 20.1.11. Uso del
ratn en Windows 20.1.11.1. Coordenadas del ratn 20.1.12. Common Controls para
ficheros en Windows y tooltip 20.1.12.1. Common Controls para ficheros en Windows y
tooltip 20.1.13. Ejemplo de DLLs 20.1.13.1. Ejemplo de DLLs 20.1.14. Depuracin en
Windows
21. Programacin Linux
21.1. Programacin Linux
22. Programacin grfica
22.1. Programacin grfica 22.1.1. Algunas definiciones 22.1.1.1. Pixel 22.1.1.2. Profundidad
de color 22.1.1.3. El bfer de vdeo 22.1.1.4. El color 22.1.1.5. La paleta de colores 22.1.1.6.
Organizacin de la memoria en modo 13h 22.1.1.7. Modos grficos 22.1.1.8. Razn de
aspecto
23. Lneas grficas
23.1. Lneas 23.1.1. Ecuacin de la pendiente de la recta 23.1.2. Algoritmo de Bresenham
23.1.2.2. Ejemplo 23.1.2.2.1. Abanico de lneas grficas 23.1.2.2.2. Completitud de recuadro
con lneas 23.1.3. Recorte (Clipping) 23.1.3.1. Dibujo de punto con recorte 23.1.3.2.
Algoritmo de Sutherland-Cohen 23.1.3.3. Depuracin
24. Rectngulos
24.1. Rectngulos 24.1.1. Rectngulos y razn de aspecto 24.1.2. Ejemplo
25. Elipses
25.1. Elipses 25.1.1. Algoritmo del punto medio para dibujar crculos. 25.1.2.Crculos y razn
de aspecto 25.1.3. Algoritmo para dibujar elipses 25.1.3.1. Conversin de barrido de una
elipse 25.1.3.2. Algoritmo incremental 25.1.4. Algoritmo para dibujar circunferencias y
crculos 25.1.5. Ejemplos
26. Rellenado de regiones
26.1. Rellenado de regiones 26.1.1. Definicin de regin 26.1.1.1. Pixels del interior y del
borde 26.1.1.2. Conectividad 26.1.2. Algoritmo de rellenado de regiones 26.1.3. Ejemplo
27. La paleta grfica
27.1. La paleta 27.1.1. Qu es la paleta 27.1.1.1. Leer de la paleta 27.1.1.2. Establecer la
paleta 27.1.1.3. Evitar las interferencias 27.1.2. Ejemplos 27.1.2.1. Colores de la paleta
estndar 27.1.2.2. Colores producidos por mezcla de RGB 27.1.2.3. Fade in y Fade out
27.1.2.4. Efecto grfico rotando la paleta 27.1.2.5. Ms efectos grficos rotando la paleta
28. Formatos grficos
28.1. Algunos formatos grficos 28.1.1. Formato RAW 28.1.2. Formato PCX 28.1.3. Formato
BMP 28.1.4. Extra
29. Pantallas virtuales
29.1. Pantallas virtuales 29.1.1. Qu es una pantalla virtual 29.1.1.1. Pantallas virtuales en
13h 29.1.2. Ejemplos 29.1.2.1. Rebote de pelota simple 29.1.2.2. Rebote de pelota

esperando el comienzo del retrazo 29.1.2.3. Rebote de pelota mediante pantalla virtual
29.1.2.4. Rebote de varias pelotas mediante pantalla virtual
30. Texto en modo grfico
30.1. Texto en modo grfico 30.1.1. Fuentes del sistema 30.1.1.2. Soporte del BIOS de vdeo
30.1.1.3. Caracteres por defecto en VGA y MCGA 30.1.2. Generador de caracteres software
30.1.2.1. Manipulacin de pixels 30.1.2.2. Recorte 30.1.3. Ejemplos 30.1.3.1. Fuentes 8x8 de
la BIOS 30.1.3.2. Fuentes 8x16 de la BIOS 30.1.3.3. Fuentes 8x16 del usuario 30.1.3.4. Otras
fuentes del usuario 30.1.5. Ms all
31. Seno y coseno
31.1. Funciones seno y coseno 31.1.1. Definicin 31.1.1.1. Razones trigonomtricas 31.1.2.
Metodologa 31.1.2.1. Regla de clculo 31.1.3. Ejemplo: espiral 31.1.3.1. Ejemplo con tablas
pregeneradas 31.1.3.2. La base de la figura 31.1.3.3. Espiral con coprocesador
32. Grficos fractales
32.1. Grficos fractales 32.1.1. Definicin de fractal 32.1.1.1. La idea de dimensin 32.1.1.2.
Definicin de fractal 32.1.1.3. Dimensin de Hausdorff-Besicovitch 32.1.2. Fractales lineales
32.1.2.1. Polvo de Cantor 32.1.2.2. Tringulo de Sierpinski 32.1.2.3. Curva de Koch 32.1.2.4.
Curvas de Hilbert 32.1.2. Fractales no lineales o complejos 32.1.3.1. Conjuntos de Julia
32.1.3.2. Conjunto de Mandelbrot 32.1.4. Caos 32.1.4.1. Diagrama de bifurcacin 32.1.4.2.
Atractor de Lorenz 32.1.5. L-Systems 32.1.6. Plasma fractal 32.1.6. Fuego fractal 32.1.8.
Generacin de terrenos 32.1.9. Nubes
33. Animacin
33.1. Animacin 33.1.1. Operaciones de pixel bit a bit 33.1.1.1. XOR 33.1.1.2. NOT 33.1.1.3.
AND 33.1.1.4. OR 33.1.2. El teclado 33.1.3. Doble, triple y n-buffering 33.1.4. Teselado de
bloques de bits 33.1.5. Animacin 33.1.5.1. Restaurar el fondo
34. Ejemplos de programas grficos
34.1. Ejemplos de programas grficos 34.1.1. Volcar pantalla a BMP 34.1.2. Rebote 34.1.3.
Bump mapping 34.1.4. Curva de Ceva 34.1.5. FeedBack 34.1.6. Lupa 34.1.6.1. Lupa sobre
cuadrados 34.1.6.2. Lupa sobre baldosas 34.1.6.3. Lupa sobre imagen 34.1.7. Nieve
34.1.7.1. rboles de Navidad 34.1.7.2. Nevada 34.1.8. Plasma 34.1.8.1. Plasma dinmico
34.1.8.2. Plasma con doble bfering 34.1.9. Lluvia 34.1.10. Shade Bob 34.1.11. Sprite
34.1.11. Suelos 34.1.11.1. Suelo cuadrados simple 34.1.11.2. Suelo cuadrados con retraso
34.1.11.3. Suelo orfebre dinmico 34.1.11.4. Suelo de estrellas
35. Space Invaders
35.1. Ejemplo de space invaders 35.1.1. Juego invaders recogiendo BIOS-ticks 35.1.2. Juego
invaders interceptando Int 1Ch 35.1.3. Juego invaders usando counter0-PIT 35.1.4. Juego
invaders leyendo contador del canal 0 del PIT 35.1.5. Juego invaders interceptando Int 1Ch
con msica de fondo (entrecortado) 35.1.6. Juego invaders interceptando Int 1Ch con
msica de fondo (correcto)
36. Introduccin a la programacin 3D
36.1. Introduccin a la programacin 3D
37. Algunos ejemplos en 3D
37.1. Algunos ejemplos en 3D
Apndices

A. Caracteres ASCII
B. Saltos Condicionales
C. Debug
C.1. Debug C.1.1. Ejecucin del programa C.1.2. Comandos de Debug C.1.2.1. A C.1.2.2. D
C.1.2.3. E C.1.2.4. G C.1.2.5. N C.1.2.6. P C.1.2.7. Q C.1.2.8. R C.1.2.9. T C.1.2.10. U
C.1.2.11. W
D. rea de datos de la BIOS
D.1. rea de datos de la BIOS D.1.1. Datos del sistema D.1.2. Datos del adaptador de
pantalla
E. Puertos de entrada y salida
F. Cdigos scan del teclado
F.1. Cdigos scan del teclado F.1.1. Teclas de funciones F.1.2. Teclado numrico F.1.3. Teclado
alfabtico F.1.4. Teclado numrico (sobre el teclado alfabtico) F.1.5. Miscelnea
G. Optimizaciones
G.1. Optimizaciones G.1.1. Limpiar registros G.1.2. Registro BP G.1.2. Nos aprovechamos del
cdigo G.1.3. Incrementos G.1.4. Multiplicacin y divisin por potencias de dos G.1.5.
Espacio de memoria reservado pero no inicializado G.1.6. Mover y almacenar palabras en
lugar de bytes G.1.7. Evitar saltos G.1.8. Tamao de las variables G.1.9. Ejemplo
H. MS-DOS
H.1. MS-DOS H.1.1. Qu es H.1.2. Dnde encontrarlo H.1.3. El indicador de comandos
(PROMPT) H.1.4. Cambiar de directorio H.1.5. Limpiar la pantalla H.1.6. Directorio H.1.7.
Crear un directorio H.1.8. Creacin de un archivo H.1.9. Visualizacin de un archivo H.1.10.
Archivos BATCH H.1.10.1. Comentarios H.1.10.2. Impresin H.1.10.3. Etiquetas H.1.10.4.
Saltos H.1.10.5. Flujo H.1.10.6. Bucles H.1.10.7. Pausas H.1.10.8. Parmetros H.1.10.11.
Ejemplos H.1.11. Borrar ficheros H.1.12. Borrar directorios
I. Instrucciones 8087 (por orden alfabtico)
J. Grandes proyectos en ensamblador
J.1. Grandes proyectos en ensamblador J.1.1. Flat assembler J.1.2. MenuetOS
K. Declogo de buenas prcticas
Otros

Prembulo
Qu es Abre los Ojos al Ensamblador
Realmente no es un libro. Son las notas bien organizadas y estructuradas en mi camino de
aprendizaje del lenguaje ensamblador.
Cmo he aprendido a programar en Ensamblador
El formato ha sido absolutamente autodidacta. Decenas de horas buscando informacin en
internet. Estudindome programas escritos en otros lenguajes. Libros en ensamblador y
otros lenguajes. Cientos de horas persiguiendo al dichoso programa que no acaba de
funcionar. Especialmente difcil ha sido encontrar informacin en ensamblador respecto a
las listas y rboles, de hecho no encontr ninguna.
Por qu tres compiladores: MASM, FASM, NASM
Buena pregunta!. Yo mismo me la he hecho muchas veces, sobre todo cuando tena que
traducir un programa correcto a los otros y tena que perseguir los errores durante horas.
En principio comenc con MASM, cmo no?. Es el que tiene ms antigedad y, por tanto,
ms recorrido, as como abundante bibliografa y recursos por internet. Adems, su uso se

me antoja ms sencillo que el de otros muchos. Ofrece cantidad de sintaxis destinada a


facilitar la vida al programador, se me vienen a la cabeza, por ejemplo, las estructuras, las
matrices, la creacin de variables locales dentro de procedimientos, etc. Conozco gente y
he ledo en muchos foros, despotricando contra Microsoft y sus herramientas; yo no lo
comparto en absoluto. El nivel de usabilidad de que las dota no es fcil de programar y son
tan hbiles como cualquier otra. Y, adems, se puede obtener de forma gratuita, aunque
siga siendo de cdigo propietario.
NASM. Ya cuando empec con mis notas, me iba interesando. Haba comunidades con
bastante activad de usuarios y se vean libros dedicados a l. Es gratuito, open source y
multiplataforma, nos lo podemos encontrar presente en muchas distribuciones de linux. En
resumen pareca bastante atractivo. Y, sinceramente, no me ha defraudado, el uso que hace
de las estructuras es bastante bueno, facilita bastante la vida.
FASM. Por ste me empec a interesar bastante ms tarde que por NASM. De hecho tuve
que revisarme mucho de lo escrito ya para adaptarlo a l. En muchas de mis incursiones por
internet buscando informacin, fue cuando me top con informacin sobre este compilador,
y su comunidad de usuarios pareca bastante activa. La programacin con l tambin
pareca muy interesante, adems, su sintaxis es pero que muy parecida a la de NASM, as
que no haba un gran salto. Adems de esto me parece un proyecto impresionante, pues se
ofrece en un fichero comprimido donde viene todo un paquete, con cdigo fuente incluido
para programar en una gran variedad de sistemas, que incluyen MS-DOS, Windows de 32 y
64 bits, Linux, etc. Adems viene con su propio editor de textos adaptado al compilador
FASM con coloreado de sintaxis, y tambin acompaado del cdigo fuente. Todo viene con
cdigo fuente compilable con el propio compilador FASM del paquete. Impresionante. Sin
embargo, en mi opinin, adolece un poco en su definicin de las estructuras, me gustara
que, al menos, fuesen como las de NASM.
Por cul me decantara?. Sinceramente, creo que cualquiera de los tres es perfectamente
vlido. Ahora bien, debo confesar que la mayor parte de los programas los he desarrollado
primero en MASM y luego los he traducido a NASM/FASM.
Por qu otro libro en ensamblador
Surge como mi necesidad personal de instruirme en este lenguaje. Su origen son las notas
que tomaba en mi formacin. Posteriormente pens que quizs podra resultar interesante
para alguien y es cuando empiezo a documentarlo en formato libro. En algn sitio le que un
libro nace cuando no se ha encontrado nada parecido, tambin podra servir como
explicacin.
Por qu el nombre "Abre los Ojos al Ensamblador"
En mi intencin no est ser pretencioso. A veces es difcil escoger un nombre, pero pens
que ste es bonito y refleja mi propia experiencia personal con el lenguaje ensamblador, y
espero que tambin sea la tuya.
Qu puedes esperar de este libro
Intento alejarme del estilo clsico de los libros en ensamblador que estn enfocados
bsicamente a la programacin de sistemas. Creo que aqu se puede aprender a programar
en ensamblador como si de cualquier otro lenguaje se tratase.
Qu no se debe esperar de este libro
No se debe esperar que te lo resuelva todo. No es un libro al uso, puesto que abarca el
perodo de conocimiento prcticamente a cero con el que actualmente tengo. Con todo lo
que ello implica, para bien y para mal. A lo largo de todo el libro hay comentarios que le
pueden venir muy bien a un nefito o mtodos de depuracin marca de la casa, pero

tambin habr cdigo escrito hace tiempo que ahora mismo enfocara de forma diferente o
que abreviara de forma ms elegante. S que hay fallos, como en todo, por ejemplo en los
comentarios de los registros que se modifican dentro de una rutina, estn dentro de los
temas pendientes. Se espera que te lo leas bien, lo asimiles, modifiques los puntos que
necesites y, finamente, tomes tu propia decisin.
Cosas que modificaras del libro
Probablemente haya muchas, pero repito que es mi experiencia personal, en l he incluido
lo que me pareca interesante, como me pareca adecuado. Es posible que en algunos
puntos consideres el texto excesivo y en otros escasos, pero es fruto de mi gusto.
Por qu deberas aprender ensamblador
Por qu no?. Pensaba dejarlo aqu, pero aadir una cosa ms: si te gusta programar, te
gustar el ensamblador.
Por qu Abre los Ojos al Ensamblador no es gratuito
Esta afirmacin no es cierta, lo nico que no es gratuito son las bibliotecas que se utilizan
para compilar muchos programas del libro, pero tanto el texto como amplias partes de l,
como son la programacin en Windows o las interfaces con lenguajes de alto nivel s que lo
son, en la medida en que estn accesibles ntegramente. De hecho tampoco he puesto
mucho nfasis en esto, por ejemplo tambin est completo el programa Tetris.
Dicho esto y respondiendo a la pregunta, es evidente que no espero hacerme rico con el
lenguaje ensamblador a estas alturas, pero s me gustara que cubriese los gastos y, si me
diese tambin para alguna entrada de cine, pues estupendo. El libro no est completo y me
gustara hacerlo lo ms participativo posible, pero el ensamblador no es la nica ocupacin
que tengo, de hecho slo es una aficin, y le dedicar tanta atencin como la despierte
entre la gente.
Cabe resear que el costo del registro se considera como un donativo y, por lo tanto, no
tiene ninguna clase de implicaciones para mi persona. Abre los Ojos al Ensamblador no lleva
aparejado el soporte ni la devolucin del coste del registro, adems, se puede considerar
que tienes todo el tiempo del mundo para probarlo antes de registrarte y te exhorto a que
as lo hagas, tmate tu tiempo, revsatelo bien y, cuando ests convencido, realiza el pago
del registro. La novedad es que ya no hay registro, dejo como ejercicio las libreras.
Muy importante tambin. Debes considerar que ninguna obra est libre de fallos y sta no
es una excepcin. De ningn modo me puedo considerar responsable de las
consecuencias debidas o indebidas que se puedan suceder del uso que le des a la
informacin, programas, cdigo, etc que aqu (en el libro Abre los Ojos al
Ensamblador) existen, slo t eres el responsable.
Por qu cuesta 10 euros el registro
Es un nmero redondo y lo suficientemente bajo como para que sea accesible por cualquier
persona. Pues eso, las libreras ya no se venden.
Qu es el foro
Es un punto de encuentro entre todos aquellos a los que nos gusta el ensamblador para
intercambiar opiniones y aprender unos de otros, yo tambin.
Qu no es el foro
No es un punto de soporte para Abre los Ojos al Ensamblador ni para cualquier duda que te
pueda surgir. Tampoco estoy obligado a crearlo ni a mantenerlo.
Puedo usar la informacin o cdigos aqu descritos en mi propio proyecto?

Claro, slo tienes que darme crdito donde corresponda. Lo que no es admisible es que tu
proyecto consista en hacer otro Abre los Ojos al Ensamblador cambiando el autor por tu
nombre. Un mximo de un 20%-30% de AOE en tu proyecto podra ser aceptable, aunque es
deseable que intentes innovar, no copiar.
He visto que quedan cosas pendientes, tendr que volver a pagar el registro
cuando estn terminadas?
No, el registro es para todo el libro Abre los Ojos al Ensamblador, est todo terminado o no.
Slo t eres el responsable
Para que quede bien claro, le pongo un ttulo. Debes entender que este libro puede contener
informacin, cdigo, etc. que sean incorrectos. Tambin puede ocurrir que, siendo correctos,
t hagas un mal uso de ellos. Da igual, en cualquier caso el responsable del uso que hagas
de la informacin, datos, cdigo, programas, etc. de este libro slo eres t.
Por favor, no te olvides de mirar los trminos legales de uso del libro.

1.1. Sistemas numricos


1.1.1. Sistema decimal
El sistema decimal es el sistema numrico natural humano, en el que todos pensamos naturalmente. Pero,
qu es?. Es un sistema numrico en el que la base es el nmero 10 (bastante redondo). Vemoslo con un
ejemplo. Supongamos que tenemos el nmero 5013. Vamos a ver cul es su estructura en base 10:
5013 = 5 * 103 + 0 * 102 + 1 * 101 + 3 * 100 = 5000 + 0 + 10 + 3.

Puedes ver que hemos empleado el 10 como base en todas las exponenciaciones, por eso se le llama de
base 10.

1.1.2. Sistema binario


Cualquier nmero en cualquier base puede ser representado exactamente por otro nmero en cualquier
otra base numrica. Esto implica que da exactamente igual pensar en base 10 (como hacemos los
humanos) o en base binaria (como hacen las computadoras). La base binaria es la base 2. Las
computadoras piensan en este sistema porque funcionan con energa elctrica. De esta manera le asignan 5
voltios al nmero 1, y ningn voltio al 0, con lo que pueden representar cualquier nmero formado por
ceros y unos (sistema binario). Y esto es todo lo que una computadora necesita para poder trabajar. Pues,
como veremos ms adelante, cualquier tipo de operacin y de dato est representado por un nmero.

1.1.3. Conversin entre decimal y binario


Vamos a ver cmo se pasa un nmero binario a decimal. Supongamos el 1101 binario:
1101 = 1 * 23 + 1 * 22 + 0 * 21 + 1 * 20

8 + 4 + 0 + 1

13

Fig. 01-01 - Tma del Cociente


Para pasar un nmero de decimal a binario utilizaremos el teorema del cociente en el anillo , vase Fig.
01-01.
Con lo cul, 13d = 01101b Esta es una notacin muy comn en programacin, 13d significa 13 decimal y
1101b, 1101 binario. De la misma forma que los humanos solemos representar un nmero decimal
separando cada tres cifras para un visionado ms cmodo, en computacin, se representar el nmero
binario separando cada cuatro dgitos (cada cuatro, porque 4 es potencia de 2, que es la base del
entendimiento de la computadora).

1.1.4. Operaciones matemticas bsicas en base dos


Actualmente en casi cualquier calculadora se puede trabajar en base binaria, decimal, hexadecimal e
incluso ms, con lo cul, no merece la pena entrar en profundidades. Lo ms aconsejable es, por tanto,
echar las cuentas con una calculadora y hacer las equivalencias entre las distintas bases tambin con sta,
pues de esta forma nos ahorraremos fallos innecesarios. No obstante, he elegido a modo de ejemplo una
suma y una resta en base binaria:
Suma en base dos:
1101 =
23 + 22 + 01 + 20 = 8 + 4 + 1 = 13d
1011 =
23 + 02 + 21 + 20 = 8 + 2 + 1 = 11d
--------11000 = 24 + 23
= 16 + 8
= 24d

Explicacin:
Como en base decimal, siempre empezamos por la derecha y decimos:

1 ms 1 son 2 (en decimal), que en binario se representa con un 10, por lo tanto, ponemos un cero
y nos llevamos una.

0 ms 1 es 1, ms 1 que nos llevbamos de antes, son 2 (en decimal), que de nuevo, en binario se
representa por un 10, por lo que ponemos un cero y nos llevamos una.

1 ms 0 es 1, ms 1 que nos llevbamos de antes, son 2 (en decimal), que en binario es 10, con lo
que ponemos un cero y nos llevamos 1.

1 ms 1 son 2, ms 1 que nos llevbamos antes son 3 (en decimal), que en binario se representa por
un 11, que es lo que ponemos, et voil.

Resta en base dos


1101 = 23 + 22 + 20
1011 = 23 + 21 + 20
-----0010 =
21

= 8 + 4 + 1 = 13d
= 8 + 2 + 1 = 11d
--=
2
= 2d

Explicacin:
De nuevo, al igual que en base 10 empezamos por la derecha y decimos:

De 1 a 1 van 0 y nos llevamos 0.

De 1 a 10b (2d) va 1 y nos llevamos 1.

0, ms la que nos llevbamos de antes, es 1, que hasta 1 van 0, y nos llevamos 0.

De 1 a 1 van 0 y nos llevamos 0, c'est fini.

1.1.5. Operaciones lgicas


Adems de las conocidas operaciones matemticas, en el sistema binario se pueden definir otra serie de
funciones especiales conocidas como operaciones lgicas que surgen de la idea de asignar el valor "falso"
al dgito 0 y el valor "verdadero" al 1. Estas operaciones se definen en principio para cantidades de un
nico dgito. Las ms importantes de ellas las vemos en la siguiente tabla:
X

X and Y

X or Y

X xor Y

not X

Tabla 01-01 - Operaciones Lgicas

X and Y vale 1 slo cuando X e Y valen 1 los dos, y 0 en caso contrario

X or Y vale 1 cuando al menos uno de los dos vale 1, y 0 en caso contrario

X xor Y vale 1 cuando X e Y son distintos y 0 cuando son iguales

not X es el opuesto de X

1.1.6. El sistema hexadecimal


Uno de los mayores problemas del sistema binario es la cantidad ingente de cifras que requiere la
representacin de un nmero de forma temprana, intenta por ejemplo representar en binario el nmero
decimal 1000. Otro de sus grandes problemas es que la conversin de binario a decimal y viceversa no es
trivial. Estos dos problemas se solventan con el sistema hexadecimal que es realmente compacto y cuya
conversin a binario y viceversa es muy sencilla, por lo que esta notacin es comnmente utilizada en
computacin, ya que, como ya hemos dicho, el sistema binario es con el que piensa el ordenador.
Como su nombre indica el sistema hexadecimal tiene por base al nmero 16. Aqu tenemos un problema,
pues los nmeros que nosotros conocemos van del 0 al 9, que son 10, cmo llegar al 16?; fcil, le
aadimos las letras A (10), B (11), C (12), D (13), E (14), F (15) a partir del 10, con lo cul ya tenemos 16
dgitos para representar nmeros.

1.1.6.1. Conversin entre hexadecimal y decimal


Vamos a ver cmo se pasa un nmero hexadecimal a decimal. Supongamos el 12B3 hexadecimal:
12B3

= 1 * 163 + 2 * 162 + 11 * 161 + 3 * 160

4096 + 512 + 176 + 3

4787

Para pasar un nmero de decimal a hexadecimal utilizaremos el teorema del cociente en el anillo :

Fig. 01-02 - Tma del Cociente


Con lo cul, 4787d = 12B3h.
Esta es una notacin muy comn en programacin, 4787d significa 4787 decimal y 12B3h, 12B3
hexadecimal. La primera cifra de un nmero hexadecimal es siempre un nmero, ponindose un cero a la
izquierda si fuera necesario.
El 8086 es un procesador de 16 bits, lo cul quiere decir que internamente es capaz de trabajar con cifras
binarias de 16 dgitos de longitud. Las direcciones de memoria con las que trabaja tienen una longitud de
20 bits, lo que le permite direccionar un total de 1 Megabyte de memoria.

1.1.6.2. Conversin entre hexadecimal y binario


Veamos una tabla con la conversin inmediata de los primeros 16 nmeros hexadecimales:

Binario

Hexadecimal

Binario

Hexadecimal

0000

1000

0001

1001

0010

1010

0011

1011

0100

1100

0101

1101

0110

1110

0111

1111

Tabla 01-02 - Conversin Binario-Hexadecimal


Para convertir un nmero hexadecimal en binario tan slo tenemos que utilizar esta tabla, y a cada dgito
hexadecimal sustituirlo por sus cuatro dgitos decimales. Supongamos que tenemos el nmero 0ABCDh y
lo queremos pasar a binario:
0
A
B
C
D
0000 1010 1011 1100 1101

Es as de sencillo.
Vamos a convertir ahora un nmero binario en hexadecimal. Para hacer esto, tan slo tenemos que
asegurarnos que el nmero de cifras que tiene nuestro nmero es mltiplo de 4, porque vamos a volver a
utilizar la tabla anterior. Supongamos, por ejemplo, el nmero 1011001010b. Lo primero que tenemos que
hacer es aadirle dos ceros a la izquierda para que tenga un nmero de dgitos mltiplo de cuatro, y luego,
la operacin es justo la inversa de la anterior.
0010 1100 1010
2
C
A

1.1.7. Representacin de datos


Matemticamente se puede trabajar con cualquier tipo de nmero, sin embargo, las computadoras estn
diseadas para trabajar internamente con nmeros de base binaria, que son, como ya sabemos, slo ceros y
unos. Vamos a ver cmo estn estructurados:

1.1.7.1. Bit
Es la unidad ms pequea de informacin, puede contener slo un 0 un 1.

1.1.7.2. Nibble
Es una coleccin de cuatro bits. No es una estructura de especial inters salvo para dos objetos:
1. El BCD, que es una forma de representar nmeros en formato ASCII en 4 bits
2. Los dgitos hexadecimales, cada uno de ellos tiene una representacin de 4 bits.
Con un nibble se pueden representar hasta 24 = 16 valores diferentes.

1.1.7.3. Byte
Es la ms importante estructura de datos, pues es el tamao de dato ms pequeo accesible por un 8086 y
est compuesta por 8 bits, o sea, 2 nibbles, y por tanto son representados por 2 dgitos en hexadecimal.
7

Tabla 01-03 - Estructura de un Byte


Un byte puede representar hasta 28 = 256 valores diferentes, por ejemplo, representa cada uno de los 256
caracteres que hay en el cdigo ASCII.

1.1.7.4. Palabra
Es un grupo de 16 bits, o equivalentemente, 2 bytes 4 nibbles; por lo que puede ser representado por un
nmero hexadecimal de 4 dgitos. Es tambin una estructura muy importante porque todos los registros
del 8086 son de 16 bits, que es con la unidad con la que fue diseada para trabajar. Esto quiere decir que el
microprocesador 8086 es de 16 bits.
15

14

13

12

11

10

09

08

07

06

05

04

03

02

01

00

Tabla 01-04 - Estructura de una Palabra


Una palabra puede representar hasta 216 = 65.536 valores diferentes. Si definimos una variable como
palabra, debemos saber que puede representar un nmero entero de 0 hasta 65.535 o bien un entero con
signo desde -32.768 hasta 32.767. El microprocesador 8086 trabaja con registros de 16 bits.

1.1.7.5. Palabra doble


Es un grupo de dos palabras, es decir, de 32 bits, 4 bytes u 8 nibbles, por lo que puede ser representado por
un nmero hexadecimal de 8 dgitos.
31

30

29

28

27

26

25

24

23

22

21

20

19

18

17

16

15

14

13

12

11

10

09

08

07

06

05

04

03

02

01

00

Tabla 01-05 - Estructura de una Palabra Doble


Una de sus funciones ms importantes en entornos de 16 bits es la de contener un segmento:direccin. En
entornos de 32 bits contiene una direccin, puesto que se trabaja con modelos de memoria planos.
Una palabra doble puede representar hasta 232 = 4.294.967.295 valores diferentes. Por lo que una variable
declarada como tal puede tomar valores desde 0 hasta 4.294.967.295 sin signo o bien desde
-2.147.483.648 hasta 2.147.483.647 con signo.
Existen procesadores de 32 bits, como el 386, porque se dise para que trabajase internamente con
registros de 32 bits.

1.1.7.6. Cudruple palabra


Es un grupo de cuatro palabras, es decir, 64 bits, 8 bytes 16 nibbles, por lo que puede ser representado
por un nmero hexadecimal de 16 dgitos.

Una cudruple palabra puede representar hasta 264 = 18.446.744.073.709.551.616 valores diferentes.
Actualmente tambin existen microprocesadores de 64 bits profusamente extendidos entre los PCs.

1.1.7.7. Mltiplos del byte


Si para medir la capacidad de los registros internos del procesador se usan las unidades indicadas
anteriormente, cuando se trata de indicar la capacidad de un bloque de memoria o de ciertos dispositivos
como los CD-ROM, discos duros y similares, se emplean siempre mltiplos del byte. Todos ellos, al
operarse con la base 2 en lugar de la decimal, usan como multiplicador no el millar, sino el 1024, que es el
resultado de elevar 2 a 10.

1 Kb (kilo byte) = 210 bytes = 1.024 bytes

1 Mb (mega byte) = 220 bytes = 1.024 Kb = 1.048.576 bytes

1 Gb (giga byte) = 230 bytes = 1.024 Mb = 1.073.741.824 bytes

1 Tb (tera byte) = 240 bytes = 1.024 Gb = 1.099.511.627.776 bytes

1.1.7.8. Nmeros con y sin signo


Hasta ahora hemos tratado slo los nmeros binarios positivos, pero qu pasa con los negativos?.
En el sistema decimal, el signo de un nmero se expresa anteponiendo a la cantidad un guin para indicar
que se trata de un nmero negativo o nada en caso de que sea positivo. Sin embargo, los ordenadores slo
son capaces de almacenar dgitos binarios, no signos, por lo que hay que recurrir a algn sistema
alternativo para indicar el signo de un nmero. Adems, matemticamente podemos conseguir cualquier
nmero, de cualquier longitud, pero las mquinas tienen una capacidad finita, por lo que debemos
restringir el tipo de nmero que podemos tomar. Hay que encontrar algn mtodo para conseguir las
mismas propiedades que tiene (,+), el grupo de los nmeros enteros.
(,+) es un grupo conmutativo
Sean a, b, c elementos de (,+)

Propiedad asociativa: a + (b + c) = (a + b) + c

Existe el elemento neutro (0): 0 + a = a + 0 = a

Existe el elemento simtrico (-a): a + (-a) = (-a) + a = 0

Propiedad conmutativa : a + b = b + a

Puesto que la capacidad de los ordenadores es limitada, establecemos unas magnitudes de dimensiones:

Byte, que tiene una capacidad de 8 bits.

Palabra, con una capacidad de 16 bits.

Doble palabra, con capacidad para 32 bits.

Cuadruple palabra, de 64 bits.

Existen ms, pero estos son los ms usados. Todos ellos estn pensados naturalmente para albergar
nmeros enteros positivos hasta su lmite, pero cmo podemos almacenar nmeros negativos?.
Realmente tenemos que usar un truco que es establecer la mitad de su capacidad para los nmeros
positivos y la otra mitad para los negativos.
El sistema ms comnmente utilizado se denomina "complemento a dos", y se basa en las siguientes
reglas:

Un nmero positivo tiene su bit ms significativo (el de la izquierda) siempre a cero, y a uno si es
negativo.

Para convertir un nmero positivo en negativo (o viceversa) se invierten todos los bits del nmero,
y luego se le suma uno al resultado.
Por ejemplo:
35d = 00100011b -> (invert) -> 11011100b -> +1 -> 11011101b = -35d
-35d = 11011101b -> (invert) -> 00100010b -> +1 -> 00100011b = 35d

Supongamos que cogemos un nmero de magnitud byte, esto significa que slo puede contener 8 dgitos,
ceros o unos.
Grficamente el sistema "complemento a dos" quedara como sigue:

Fig. 01-03 - Compl a 2


Enteros con signo

Compl a 2

Enteros sin signo

Hexadecimal

-128

1000 0000

128

80

-127

1000 0001

129

81

-126

1000 0010

130

82

[...]

[...]

[...]

[...]

-3

1111 1101

253

FD

-2

1111 1110

254

FE

-1

1111 1111

255

FF

0000 0000

0000 0001

0000 0010

0000 0011

[...]

[...]

[...]

[...]

125

0111 1101

125

7D

126

0111 1110

126

7E

127

0111 1111

127

7F

Tabla 01-06 - Complemento a 2


Vemos en este grfico que esta disposicin que hemos elegido para nuestro sistema numrico es como el
pez que se muerde la cola.
Supongamos que tenemos el nmero 1111 1111b. qu ocurrira si le sumamos 1?:
1111 1111
1
-------------- +
1 0000 0000

La cifra que obtenemos excede de tamao byte, puesto que tiene 9 dgitos, por lo tanto el dgito de la
extrema izquierda se pierde, es como si intentaras llenar una botella con vasos de agua y el ltimo no
cupiese, simplemente se desbordara y se perdera. De esta forma qu es lo que obtenemos?, el nmero
0b, con lo que obtenemos este crculo vicioso del que hablbamos antes. Esto ocurre por la ya mencionada
limitacin de contencin de cualquier nmero de las computadoras y a este suceso se le llama
desbordamiento. La nica solucin para que no ocurran desbordamientos (puesto que obtenemos
resultados imprevisibles) es elegir una botella lo suficientemente grande como para que quepan todos los
vasos de agua que le vamos a echar.
Sean los nmeros:

a = 1000 0001b = -(0111 1110b + 1d) = -(126d + 1d) = -127d

b = 0000 0010b = 2d

c = 0101 0101b = 85d

En el caso de que tratemos con enteros con signo se observa inmediatamente que el nmero a es negativo,
puesto que su dgito de extrema izquierda (el de mayor peso) es 1. Para ver su representacin decimal hay
que invertir sus bits y sumarle un 1 decimal.
Este subconjunto de Z, en el caso de los bytes de -128 a 127, con esta operacin suma en complemento a 2
que hemos definido es un subgrupo:

Es cerrado respecto de la suma. Si notamos al subconjunto como B, b y b' dos elementos suyos,
b+b' tambin es de B por la propiedad del desbordamiento.
1000 0001b
0111 1111b
------------ +
1 0000 0000b

Contiene al elemento neutro. Claramente es el cero.

Cada elemento tiene su simtrico. Dado g en G, su simtrico ser: NOT(g) + 1. NOT cambiar
cada bit a su contrario, y luego le sumamos 1. nicamente el 128 se escapa de esta propiedad

porque -128 es un byte, pero 128 ya es un word. As ([-127,127], suma complemento a 2) sera un
subgrupo de (Z,+), pero el -128 tambin cabe dentro de un byte.

-128d = 10000000b -> not(10000000b)


-128d. Sera 128d en word
-127d = 10000001b -> not(10000001b)
-126d = 10000010b -> not(10000010b)
...
-2d = 11111110b -> not(11111110b)
-1d = 11111111b -> not(11111111b)
0d = 00000000b -> not(00000000b)
0d. Desborda un 1
1d = 00000001b -> not(00000001b)
2d = 00000010b -> not(00000010b)
...
126d = 01111110b -> not(01111110b)
127d = 01111111b -> not(01111111b)

Propiedad conmutativa.

1000 0001b
0000 0010b
0000 0010b
1000 0001b
----------- +
---------- +
1000 0011b
1000 0011b
1000 0011b = -(0111 1100b + 1d) = -(124d + 1d) = -125d = -127d + 2d.

+ 1b = 01111111b + 1b = 10000000b =
+ 1b = 01111110b + 1b = 01111111b =
+ 1b = 01111101b + 1b = 01111110b =

127d
126d

+ 1b = 00000001b + 1b = 00000010b =
+ 1b = 00000000b + 1b = 00000001b =
+ 1b = 11111111b + 1b = 00000000b =

2d
1d

+ 1b = 11111110b + 1b = 11111111b =
+ 1b = 11111101b + 1b = 11111110b =

-1d
-2d

+ 1b = 10000001b + 1b = 10000010b = -126d


+ 1b = 10000000b + 1b = 10000001b = -127d

Importante
Antes de realizar operaciones con nmeros con signo es preciso cerciorarse de que todos tengan el mismo
nmero de bits. Si esto no es as hay que alargar el tamao de los ms cortos al tamao del mayor. Para
ello se repite la cifra a la izquierda tantas veces como sea necesario, es decir, a los nmeros negativos se
les aade 1 repetidas veces a la izquierda y 0 a los positivos. Esto ya se consigue con los operadores
CBW, CWD, por ejemplo.
Otra cosa son los enteros sin signo. Por ejemplo, de tipo byte, que son 8 bits seran 28=256 elementos, que
van desde el 0 hasta el 255. Aqu ya no tenemos la suma en complemento a 2, sino la suma normal, pues
no existen los negativos, pero el desbordamiento sigue existiendo, lo cul provoca que el nmero
resultante de la suma siga siendo de tipo byte, pero el resultado sera distinto al esperado. Por ejemplo:
244d = F4h = 11110100b
128d = 80h = 10000000b
------------------------- +
372d = 174h = 101110100b

Vemos que el nmero binario resultante de la suma tiene 9 dgitos, se pierde entonces el de la extrema
izquierda, quedando:
116d =

74h =

01110100b

Obsrvese que un byte slo puede tener dos dgitos hexadecimales, pues FFh = 255d.

1.1.7.9. Nmeros reales


En computacin son llamados tambin nmeros "en coma flotante", "floating point" en ingls, debido a
que los decimales se separan con una coma en la notacin espaola y con un punto en la notacin inglesa.

Al igual que ocurra con los nmeros negativos, el ordenador no trata directamente con este tipo de
nmeros, sino que se vale de un artificio para ello. Tampoco existe una capacidad infinita para ellos,
lgicamente.
Nosotros vamos a ver slamente tres tipos de nmeros en coma flotante, descritos en la siguiente tabla:
Tipo de dato

Bits Bytes

Dgitos significativos

Rango aproximado

Real Corto

32

6-7

1.18*10-38 hasta 3.40*1038

Real Largo

64

15-16

2.23*10-308 hasta 1.79*10308

Real Extendido

80

10

19

3.37*10-4932 hasta 1.18*104932

Tabla 01-07 - Nmeros en Coma Flotante


El rango de los exponentes para los nmeros reales es:
Formato

Rango de exponente

Real Corto

-127 a +128

Real Largo

-1023 a +1024

Real Extendido

-16383 a 16384
Tabla 01-08 - Rango de Exponentes

Cmo pasamos un nmero real decimal a binario?


Es bien sencillo, tan slo hay que fijarse que estar en base 2 significa que todos los nmeros son
combinaciones lineales de potencias de 2 (igual que si estamos en base decimal seran combinaciones
lineales de potencias de 10).
Por ejemplo, cojamos el nmero decimal 39.5625 (es conveniente habituarse a la notacin inglesa del
punto para designar los decimales porque los lenguajes de programacin estn diseados en ingls y esta
es la notacin que utilizan).
En base decimal tenemos:
39.5625 = 3x101+9x100+5x10-1+6x10-2+2x10-3+5x10-4

En binario tenemos:
39.5625 = 32+4+2+1+0.5+0.0625 =
1x25+0x24+0x23+1x22+1x21+1x20+1x2-1+0x2-2+0x2-3+1x2-4

Con lo que ya tenemos la representacin binaria del nmero:


39.5625d = 100111.1001b
Vamos a ver un algoritmo para hacer esto:
La primera parte consiste en convertir la parte entera a binario. Esto ya se hace como hemos visto
anteriormente, utilizando el Teorema del Resto:
39d = 100111b

La segunda parte consiste en convertir la parte decimal a binario. Para ello utilizamos un procedimiento
semejante al anterior, slo que ahora en lugar de dividir por 2, multiplicamos por 2 y vamos cogiendo la
parte entera que nos va saliendo hasta que nos quedemos sin decimales:
Parte decimal

*2

Parte entera

0,5625

1,1250

0,1250

0,2500

0,2500

0,5000

0,5000

1,0000

Tabla 01-09 - Conversin parte decimal a binario


Tomando de arriba a abajo tenemos que 0.5625b = 1001d
Obsrvese, asimismo que este algoritmo es vlido para cualquier base a la que queramos convertir,
utilizando su base para multiplicar.
Cmo guardamos en memoria un nmero binario decimal?
Vamos a seguir las especificaciones dadas por el IEEE-754. Para guardar algo tendremos que reservar
espacio y esto influir decisivamente en nuestra forma de guardar el nmero binario decimal, si bien el
mtodo estructural es el mismo.
El formato con el que vamos a guardar un nmero real binario es este:
Ax2B
Donde A es un nmero binario decimal con 1 como parte entera y cualquier combinacin de unos y ceros
para la parte decimal. Por ejemplo: 1.0101001
B es el exponente del nmero binario decimal, para aceptar negativos y positivos, ste se va a guardar de
forma discriminada.
Es interesante recordar que la notacin cientfica que se utiliza muy a menudo para un nmero decimal
real es la siguiente:
aEb

Donde a es un nmero real cualquiera, Eb significa por 10 elevado a b. Entonces a es la mantisa y b es el


exponente.
Veamos ahora cul es la estructura para cada uno de los tipos de nmeros reales:

El bit ms significativo tanto de los 32 de real corto, como de los 64 del real largo, como de los 80
del Real extendido est reservado para almacenar el signo del nmero: 0 para positivo, 1 para
negativo.

Los siguientes 8 bits del real corto, 11 para el real largo y 15 para el Real extendido, estn
reservados para guardar el exponente del nmero, y para trabajar con exponentes positivos y
negativos, ste est discriminado por una suma de 127 (27-1) en el caso de reales cortos, 1023 (2101) para los reales largos y 16383 (214-1) para los Reales extendidos.

El resto de los bits se reservan para la mantisa del nmero exponencial. Es importante decir que el
1 de la parte real de la mantisa no se guarda puesto que se asume que siempre es as. En caso del
nmero real 0, toda la estructura que comentamos tendr todos sus bits a cero.

Veamos esto mismo grficamente:


S

EXP

31

30

MANTISA
23

22

Tabla 01-10 - Real corto


S

EXP

63

62

MANTISA
52

51

Tabla 01-10 - Real largo


S

EXP

79

78

MANTISA
64

63

Tabla 01-10 - Real extendido


Examinamos, como ejemplo, cmo se guardara el nmero anterior en un real corto:
Hemos dicho que
39.5625d = 100111.1001b = 1.001111001x25b

El signo es positivo
El exponente 5d+127d = 132d = 10000100b
La mantisa 001111001
Con lo cul, se guardara en un espacio de memoria de 32 bits as:
0 10000100 00111100100000000000000b = 421E4000h

Si estamos trabajando en un entorno de 16 bits, esto se recogera en DX:AX as: DX = 421E, AX = 4000 y
se guardara en formato Little Endian as: 00 40 1E 42.
Algunos ejemplos:
0
1
0
1

00000000
00000000
11111111
11111111

00000000000000000000000b
00000000000000000000000b
00000000000000000000000b
00000000000000000000000b

=
=
=
=

Cero Positivo
Cero Negativo
Infinito positivo
Infinito negativo

1 10000111 00110001101000000000000b = C3 98 D0 00h


-1 * 2(135-127) * 1.00110001101 = -100110001.101 = -305.625
0 10000000 00000000000000000000000b = 40 00 00 00h
+1 * 2(128-127) * 1.0 = 10.0 = 2
0 10000101 01101101101001110000000b = 42 B6 D3 80h
+1 * 2(133-127) * 1.0110110110100111 = 1011011.0110100111 = 91.4130859375

0 10000001 01011000000000000000000b = 40 AC 00 00h


+1 * 2(129-127) * 1.01011 = 101.011 = 5.375
0 10000000 11000000000000000000000b = 40 60 00 00h
+1 * 2(128-127) * 1.11 = 11.1 = 3 + 0.5 = 3.5

Obsrvese que multiplicar un nmero X en binario por 2n equivale a correr la coma decimal de X n veces
a la derecha si n es positivo, y a la izquierda si n fuera negativo
Por ejemplo, veamos cmo calculamos la representacin decimal del binario 101.011:
La parte entera:
101b=5d.

La parte decimal:
0*2-1+1*2-2+1*2-3 = 1/4d+1/8d=3/8d=0,375d

RealCM01

RealCJ01

RealCN01

RealCF01

Cdigo

Cdigo

Cdigo

Cdigo

[bin]

[bin]

[bin]

[bin]

Resultado en pantalla
>RealCF01
.0004998

Source 01-01 - Imprimir nmeros reales en pantalla


Lo que hacemos en este ejemplo es ir desmenuzando cada parte del nmero real guardado segn las
especificaciones anteriormente comentadas. Una vez que tenemos la parte entera y la decimal, hay que
convertirlas a ASCII para imprimirlas.
1.1.7.9.1. Inexactitudes en la representacin de los nmeros reales en binario
Ejercicio: Convertir el nmero decimal 0,1d a binario.
Pronto comprobaremos que este proceso se repite indefinidamente y nunca llegaremos al valor exacto de
0,1d en binario. Lo nico que podremos hacer ser aproximarlo tanto como podamos, para lo cul
trabajaremos con las cotas superior e inferior binarias de ste nmero correspondientes a su truncamiento
(23 bits en caso de los reales simples) y su inmediato superior. Esto implica que cada vez que operemos
con este nmero, estaremos perdiendo ms y ms precisin.
Parte decimal

*2

Parte entera

0,1

0,2

0,2

0,4

0,4

0,8

0,8

1,6

0,6

1,2

0,2

0,4

Tabla 01-11 - Representacin 1.0 en binario

Ya hemos encontrado el ciclo (0011). Por tanto, la representacin binaria es:


0,1 =

0,00011 = 1,10011001100110011001100 * 2-4

cuya representacin en IEEE-754 es:


x = 0 01111011 10011001100110011001100...
x' = 0 01111011 10011001100110011001100
x''= 0 01111011 10011001100110011001101 = 3DCCCCCD

x'' est ms prximo a x que x', por lo que la representacin de x ser x''.
Vamos a ver ahora mediante un ejemplo cmo la representacin de un nmero en coma flotante pierde
precisin frente a los nmeros enteros:
Para empezar, el espacio utilizado para representar un nmero en coma flotante hay que dividirlo para
guardar el exponente y la mantisa, mientras que el nmero entero usa todo el espacio para la mantisa. Esto
significa que el formato para representar nmeros en coma flotante tendr menos precisin que el formato
entero.
Supongamos que tenemos el siguiente formato en 8 bits para representar nmeros en coma flotante:
EEE MMMMM
3
5

El exponente no va a estar biselado, con lo que podr representar exponentes desde el 0 hasta el 7 y la
mantisa usa el bit 1 por defecto de la parte entera numrica.
Si el exponente es 0 y la mantisa es 0, el nmero ms pequeo que podremos representar ser 1,0x20 = 1.
Si el exponente y la mantisa tienen todos sus bits a 1, el nmero ms grande que podremos representar
ser 1,11111x27 = 11111100b = 252d.
Por otra parte usando el formato de 8 bits para guardar un entero, tenemos que el nmero ms pequeo
que puede representar es 0 y el mayor es 28-1 = 255.
Para empezar, ya estamos viendo que el nmero de enteros que abarca es mayor que el de coma flotante, si
bien ste puede representar nmeros decimales que el otro no puede, claro.
Vamos a ver ahora una curiosa prdida de datos mediante este mtodo de representar nmeros en coma
flotante. Si el mayor nmero representable es 252, cul es su inmediato anterior?. Sera 1,11110 x 27 =
11111000b = 248d.
Es decir que antes del 252 va el 248, nos hemos comido el 249, 250, 251!, que la representacin entera s
posee.
Asmismo, el siguiente en la lista sera
1,11101 x 27 = 11110100b = 244d.
Nos hemos vuelto a saltar 4 valores.
El montante del error es mayor para los valores ms altos, puesto que la prdida de precisin en la mantisa
es amplificada por el exponente. Cuanto ms pequeo es el valor, menor es el error en la precisin.

Por ejemplo, si el valor ms pequeo representable es el 1, cul es el siguiente?


Sera 1,00001 x 20 = 1.03125d
Sin prdida de precisin comparado con un entero. Y podemos representar exactamente el nmero 2:
1,00000 x 21 = 2d
En definitiva, la representacin de los nmeros en coma flotante sufren prdida de precisin tanto ms
cuanto mayor sea el valor, mientras que para los valores pequeos es bastante aproximado. As que
cuidado cuando hagamos conversiones entre nmeros.

1.1.7.10. Little Endian vs Big Endian


Dependiendo de la computadora que estemos usando, los bytes de una estructura multibyte se pueden
almacenar de dos formas diferentes, que son llamados "Big Endian" y "Little Endian".
Little Endian significa que el byte ms bajo de la estructura multibyte es almacenado en la direccin de
memoria ms pequea, y el byte ms alto en la direccin ms grande. Por ejemplo, supongamos que
tenemos una estructura multibyte de tipo LongInt (4 bytes): Byte3 Byte2 Byte1 Byte0, se almacenaran en
memoria de la siguiente manera:
Base
Base
Base
Base

Direccin+0
Direccin+1
Direccin+2
Direccin+3

Byte0
Byte1
Byte2
Byte3

Big Endian acta justo al revs, es decir, el byte ms alto de la estructura multibyte se almacena en la
direccin de memoria ms pequea y el byte ms bajo en la direccin ms grande. La estructura multibyte
anterior, se almacenara as:
Base
Base
Base
Base

Direccin+0
Direccin+1
Direccin+2
Direccin+3

Byte3
Byte2
Byte1
Byte0

Comentario
La distribucin Little Endian la utilizan microprocesadores tales como el de Intel, y la del Big Endian
microprocesadores como los de Motorola, como los que usan los ordenadores "Apple". Obsrvese que
con la primera estructura, que va a ser la que nosotros utilizamos, vamos a ver que los pares de dgitos
hexadecimales que forman un byte se guardan en "orden inverso" al que posee la estructura multibyte.
Esta caracterstica quizs nos desconcierte un poco al principio, pero enseguida se le coge el manejo.
No vamos a entrar aqu en el agrio debate que suscitan los pros y contras de cada uno de ellos, en cambio
vamos a ver un ejemplo ilustrativo de cmo se guarda un entero de tipo LongInt (4 bytes) usando la
distribucin Little Endian. Para ello vamos a utilizar el depurador AFD, que es sencillo de utilizar y
gratuito.
El cdigo fuente del programa LEndian.asm es el siguiente:
;
;
;
;
;
;
;

---------------------------------------------------------------------------TITULO : Ejemplo de Little Endian


--------AUTOR
: Alfonso Vctor Caballero Hurtado
--------VERSION : 1.0
----------------------------------------------------------------------------

codigo segment 'code'


; Abre el segmento de cdigo
assume cs:codigo, ds:codigo, es:codigo, ss:codigo
org 100h
; COM -> comienza en 100h
Inicio: jmp entrada
; Comienzo de la ejecucin
; Este es el espacio reservado para los datos
miLongInt dd 0ABCDEF01h
; Definimos el LongInt
; Aqu podemos definir ms prodecimientos
entrada proc
; Abre el procedimiento de entrada
; Aqu pondremos lo que queramos que haga el programa
mov ax, word ptr miLongInt
mov dx, word ptr miLongInt + 2
; Con lo de aqu abajo terminamos el programa y emitimos una seal
; de que todo ha ido bien
mov ax, 4c00h
; Servicio 4Ch, mensaje 0
int 21h
; volvemos al DOS
entrada endp
; cierra el procedimiento
codigo ends
; Y/O tambin macros
end Inicio
; le decimos al ensamblador que aqu termina el programa

Hemos definido una variable de tipo LongInt de 4 bytes llamada "miLongInt" con el valor 0ABCDEF01h.
Le ponemos un cero delante porque sino el ensamblador supondra que se trata del nombre de una
etiqueta. Vamos ahora a ver cmo se guarda esta variable en memoria. Para ello utilizamos el programa
AFD como hemos dicho. Sabemos que este valor se guarda a partir de la direccin de memoria 102h
porque en el lugar correspondiente a la instruccin mov dx, word ptr miLongInt aparece en el volcado
hexadecimal MOV AX, [0102]. Nos desplazamos entonces a la parte de abajo correspondiente al
segmento de datos DS mediante la tecla "F8" y avanzamos con la tecla "Av. Pag." hasta que llegamos a
este lugar de memoria. Tras ejecutar las instrucciones hasta llegar a mov ax, 4c00h para meter en DX y
AX el valor alto y bajo de miLongInt respectivamente, que podemos ver en Fig. 01-04.

Fig. 01-04 - Depurando LENDIAN.COM con AFD


Vemos, pues, que el valor que toman los registros DX:AX = AB CD : EF 01, que es justamente el valor de
la variable miLongInt, adems, vemos que su valor almacenado en memoria es 01 EF CD AB, siguiendo
el mtodo Little Endian, por tanto.

1.2. Registros

Dentro del procesador 8086 existen 14 registros de 16 bits, su misin es almacenar datos o direcciones de
memoria de forma temporal a lo largo del programa. Hay que utilizarlos siempre que se pueda porque los
accesos a memoria son mucho ms lentos que los accesos a los registros. Adems, hay ciertas operaciones
que slo se pueden realizar sobre los registros. Hay registros que tienen caractersticas especiales, los hay
que estn especializados en una determinada accin y no todos sirven para realizar algn proceso en
concreto. Por ejemplo:
AX, BX, CX, DX pueden utilizarse como registros de 16 bits o el byte superior e inferior por separado
como sendos registros de 8 bits. No hay ningn otro registro con esta caracterstica.

1.2.1. Registros de propsito general


Son los registros ms utilizados durante el programa.

Registro AX. Es el acumulador principal, utilizado para operaciones que implican entrada/salida y
la mayor parte de la aritmtica.

Registro BX. Es el registro base. Es el nico de proposito general que puede ser un ndice para
direccionamiento indexado, as como empleado para clculos.

Registro CX. Es el registro contador. Es muy utilizado con la orden loop para repetir un ciclo.
Tambin es usado para el corrimiento de bits y para muchos clculos.

Registro DX. Es el registro de datos. Es utilizado en operaciones de entrada/salida, as como en la


multiplicacin y divisin con cifras grandes trabajando con el AX.

1.2.2. Registros de segmento


Definen reas de 64 Kb dentro del espacio de direcciones de 1 Mb del 8086. Estas reas pueden solaparse
total o parcialmente. No es posible acceder a una posicin de memoria no definida por algn segmento: si
es preciso, habr de moverse alguno.

Registro CS (CODE SEGMENT). El DOS almacena la direccin inicial del segmento de cdigo
de un programa en el registro CS. Esta direccin de segmento, ms un valor de desplazamiento en
el registro de apuntador de instruccin (IP), indica la direccin de una instruccin que es buscada
para su ejecucin. Para propsitos de programacin normal, no se necesita referenciar el registro
CS.

Registro DS (DATA SEGMENT). La direccin inicial de un segmento de datos de programa es


almacenada en el registro DS. En trminos sencillos, esta direccin, ms un valor de
desplazamiento en una instruccin, genera una referencia a la localidad de un byte especfico en el
segmento de datos. Suele ser necesario inicializarlo.

Registro SS (STACK SEGMENT). Permite la colocacin en memoria de una pila, para


almacenamiento temporal de direcciones y datos. El DOS almacena la direccin de inicio del
segmento de pila de un programa en el registro SS. Esta direccin de segmento, ms 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 propsitos de programacin normal, no se necesita referenciar el
registro SS.

Registro ES (EXTRA SEGMENT). 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 direccin de segmento apropiada.

1.2.3. Registros punteros de pila

Registro SP (STACK POINTER). Apunta a la cabeza de la pila. Utilizado en las instrucciones de


manejo de la pila. El MS-DOS suele colocar la pila al final del espacio de memoria ocupada por el
programa. El SP lo coloca justo en la cima de la pila. Todos los datos que se almacenan en la pila
son de longitud palabra y cada vez que se introduce algo en ella por medio de manejo de pila
(PUSH y POP), el puntero se decrementa en dos (puesto que es una palabra: 2 bytes).

Registro BP (BASE POINTER). Apunta a una zona de la pila dedicada al almacenamiento de


datos (variables locales y parmetros de las funciones en los programas compilados).

1.2.4. Registros ndices

Registro SI (SOURCE INDEX). Utilizado como registro de ndice en ciertos modos de


direccionamiento indirecto, tambin se emplea para trabajar con operaciones de cadenas.

Registro DI (DESTINATION INDEX). Utilizado en determinados modos de direccionamiento


indirecto y para trabajar con operaciones de cadenas.

1.2.5. Puntero de instrucciones o contador de programa

Registro IP (INSTRUCTION POINTER). Marca el desplazamiento de la instruccin en curso


dentro del segmento de cdigo. Es automticamente modificado con la lectura de una instruccin.

1.2.6. Registro de estado o de indicadores (flags)


Es un registro de 16 bits de los cules 9 son utilizados para indicar diversas situaciones durante la
ejecucin de un programa. Los bits 0, 2, 4, 6, 7 y 11 son indicadores de condicin, que reflejan los
resultados de operaciones del programa; los bits del 8 al 10 son indicadores de control y el resto no se
utilizan. Estos indicadores pueden ser comprobados por las instrucciones de salto condicional, lo que
permite variar el flujo secuencial del programa segn el resultado de las operaciones.
15

14

13

12

11

10

09

08

07

06

OF

DF

IF

TF

SF

ZF

05

04
AF

03

02
PF

01

00
CF

Tabla 01-12 - Estructura de la Palabra de Banderas


La descripcin de las banderas es la siguiente:

CF (Carry Flag). Indicador de acarreo. Su valor ms habitual es lo que nos llevamos en una suma o
resta.

OF (Overflow Flag). Indicador de desbordamiento. Indica que el resultado de una operacin no


cabe en el tamao del operando destino.

ZF (Zero Flag). Indicador de resultado 0 o comparacin igual.

SF (Sign Flag). Indicador de resultado o comparacin negativa.

PF (Parity Flag). Indicador de paridad. Se activa tras algunas operaciones aritmeticolgicas para
indicar que el nmero de bits a uno resultante es par.

AF (Auxiliary Flag). Para ajuste con operaciones BCD.

DF (Direction Flag). Indicador de direccin. Manipulando bloques de memoria, indica el sentido


de avance (ascendente /descendente).

IF (Interrupt Flag). Indicador de interrupciones: puesto a 1 estn permitidas.

TF (Trap Flag). Indicador de atrape (ejecucin paso a paso).

1.2.7 Resumen grfico del conjunto de registros del 8086:


1.2.7.1. Registros de propsito general
15

14

13

12

Nibble 3

11

10

09

08

Nibble 2

07

06

05

04

Nibble 1

AH

03

02

01

00

01

00

01

00

01

00

01

00

Nibble 0

AL
Tabla 01-13 - Registro AX

15

14

13

12

Nibble 3

11

10

09

08

Nibble 2

07

06

05

04

Nibble 1

BH

03

02

Nibble 0

BL
Tabla 01-14 - Registro BX

15

14

13

12

Nibble 3

11

10

09

08

Nibble 2

07

06

05

04

Nibble 1

CH

03

02

Nibble 0

CL
Tabla 01-15 - Registro CX

15

14

13

12

Nibble 3

11

10

09

08

Nibble 2

07

06

05

04

Nibble 1

DH

03

02

Nibble 0

DL
Tabla 01-16 - Registro DX

1.2.7.2. Registros Punteros de Pila


15

14

13

12

11

10

09

08

07

06

05

04

03

02

Tabla 01-17 - Registro SP


15

14

13

12

11

10

09

08

07

06

05

04

03

02

01

00

05

04

03

02

01

00

05

04

03

02

01

00

05

04

03

02

01

00

05

04

03

02

01

00

05

04

03

02

01

00

05

04

03

02

01

00

05

04

03

02

01

00

05

04

03

02

01

00

Tabla 01-18 - Registro BP

1.2.7.3. Registro Puntero de Instrucciones


15

14

13

12

11

10

09

08

07

06

Tabla 01-19 - Registro IP

1.2.7.4. Registros de Segmento


15

14

13

12

11

10

09

08

07

06

Tabla 01-20 - Registro CS


15

14

13

12

11

10

09

08

07

06

Tabla 01-21 - Registro DS


15

14

13

12

11

10

09

08

07

06

Tabla 01-22 - Registro ES


15

14

13

12

11

10

09

08

07

06

Tabla 01-23 - Registro SS

1.2.7.5. Registros de ndice


15

14

13

12

11

10

09

08

07

06

Tabla 01-24 - Registro SI


15

14

13

12

11

10

09

08

07

06

Tabla 01-25 - Registro DI

1.2.7.6. Registro de banderas


15

14

13

12

11

10

09

08

07

06

OF

DF

IF

TF

SF

ZF

Tabla 01-26 - Registro de banderas

AF

PF

CF

1.3. Puertos de entrada/salida


Dada la limitacin de memoria del 8086, se le aadi un sistema de acceso a perifricos denominado
"puertos de entrada/salida". Las tarjetas colocan su memoria en un espacio de direcciones especial,
separado de la RAM principal del ordenador, con direcciones en el intervalo 0h-3FFh, es decir 1.024
puertos en total. El acceso a estas posiciones se lleva a cabo mediante instrucciones especiales de
entrada/salida, que se encuentran bastante limitadas en sus posibilidades, lo que provoca que las tarjetas
que utilizan este sistema ocupen muy pocas direcciones de E/S. Este es el sistema ms utilizado, y no
existe ninguna tarjeta del PC que no lo utilice. Se utilizan las instrucciones IN y OUT para manejar E/S
directamente a nivel de puerto.
IN transfiere informacin desde un puerto de entrada al AL si es un byte y al AX si es una palabra. El
formato general es:
IN reg-acum, puerto

OUT transfiere informacin desde un registro a un puerto, si es un byte y desde AX si es una palabra. El
formato general es:
OUT puerto, reg-acum

Podemos especificar una direccin de puerto esttica o dinmicamente:


Estticamente: Podemos utilizar un operando desde 0 hasta 255 directamente como:
Input
Output

IN AL, puerto
OUT puerto, AX

; Entrada de un byte
; Salida de una palabra

Dinmicamente: Podemos utilizar el contenido del registro DX de 0 a 65.535 indirectamente, puede ser
adecuado para ir incrementando DX a la vez que se van procesando las direcciones de los puertos. Veamos
el siguiente ejemplo:
MOV DX, 60h
IN AL, DX

; Puerto 60h (teclado)


; Obtiene un byte

Podemos ver algunos de los principales puertos en el apndice E.


Aunque la prctica recomendada es utilizar las interrupciones del DOS y del BIOS, se pueden pasar por
alto con seguridad para acceder directamente a los puertos 21h, 40-42h, 60h, 61h y 201h.
Por ejemplo, para mandar un carcter a la impresora mediante la interrupcin 17h de la BIOS, debemos
insertar el nmero de puerto de la impresora en el registro DX:
MOV
MOV
MOV
INT

AH, 00h
AL, char
DX, 0
21h

;
;
;
;

Peticin para imprimir


Carcter que se va a imprimir
Puerto de la impresora 0 = LPT1
Llama al DOS

1.4. Organizacin de direcciones: Segmentacin


El diseo del 8086 es de 20 bits para el bus de direcciones y 16 para el de datos. Con 20 bits para el bus de
direcciones el nmero mximo de posiciones de memoria es de 220 bytes = 1.048.576 bytes = 1 Mb (20 es
el exponente del 2); sin embargo nuestros registros son de 16 bits que pueden direccionar a un mximo de

64 Kb (64 Kb es 216 bytes = 65.536 bytes). Cmo acceder entonces al megabyte de memoria?. Una
posible solucin consista en utilizar dos de nuestros registros de 16 bits, lo cul equivaldra a utilizar un
registro de 32 bits, pero por aqul entonces probablemente pensaron que nadie habra de necesitar nunca
tanto, por lo cul idearon un sistema denominado segmentacin que consiste en dividir la memoria en
grupos de 64 Kb. Cada grupo se asocia con un registro de segmento de 16 bits; el desplazamiento dentro
de cada segmento lo proporciona otro registro de 16 bits. Para alcanzar los 20 bits multiplicamos por 16 el
valor del registro de segmento y sumamos el desplazamiento. Obsrvese que multiplicar por 24=16
equivale a correr el nmero cuatro posiciones a la izquierda y los cuatro dgitos de la derecha se rellenan
con ceros, mientras que dividir por 16 equivaldra a correr el nmero 4 dgitos de la derecha y los cuatro
de la izquierda se rellenan con cero.
OFFSET = SEGMENT * 16
SEGMENT = OFFSET / 16 (perdemos los 4 bits inferiores)
direccin = segmento * 16 + desplazamiento
SEGMENT
0010010000010000---OFFSET
----0100100000100010
Direccin de 20 bits 00101000100100100010
Por ejemplo, con DS:SI
====== DS ======
====== SI ======

Esta es la forma DS:SI con la que accedemos a 20 bits con dos registros de 16 bits. El segmento en DS y
el desplazamiento en SI. Obsrvese que DS y SI se solapan, esto implica que existe ms de una forma de
acceder a la misma direccin de memoria, por ejemplo, 3D00h:0300h es equivalente a 3D30:0000h.
Veamos por qu:
Tngase en cuenta que 16 decimal equivale a 10 hexadecimal. Y como sabemos, multiplicar por 10
equivale a aadir un cero a la derecha. Pues bien, vamos a encontrar la direccin de memoria accedida por
estas segmentaciones:
3D00h:0300h => direccin = 3D00h * 10h + 0300h = 3D000 + 0300h = 3D300h
3D30h:0000h => direccin = 3D30h * 10h + 0000h =
= 3D300h

1.4.1. Modos de direccionamiento


Son los distintos modos de acceder a los datos en memoria por parte del procesador. Antes de nada, la
sintaxis general de las instrucciones suele ser la siguiente:
instruccin DESTINO, FUENTE
Que indica que el contenido de fuente se deja en destino.

Direccionamiento inmediato. El operando es una constante situada detrs del cdigo de la


instruccin. Sin embargo, como registro destino no se puede indicar uno de segmento (habr que
utilizar uno de datos como paso intermedio).

ADD
dato
MOV
DATO
MOV

AX,
EQU
AX,
dw
AX,

0FFFh
0FFFh
dato
0FFFh
OFFSET dato

; 0FFFh es una constante numrica


; Declaramos un smbolo constante
; Dato es una variable
; AX = direccin de memoria de dato

Direccionamiento de registro. Los operandos, necesariamente de igual tamao, estn contenidos


en los registros indicados en la instruccin.

MOV AX, [57D1h]


MOV AX, ES:[429Ch]

Direccionamiento directo o absoluto. El operando est situado en la direccin indicada en la


instruccin, relativa al segmento que se trate.

MOV AX, [57D1h]


MOV AX, ES:[429Ch]

Direccionamiento indirecto. El operando se encuentra en una direccin sealada por un registro


de segmento*16 ms un registro base (BX/BP) o ndice (SI/DI) (Nota: BP acta por defecto con
SS).

MOV AX, [BP]


MOV ES:[DI], AX

Indirecto con ndice o indexado. El operando se encuentra en una direccin determinada por la
suma de un registro de segmento*16, un registro de ndice Si o DI y un desplazamiento de 8 16
bits.

MOV AX, [DI+desp]


MOV [SI+desp], BX

Indirecto con base e ndice o indexado a base. El operando se encuentra en una direccin
especificada por la suma de un registro de segmento*16, uno de base, uno de ndice y
opcionalmente un desplazamiento de 8 16 bits.

MOV AX, ES:[BX+DI+desp]


MOV CS:[BX+SI+desp], CX

; AX = [SS*16+BP]
; [ES*16+DI] = AX

; AX = desp[DI]
; desp[SI] = BX

; AX = ES:desp[BX][DI]
; CS:desp[BX][SI] = CX

1.4.2. Tipos de direccionamiento

Corto. Si es alcanzada por medio de un desplazamiento y est limitada a una distancia de -128 a
127 bytes.(8 bits)

Cercano. Si es alcanzada por medio de un desplazamiento y est limitada a una distancia de


-32.768 a 32.767 bytes dentro del mismo segmento.

Lejano. Si est en otro segmento y es alcanzada por medio de una direccin de segmento y un
desplazamiento.

1.4.3. La pila
Es un bloque de memoria de estructura LIFO ("Last Input First Output": ltimo en entrar, primero en
salir), grficamente podra decirse que tiene una estructura de una pila de platos: el primero se coloca
sobre la mesa, el segundo sobre el primero, el tercero sobre el segundo y as sucesivamente; y cuando
vamos a coger un plato, el primero que cogemos es el ltimo que pusimos, el de ms arriba.

El tamao de la pila hay que definirlo en un archivo EXE, si es un archivo COM el DOS establece la pila
al final del segmento de 64K y carga el registro SP con FFFEh, la parte superior de la pila (el tope de la
pila) si el segmento de 64K es suficientemente grande. Se incrementa en direccin a los datos.
La pila se direcciona mediante desplazamientos desde el registro SS (stack segment). Las posiciones
individuales dentro de la pila se calculan sumando al contenido del segmento de pia SS un desplazamiento
contenido en el registro puntero de pila SP. Todos los datos que se almacenan en la pila son de longitud
palabra, y cada vez que se introduce algo en ella por medio de las instrucciones de manejo de pila (PUSH
y POP), el puntero se decrementa en dos; es decir, la pila avanza hacia direccines decrecientes. El registro
BP suele utilizarse normalmente para apuntar a una cierta posicin de la pila y acceder indexadamente a
sus elementos, generalmente en el caso de variables, sin necesidad de desapilarlos para consultarlos.
La pila es utilizada para preservar el valor de un registro o de una variable de 16 bits (1 palabra)
metindola en la pila con la orden PUSH que salvamos para recuperarla posteriormente con la orden POP
que cogemos. Las rdenes POP deben hacerse justo en orden inverso a las PUSH puesto que la pila tiene
estructura LIFO. Su empleo es la nica forma de definir variables locales. Tambin es utilizada
internamente para cargar el IP cuando llamamos a una subrutina y luego se recoge ste. Tambin se puede
emplear para pasar parmetros a los procedimientos.
Puesto que la pila va a ser muy utilizada, tanto por el programador como por operaciones internas, es muy
necesario ir desapilando todo lo apilado para evitar una prdida de control sobre el ordenador por
desbordamiento de sta.

Fig. 01-05 - Funcionamiento de la Pila

1.4.4. Memoria Interna


La microcomputadora posee dos tipos de memoria interna:

RAM. Memoria de acceso aleatorio.

ROM. Memoria de slo lectura.

Los bytes en memoria se numeran en forma consecutiva, iniciando con 00, de modo que cada localidad
tiene un nmero de direccin nico.
Aqu abajo vemos un mapa fsico de la memoria del PC tipo 8086. Del primer megabyte de memoria, los
primeros 640K los ocupa la RAM, la mayor parte de la cul est disponible para su uso.

Inicio

Direccin

Uso

Dec 960K

Hex F0000

64K sistema base de ROM

768K

C0000

192K rea de expansin de memoria (ROM)

640K

A0000

128K rea de despliegue de vdeo (RAM)

0K

640K memoria (RAM)

Memoria Superior
Memoria Convencional

Tabla 01-28 - Mapa de la Memoria Fsica

ROM. Es un chip especial de memoria que slo puede ser leda. Debido a que las instrucciones y
los datos estn "grabados" permanentemente en un chip de ROM, no pueden ser alterados. El
Sistema Bsico de Entrada/Salida (BIOS) de ROM inicia en la direccin 768K y maneja los
dispositivos de entrada/salida, como un controlador de disco duro. La ROM que inicia en 960K
controla las funciones bsicas de la computadora, como la autoprueba al encender, patrones de
puntos para los grficos y autocargador de disco. Cuando se enciende la computadora, la ROM
realiza ciertas verificaciones.

RAM. Un programador est preocupado principalmente con la RAM, que sera mejor llamada
memoria de lectura-escritura. La RAM se dispone como una "hoja de trabajo" para
almacenamiento temporal y ejecucin de programas. Ya que el contenido de la RAM se pierde
cuando se apaga la computadora, debe reservar almacenamiento externo para guardar programas y
datos.

1.4.5. Memoria Convencional

Fig. 01-06 - Mapa de la Memoria Convencional


Encender la computadora provoca una "inicializacin" (a veces llamado "arranque en fro"). El procesador
introduce un estado de restauracin, limpia todas las localidades de memoria (es decir) coloca cero en
todas ellas), realiza una verificacin de paridad de la memoria y asigna al registro CX la direccin del
segmento FFFF[0]h y al registro IP el desplazamiento cero. Por tanto, la primera instruccin a ejecutarse
est en la direccin formada por la pareja CS:IP, que es FFF0h, la cul es el punto de entrada al BIOS en
ROM.
La rutina de BIOS que se inicia en FFFF0h verifica los diferentes puertos para identificarlos e inicializa
los dispositivos que estn conectados a la computadora. Despus el BIOS establece dos reas de datos. En
la Fig. 01-06 vemos un mapa de la memoria convencional.

La tabla de servicios de interrupciones se inicia en memoria baja en la localidad 0 y contiene las


direcciones de las interrupciones que ocurren.

rea de datos de BIOS. Se inicia en la localidad 0040:0000, que est estrechamente relacionada
con los dispositivos conectados. A continuacin el BIOS determina si est presente un disco que
contenga los archivos de sistema del DOS y, en caso de que as sea, accede al cargador de arranque
desde ese disco, cargando los archivos de sistema IO.SYS y MSDOS.SYS desde el disco hacia la
memoria y transfiere el control al punto de entrada del IO.SYS.

1.4.6. Segmentos de Ensamblador


Tanto el cdigo como los datos se agrupan en bloques conocidos como segmentos. A pesar de que tienen
el mismo nombre, los segmentos de un programa ensamblador no son equivalentes a los segmentos en que
divide la memoria el procesador 8086. Una diferencia notable es el hecho de que un segmento
ensamblador puede comenzar en cualquier posicin de memoria mientras que, como ya se vio, los
segmentos de memoria comienzan siempre en posiciones mltiplos de 16. Si bien tambin tienen
similitudes:
Un segmento no puede ocupar, entre cdigo y datos, ms de 64 kilobytes de memoria.
El nombre de un segmento puede utilizarse como valor simblico del segmento de memoria en que se
encuentra ste.
Codigo SEGMENT
MOV AX, Codigo
Codigo ENDS

; Coloca en AX el valor del segmento


; donde se encuentra el cdigo

Sin embargo, esta forma de utilizar el nombre del segmento de cdigo slo es posible en programas de
tipo .EXE, en programas de tipo .COM ni si quiera es necesario, puesto que slo cuenta con un segmento.
La forma de definir un segmento mediante la sintaxis clsica de MASM es mediante una pareja de
directivas que marcan su comienzo y final. Estas directivas son SEGMENT para el comienzo y ENDS
para el final. Ambas van precedidas por el nombre que se le da al segmento y, en el caso de la primera, va
seguida de una serie de palabras que indican algunas caractersticas del segmento. Obsrvese que con la
sintaxis de NASM no es necesario definir el final del segmento, pues se considera implcito al inicio del
siguiente.
Las caractersticas o atributos que se aplican a la directiva SEGMENT son la alineacin, la combinacin y
la clase, las cuales pueden darse en cualquier orden. En caso de que se omitan algunos de estos cuatro
tipos de atributos, el ensamblador tomar para ellos sus valores por defecto.

1.4.6.1. Alineacin
Se utiliza para que el segmento comience en una direccin de memoria que sea mltiplo de un valor
determinado. Sus posibles valores son los siguientes:
Alineacin

Mltiplo de

BYTE

WORD

DWORD

PARA

16

PAGE

256

MEMPAGE

4096
Tabla 01-29 - Alineacin

El valor por defecto es PARA, el cul es utilizado en la mayora de las ocasiones, puesto que, al utilizar
una direccin mltiplo de 16 como comienzo hace que el segmento ensamblador coincida exactamente
sobre un segmento de memoria, formndose as una equivalencia entre ambos.
Obsrvese que el 8086 y 80286 tienen un bus de datos de 16 bits (una palabra), por lo que trabajan ms
rpido si acceden a datos con tamao de palabra. Supongamos el valor 8A9Bh que se encuentra en la
direccin de memoria 912-913, el procesador los podr recuperar en una sola pasada metindolos, por
ejemplo en el registro AX; sin embargo, si este mismo valor se encontrase en 911-912 tendra que
recuperarlo en dos pasos: primero leera 910-911, metiendo 9B en AL y luego leera 912-913 metiendo 8A
en AH. Vemoslo grficamente:
912

913

9B

8A

AL

AH
Tabla 01-30 - Primer caso

910

911

912

913

??

8A

9B

??

AH

AL
Tabla 01-31 - Segundo caso

Contamos con la directiva ALIGN para informar al ensamblador que nos alinee elementos en lmites. Por
ejemplo "ALIGN 2" alinea en un lmite de palabra. De forma que en un programa con muchos datos
resulta interesante su uso para acelerar el proceso de carga. Se emplea inmediatamente antes del dato que
queramos alinear. Tenemos el cdigo de ejemplo en "AlignC?1.asm". Evidentemente con esta directiva se
ocupa ms espacio, comprubese eliminndolo del cdigo y volviendo a compilarlo; sin embargo, para
una coleccin de varias palabras, slo necesitamos usarlo para la primera.
FASM MASM NASM Resultado en pantalla
Cdigo Cdigo Cdigo ; Salida con DEBUG:

[bin]

[bin]

[bin]

; Sin "ALIGN 2"


; C:\Trabajo\AOE\Codigos\Cap01>debug ALIGNCN1.com
; -d 100, 10F
; 0CC8:0100 B8 09 01 B8 00 4C CD 21-3F 9B 8A 61 20 70 61
72
.....L.!?..a par
;
; Con "ALIGN 2"
; C:\Trabajo\AOE\Codigos\Cap01>debug ALIGNCN1.com
; -d 100, 10F
; 0CC8:0100 B8 0A 01 B8 00 4C CD 21-3F 90 9B 8A 20 70 61
72
.....L.!?... par
; Sin "ALIGN 2" 8A9Bh est en 109-10A, con "ALIGN 2" est en
10A-10B

Source 01-01 - AlignC?1.asm

1.4.6.2. Combinacin

Especifica cmo debe combinarse el segmento con otros que tengan el mismo nombre y que se encuentren
en otros mdulos del programa.
Combinacin Forma de combinacin
PRIVATE

No se combina con otros segmentos del mismo nombre

PUBLIC

Se combina con los segmentos del mismo nombre en un nico segmento

STACK

El segmento se combina con otros del mismo nombre para formar la pila del programa

COMMON

Coloca el segmento en la mismas posiciones de memoria que otros con el mismo nombre

AT xxx

El segmento hace referencia al segmento fsico indicado por el valor numrico xxxx. Ese
tipo de segmentos se utilizan para acceder a memoria fuera del programa, como vectores
de interrupcin o datos de la BIOS

MEMORY

El segmento se colocar al final del programa, permitiendo utilizar la memoria que hay
ms all del mismo. Slo puede haber un segmento de este tipo y, si hay varios, el resto se
tratan como COMMON

VIRTUAL

Define un tipo de segmento comn a varios mdulos, pero que se define dentro de otro
Tabla 01-31 - Combinacin

El valor que se toma por defecto es PRIVATE.

1.4.6.3. Clase
Especifica un nombre de clase entre comillas para el segmento que el enlazador utilizar a la hora de
ordenar los segmentos. Esta ordenacin provocar que segmentos con el mismo atributo de clase se
coloquen agrupados unos tras otros. Esta caracterstica se utiliza para conseguir que todos los segmentos
de un mismo tipo (datos, cdigo, pila) se coloquen juntos en memoria cuando se cargue el programa.
Ejemplos:

datos SEGMENT PARA PUBLIC 'data'


; Abre el segmento de datos
msg db 'Hola, mundo!$'
; Mensaje a imprimir
datos ENDS
...
ASSUME CS: Codigo, DS: Datos
MOV AX, SEG datos
MOV DS, AX
datos1 SEGMENT PARA PUBLIC 'data'
msg1 DB 'Hola, $'
; Mensaje
datos1 ENDS
datos2 SEGMENT PARA PUBLIC 'data'
msg2 DB 'mundo!$'
; Mensaje a
datos2 ENDS
...
datos GROUP datos1, datos2
ASSUME CS: codigo, DS: datos

; Abre el segmento de datos


a imprimir
; Abre el segmento de datos
imprimir

Los dos cdigos fuente completos se pueden ver en el directorio Cap2 en los archivos MundoXM1.asm y
SegtosM1.asm. Ambos ejemplos tienen, a efectos prcticos, el mismo resultado, lo veremos en el siguiente
captulo.

pila SEGMENT PARA STACK 'stack'


DW 30h DUP (?)
pila ENDS

; Define la pila del programa


; 30h palabras de pila

video SEGMENT AT 0B800h


video ENDS

; Define un segmento para direccionar


; la memoria de vdeo en modo texto

1.4.6.4. Acceder a datos de Segmento


Para acceder a los datos de segmento es preciso meter su direccin dentro de un registro de segmento. Si
por ejemplo hemos definido un registro de segmento llamado "datos" como en el primer ejemplo anterior,
podemos indicarle al ensamblador dnde se encuentra de la siguiente forma:
MOV AX, [SEG] datos
MOV DS, AX
ASSUME DS:datos

Es muy conveniente recordar que no se le puede dar un valor directamente a un registro de segmento, sino
que hay que utilizar un registro de intermediario, como AX en este caso. Con la sintaxis NASM y FASM
no podremos usar ASSUME, puesto que no nos permite "asumir" nada y basta con la primera parte.
Mediante las nuevas directivas de segmento de la sintaxis MASM podemos, adems hacerlo de otra
manera.
.data
msg db 'Hola, mundo!$'
...
.CODE
MOV AX, @DATA
MOV DS, AX

; Abre el segmento de datos


; Mensaje a imprimir

Para acceder a una direccin de memoria, se puede poner explcitamente el valor del segmento donde est
aunque ya lo tenga el segmento DS. Por ejemplo:
MOV AX, DS:msg

La directiva ASSUME puede ir seguida de uno o varios nombres de registros de segmento seguidos de dos
puntos y el nombre del segmento hacia el que estn apuntando. Un ejemplo sera:
ASSUME CS:Codigo, DS:Datos, SS:Pila

En caso de que se desee anular la asociacin entre un registro de segmento y un segmento, se puede
utilizar el nombre de segmento NOTHING para indicar este hecho.
ASSUME DS:Datos
ASSUME DS:NOTHING

; Informa que DS apunta al segmento Datos


; Informa que DS ya no a punta a Datos

Un detalle importante es que ASSUME es una directiva y, como tal, no genera cdigo que cargue en los
registros de segmento el valor que indica. Es, por tanto, labor del programador el iniciar los registros de
segmento de forma adecuada. Es adems imprescindible colocar al principio de todos los segmentos del
cdigo la directiva ASSUME, asociando el registro CS al segmento actual.
Codigo SEGMENT
ASSUME CS:Codigo

En el caso de programas EXE se aadir otra directiva opcional ASSUME asociando el registro SS al
segmento de pila, puesto que el propio MSDOS se encarga de inicializar los registros SS y SP al segmento
de pila definido por el programa, por lo que no habr que preocuparse por cambiarlos.
Los segmentos, adems, se pueden agrupar entre s para formar segmentos mayores mediante la directiva
GROUP que va precedida por el nombre del nuevo segmento formado por la combinacin de los
segmentos cuyos nombres se indican separados por comas a continuacin de la directiva GROUP. El
tamao conjunto de los segmentos de un grupo no debe superar los 64Kb. El nombre de este grupo puede
utilizarse como si fuese un nombre de segmento. Ya hemos visto un ejemplo anteriormente.
Recurdese que muchas de estas acciones se pueden obviar utilizando directivas simplificadas de
segmento, que son: .MODEL, .CODE, .CONST, .DATA, .DATA?, .FARDATA, .FARDATA?,
.STACK, .STARTUP, y .EXIT. La estructura de un programa en ensamblador con estas directivas vienen
ms adelante.

1.4.6.5. Tipos de Modelos de Memoria


La sintaxis de MASM soporta modelos de memoria estndar usados por lenguajes de alto nivel.
Modelo de
Memoria

Cdigo por
Defecto

Datos por
Defecto

Sistema Operativo

Datos y Cdigo
combinados

Tiny

Cercano

Cercano

MS-DOS

Small

Cercano

Cercano

MS-DOS,
Windows

No

Medium

Lejano

Cercano

MS-DOS,
Windows

No

Compact

Cercano

Lejano

MS-DOS,
Windows

No

Large

Lejano

Lejano

MS-DOS,
Windows

No

Huge

Lejano

Lejano

MS-DOS,
Windows

No

Flat

Cercano

Cercano

Windows NT

Tabla 01-32 - Modelos de Memoria


Los modelos Small, Medium, Compact, Large y Huge son los modelos de memoria tradicionalmente
reconocidos por la mayora de lenguajes.

El modelo SMALL soporta un segmento de datos y un segmento de cdigo. Todos los datos y
cdigos son cercanos por defecto.

El modelo LARGE soporta mltiples segmentos de datos y mltiples segmentos de cdigo. Todos
los datos y cdigos son lejanos por defecto.

El modelo MEDIUM soporta mltiples segmentos de cdigo y un solo segmento de datos.

El modelo COMPACT soporta un solo segmento de cdigo y mltiples segmentos de datos.

El modelo HUGE soporta objetos de datos mayores que un solo segmento, pero la implementacin
de este modelo debe ser cosa del programador. Puesto que el ensamblador no porporciona soporte
directo para esta caracterstica, este modelo es equivalente al LARGE.

El modelo TINY slo es admitido por el MS-DOS. Aloja todos los datos y cdigo en el mismo
segmento que no puede sobrepasar los 64Kb de longitud, al igual que el tamao del programa
completo.

El modelo FLAT funciona exactamente igual que el modelo TINY, slo que en 32 bits, alojndose
cdigo y datos en el mismo y nico segmento de 232 = 4 gigas de tamao. Para poder utilizarlo, hay
que anteponerle al menos la directiva .386. Las direcciones y punteros son todos cercanos de 32
bits.

1.4.6.6. Smbolos Predefinidos


La sintaxis MASM incluye algunos smbolos predefinidos (tambin llamados equivalencias predefinidas).
Podemos usar estos smbolos en cualquier punto de nuestro cdigo para recoger su valor. Slo hay que
tener en cuenta las maysculas y minsculas en caso de que se especifique la opcin /Cp.
Smbolos predefinidos con informacin de segmentos:
Smbolo

Descripcin

@code

Devuelve el nombre del segmento de cdigo

@CodeSize

Devuelve un entero que representa la distancia por defecto al cdigo

@CurSeg

Devuelve el nombre del segmento actual

@data

Expande hasta el DGROUP

@DataSize

Devuelve un entero que representa la distancia por defecto a los datos

@fardata

Devuelve el nombre del segmento definido por .FARDATA

@fardata?

Devuelve el nombre del segmento definido por .FARDATA?

@Model

Devuelve el modelo de memoria seleccionado

@stack

Expande al DGROUP para pilas cercanas o al STACK para pilas lejanas

@WordSize

Proporciona el atributo de tamao del segmento actual


Tabla 01-33 - Smbolos de Segmento

Smbolos predefinidos con informacin de mbito:


Smbolo

Descripcin

@Cpu

Contiene una mscara de bits especificando el modo de procesador

@Environ Devuelve valores de las variables de entorno durante el ensamblaje


@Interface Contiene informacin acerca de los parmetros del lenguaje
@Version

Representa el texto equivalente del nmero de versin del MASM. P.e. para MASM 6.1., lo
expande a 610.
Tabla 01-34 - Smbolos de mbito

Smbolos predefinidos con informacin de fecha y hora:

Smbolo

Descripcin

@Date

Proporciona la fecha actual del sistema durante el ensamblaje

@Time

Proporciona la hora actual del sistema durante el ensamblaje


Tabla 01-35 - Smbolos de mbito

Smbolos predefinidos con informacin del fichero:


Smbolo

Descripcin

@FileCur

Nombre y extensin del fichero actual

@FileName

Da el nombre del fichero principal que est siendo ensamblado

@Line

Da el n de lnea del cdigo fuente del fichero actual


Tabla 01-36 - Smbolos de Informacin de Fichero

Smbolos de Manipulacin de Macros:


Smbolo

Descripcin

@CatStr

Devuelve la concatenacin de dos cadenas

@InStr

Devuelve la posicin inicial de una cadena dentro de otra

@SizeStr

Devuelve la longitud de una cadena

@SubStr

Devuelve una subcadena dentro de otra


Tabla 01-37 - Smbolos de Manipulacin de Macros

1.5. Programas ejecutables sobre MS-DOS

Fig. 01-07 - Estructura en Memoria de los programas COM


Aparte de los ficheros batch, slo son los archivos .COM y .EXE, llamados as porque esta es su
extensin. La diferencia bsica entre los dos es que los .COM son una imagen exacta del programa
cargado en memoria mientras que los EXE, su estructura final en memoria se la da el DOS, y que los
COM no pueden superar los 64K de tamao, mientras que los EXE no tienen esta restriccin. Los
programas COM son ms rpidamente cargados en memoria porque no necesitan que el DOS les de su
estructura y son ms pequeos, pero esto es inapreciable en los ordenadores actuales. Los ficheros COM
son una reliquia del pasado, cuando la memoria era escasa y los programas no pasaban de los 64 Kb y se
han ido manteniendo por compatibilidad; si bien, para crear programas residentes en memoria son muy
adecuados y su modelo de memoria es parecido al flat de windows.

Fig. 01-08 - Estructura en Memoria de los Programas EXE


En los 64 Kb que pueden tener los programas COM como mximo, se han de incluir el cdigo de
programa, los datos y el stack. Esto tiene como consecuencia que los registros de segmento durante el
inicio del programa y durante la ejecucin del mismo apunten al inicio del semgneto de memoria de 64K
que el DOS ha reservado antes de cargar el programa. En los programas EXE, el cdigo, datos y stack se
guardan en segmentos diferentes que pueden estar repartidos en diferentes segmentos dependiendo de su
tamao.
Independientemente de si se ejecuta un programa COM o EXE, el DOS crea antes de la ejecucin del
programa una estructura de datos en la memoria, con el nombre de PSP (Program Segment Prefix), que se
compone de 256 bytes. Se antepone inmediatamente al programa en la memoria, como muestran las Fig.
01-07 y Fig. 01-08:

1.5.1. El PSP
Realmente es una reliquia del DOS, mantenido por compatibilidad. Contiene numerosos datos que el DOS
necesita para la gestin de un programa [bin], aunque para un programador, la mayora de esta
informacin, carece de inters, aunque s hay algo de mucha utilidad con la que podremos gestionar los
parmetros de entrada en la lnea de comandos. Veamos esquemticamente la estructura del PSP:
Direccin Contenido
00h-01h

Llamada de la interrupcin 20h

02h-03h

Direccin final de la memoria ocupada por el programa. Por ejemplo A0000 se pone como
00A0h

04h

Reservado

05h-09h

FAR-CALL a la interrupcin 21h

0Ah-0Dh Direccin de terminacin (direccin del segmento para INT 22h)


0Eh-11h

Direccin de salida de Ctrl+Break (direccin de segmento para INT 23h)

12h-15h

Direccin de salida de error crtico (direccin de segmento para INT 24h)

16h-17h

Segmento del PSP del proceso padre

18-2Bh

Tabla de manejadores de archivo por omisin

2Ch-2Dh Direccin de segmento de las variables de entorno


2Eh-31h

Reservado

32h-33h

Longitud de la tabla de manejadores de archivo

34h-37h

Apuntador lejano a la tabla de manejadores

38h-4Fh

Reservado

50h-51h

Llama a la funcin DOS (INT 21h y RETF)

52h-5Bh

Reservado

5Ch-6Bh FCB #1
6Ch-7Fh FCB #2
80h

Nmero de caracteres en la lnea de comandos

81h-FFh

Lnea de comandos
Tabla 01-38 - Esquema del PSP

El contenido "reservado" indica que son reas no documentadas oficialmente por Microsoft, pero no tiene
la menor trascendencia.
A continuacin describimos algunas de las reas ms relevantes:

En la direccin de 00h se encuentra un comando de lenguaje mquina que llama a una funcin del
DOS para terminar el programa. Vuelve a liberar la memoria del programa y transfiere el control
mediante la ejecucin del programa al procesador de comandos o al programa que ha iniciado la
ejecucin del programa a terminar. Antes se necesitaba este comando al final de un programa
COM o EXE para terminar su ejecucin, pero actualmente se utiliza la funcin 4Ch de la
interrupcin 21h del DOS.

En la direccin 02h se encuentra un word que marca la direccin final de la memoria RAM
reservada para el programa. Si un programa necesita ms memoria RAM adicional, puede
determinar con la ayuda de este valor, si an queda espacio entre su final y el fin de la memoria
RAM reservada. Si este es el caso, puede utilizar esta memoria para sus propios fines, de lo
contrario ha de pedir memoria RAM mediante una funcin DOS.

En 2Ch tenemos el segmento donde se encuentran las variables de entorno, tales como
COMSPEC, PATH, PROMPT, etc.

La direccin 80h registra en un byte el nmero de caracteres que introdujimos en la lnea de


comandos excepto el carcter 13 de retorno de carro, con lo que se deduce que slo pueden ser
entre 0 y 255 caracteres.

La direccin 81h recoge todos los caracteres que se indicaron despus del nombre del archivo
durante la llamada desde la lnea de comandos.

La direccin del PSP en los programas COM viene determinada por la de cualquier registro de segmento
(CS=DS=ES=SS) nada ms comenzar la ejecucin del mismo. Sin embargo, en los programas de tipo
EXE slo viene determinada por DS y ES. En cualquir caso, existe una funcin del DOS para obtener la
direccin del PSP, cuyo uso recomienda el fabricante del sistema en aras de una mayor compatibilidad con
futuras versiones del sistema operativo. La funcin es la 62h y est disponible a partir del DOS 3.0.

1.5.2. Programas COM


Cuando se crea un programa COM, hay que dejarle un hueco al inicio de 100h para que quepa aqu el PSP,
por esto se utiliza la orden ORG 100h, inmediatamente despus es necesario encontrar una sentencia
ejecutable, aunque sea una de salto al inicio del programa, para que ste pueda actuar, por eso solemos
poner un JMP Inicio, por ejemplo.

Como ya hemos dicho, un programa COM puede tener una longitud mxima de 64 Kb (65.536 bytes), de
los que se ha de descontar la longitud del PSP (256 bytes) y al menos 1 word (2 bytes) para la pila, aunque
es recomendable un mnimo de 256 bytes.
Aunque la longitud de un programa COM nunca puede pasar los 64 Kb, el DOS siempre reserva la
memoria RAM completa para ellos, con lo que no se podra llamar a otro programa con "EXEC"; esto se
puede solucionar liberando en el programa COM la memoria que no necesita, con ayuda de una funcin
del DOS, para su utilizacin.
Cuando se pasa el control a un programa COM, todos los registros de segmento apuntan al principio del
segmento COM en la memoria, con ello, el inicio del programa COM se encuentra en la direccin de
offset 100h. El puntero de stack, SP contiene el valor FFFEh, y se encuentra al final del segmento COM
de 64 Kb y va creciendo "hacia abajo", es decir, en direccin al final del programa, y debe ser el
programador el que cuide que no se solapen, en cuyo caso probablemente el programa se colgara.
Un programa COM se puede terminar con un RET ("near return"), que provoca que el programa contine
en la direccin que est como valor superior en la pila, donde el DOS coloc un cero antes de iniciar el
programa COM, por tanto saltamos a la direccin de memoria CS:0000; pero aqu se encuentra el inicio
del PSP donde est la interrrupcin 20h, que termina la ejecucin de un programa. Sin embargo, lo ms
recomendable es terminar mediante la funcin 4Ch de la interrupcin 21h, mediante la cul podemos
pasar adems un mensaje a su invocador en el registro AL, estableciendo el valor 0 como terminacin de
programa normal.

1.5.2.1. Creacin de un programa COM en ensamblador


Ya hemos dicho que un programa COM se guarda en disco como una imagen directa del cdigo mquina
y adems, el DOS no lo carga en RAM en una direccin fija, sino en una divisible por 16, con lo que los
segmentos del programa son desconocidos hasta la propia ejecucin del programa. Debido a todo ello este
tipo de programas no puede tener direcciones de segmento explcitas, es decir, comandos FAR. Slo se
permiten los comandos NEAR, que slo contienen una direccin de offset, no de segmento. De esta forma,
estos comandos siempre se refieren al segmento actual en el registro CS, DS, ES o SS, y no a una
direccin de segmento determinada. Esto implica que no estn permitidos los saltos lejanos ni las llamdas
lejanas, as como instrucciones LDS o LES. Si se usa algo de esto, se podr compilar, pero no se podr
pasar a archivo COM. Sin embargo no est prohibido cargar valores de segmentos constantes, como por
ejemplo, la direccin de segmento de la RAM de vdeo en un registro de segmento.
Tambin sabemos que el DOS asigna toda la memoria a cualquier programa que carga en RAM, lo cul
provoca problemas a un TSR ("Terminate but Stay Resident"), programa que permanece ejecutndose
mientras se puede cargar otro en RAM, pues el DOS supone que no hay ms espacio para cargar un
programa estando ya uno ejecutndose. El mismo problema tenemos cuando pretendemos ejecutar un
programa desde otro.
Esto se puede solucionar de dos formas:

Podemos liberar la memoria ms all del segmento COM de 64K.

O bien liberamos la memoria completa que el programa no necesita, donde tambin se incluye la
memoria no necesitada dentro del segmento COM, obteniendo as ms espacio para otros
programas, pero con el inconveniente de que la pila queda fuera del espacio de memoria protegido
para el programa, pues el DOS lo coloca al final del segmento de 64K del COM. Pero entonces la
pila se ha de desplazar antes de liberar la memoria al final de la memoria reservada; siendo preciso
asignarle un tamao determinado, en la mayora de los casos basta con 256 o 512 bytes.

Atacaremos este asunto en su momento.


Veremos ahora cmo se puede crear un archivo de tipo COM usando la sintaxis del MASM, NASM y
FASM:
Archivo COM usando sintaxis MASM
Existen varios tipos de estructura de archivo COM, veamos una:
FASM

MASM

NASM

Cdigo

Cdigo

Cdigo

[bin]

[bin]

[bin]

Resultado en pantalla

Source 01-02 - EsqCom?1.asm

Versin MASM
En las primeras lneas ponemos un comentario explicando ligeramente de qu trata el programa,
quin es su autor y cul es su actual versin. Obsrvese que los comentarios en ensamblador
comienzan con un punto y coma.
En la lnea 9 definimos un segmento de cdigo que llamaremos "codigo".
En la lnea 10 le decimos al compilador que asuma que todos los segmentos posibles del programa
tan slo estn en uno que es el que hemos definido antes "codigo".
En la lnea 11 provocamos que el compilador salte los primeros 100h bytes para dejar espacio al
PSP.
Tenemos que sealar el comienzo del programa. Eso lo hacemos en la lnea 12 con la etiqueta
"Inicio:" (las etiquetas se marcan con dos puntos). Adems con "jmp entrada" indicamos que se
salte las siguientes lneas hasta el punto de memoria indicado por entrada. Esto es as porque las
lneas que hay en medio no son ejecutables, puesto que son datos.
Las siguientes lneas estn reservadas para introducir datos.
En la lnea 16 definimos el procedimiento entrada con "entrada proc", es el principal del programa;
similar al "main" del lenguaje c. Podramos llamarle de cualquier otra manera, no slo entrada. En
la lnea 23 indicamos el fin de este procedimiento con "entrada endp". El nombre ha de ser el
mismo que el que definimos en la lnea 16. Dentro de este procedimiento es donde vamos a definir
todo lo que va a hacer el programa, y al final de ste es donde le indicamos al compilador que
limpie toda la memoria de este programa y vuelva al DOS.
En la lnea 21 con la instruccin "mov ax, 4c00h" indicamos que "mueva" al registro AX el valor
4C00h o mejor dicho que el registro AX tome ese valor. Pero debera leerse como que el byte
superior de AX, AH tome el valor 4Ch y el byte inferior, AL el valor 00. Esto es as porque en AH
indicamos la funcin que va a realizar la interrupcin 21h del DOS, en este caso finalizacin del
programa, limpieza de memoria y regreso al DOS y en AL sealamos con qu tipo de error ha
finalizado el programa, siendo un cero por defecto que indica sin ningn error.
En la lnea 22 tenemos la instruccin "int 21h", que pide que se ejecute la interupcin 21h del
DOS.

En estas dos lneas tenemos la interrupcin que devuelve la ejecucin al DOS. La interrupcin 21h
del DOS tiene muchas funciones, la que aqu utilizamos la indicamos en el registro AH, es la
nmero 4Ch, que devuelve la ejecucin al DOS. El valor que se mete en AL es opcional y sirve
para indicar si el programa ha tenido alguna malfuncin o no, el valor cero indica que todo ha ido
bien.
En la lnea 24 indicamos el fin del segmento codigo con "codigo ends".
Antes del procedimiento de entrada podramos definir ms procedimientos o macros, ya veremos
cmo.
En la lnea 25 le indicamos al compilador que termina el programa desde donde le dijimos que
empezaba en la lnea 5 con la etiqueta Inicio. Para ello utilizamos "end Inicio".
Muy bien, ya sabemos cmo es la estructura de un programa COM. Ahora vamos a compilarlo.
Para ello abrimos una ventana del emulador del MS-DOS, a no ser que ya trabajes directamente
desde el MS-DOS puro y duro. En el primer caso est en "Inicio->Todos los programas>Accesorios->Smbolo del sistema" en Windows XP. Ahora debes cambiarte al directorio donde
est nuestro cdigo fuente. Utiliza para ello la orden "CD nombre_camino". En mi caso utilizara
"CD c:\Trabajo\AOE\Codigos\Cap01". Una buena idea sera indicarle al smbolo del sistema que
se abra siempre en nuestro directorio. Para ello sitate con el cursor del ratn donde ya te he dicho
que est y pulsa el botn derecho, se te abrir una ventana, donde puedes elegir sus propiedades en
la parte inferior.

Fig. 01-09 - Ruta de Acceso al Smbolo del Sistema


En la pestaa de acceso directo en "Iniciar en", le pondrs tu ruta. En mi caso sera:

Fig. 01-10 - Propiedades del Smbolo del Sistema


De esta forma, cada vez que abras el smbolo del sistema se abrir en tu carpeta.
A parte de esto, es necesario que tengas en el PATH la ruta de los compiladores y enlazadores que
vas a utilizar.
Vamos a compilar el programa con MASM:
>ml /AT EsqComM1.asm [INTRO]

ml es el nombre del compilador de Microsoft de la versin 6.13, que adems se encarga de llamar
al linkador. "/AT" es una variante que le indica al compilador que produzca un archivo de tipo
COM, pero cuidado!, tiene que ir en maysculas. Y "EsqComM1.asm" es el nombre del programa
que se va a compilar, es necesario indicar tambin la extensin.
O bien, si tienes el ensamblador de Borland Turbo Assembler, lo puedes compilar as:
>tasm EsqComM1 [INTRO]
>tlink /t EsqComM1 [INTRO]

Con tasm se ensambla a un archivo objeto. Tlink es el linkador de Borland y "/t" le indica que
produzca un archivo COM.
Ahora ya puedes ejecutar el programa

>EsqComM1 [INTRO]

Vers que no produce ningn resultado porque el programa no hace nada salvo salir al DOS. Pero
nos sirve para saber que lo hemos hecho todo bien, pues el compilador no ha dado ningn mensaje
de error.
Esta es la pantalla de lo que me sale a m:

Fig. 01-11 - Ejemplo de compilacin con ML y EsqComM1.asm

Versin NASM
En la lnea 1 tenemos org 100h , que sera equivalente a resb 100h , que ya sabemos que deja
espacio para el PSP.
Una diferencia importante con la sintaxis de Microsoft es que NASM no permite "asumir" nada,
hay que definirlo explcitamente.
Seguidamente definimos varias secciones:
o section .text para el cdigo.
o Section .data para los datos.
o Section .bss para los datos no inicializados.
El resto es bien conocido.
Para ensamblar dicho cdigo hacemos:
>nasmw -fbin EsqComN1.asm -o EsqComN1.com

Versin FASM
Con use16 le decimos al compilador que genere cdigo de 16 bits.

org 100h reserva espacio para el PSP.


No necesita ningn tipo de etiqueta, a continuacin va el cdigo.
Para ensamblar dicho cdigo usaremos uno de estos dos mtodos, el ms sencillo es el primero:
o Compilarlo directamente desde el editor que trae el paquete FASM.
o

>fasm EsqComF1.asm EsqComF1.com

En el siguiente captulo haremos el famoso "Hola mundo", donde ya veremos un programa que hace algo.
Si vemos este programa con un editor hexadecimal, yo uso el FRHED, observaramos algo como:

Fig. 01-12 - ESQCOMM1.COM en hexadecimal


El primer bloque de nmeros es la direccin en memoria y el segundo es el cdigo de intrucciones de
lenguaje mquina en hexadecimal de nuestro programa. Mientras que el de la derecha es ste traducido a
cdigo ASCII. Es difcil, no obstante entender el sentido de estas instrucciones. Una forma ms sencilla de
entenderlo es utilizando la utilidad DEBUG que viene en todas las versiones de MS-DOS y Windows.
Lanzamos una ventana del "Smbolo del sistema" como ya sabemos y ponemos lo siguiente:
C:\Trabajo\AOE\Codigos\Cap01>debug ESQCOMM1.COM
-u
0D85:0100 EB00
JMP
0102
0D85:0102 B8004C
MOV
AX,4C00
0D85:0105 CD21
INT
21
0D85:0107 7365
JNB
016E
0D85:0109 61
DB
61
0D85:010A 206361
AND
[BP+DI+61],AH
0D85:010D 6D
DB
6D
0D85:010E 62
DB
62
0D85:010F 69
DB
69
0D85:0110 61
DB
61
0D85:0111 7220
JB
0133
0D85:0113 61
DB
61
0D85:0114 6C
DB
6C
0D85:0115 206469
AND
[SI+69],AH
0D85:0118 7265
JB
017F
0D85:011A 63
DB
63
0D85:011B 746F
JZ
018C
0D85:011D 7269
JB
0188
0D85:011F 6F
DB
6F
-q
C:\Trabajo\AOE\Codigos\Cap01>

Se puede observar en el bloque hexadecimal del cdigo desensamblado cmo coincide con lo que nos
indicaba el editor hexadecimal.

La utilidad DEBUG viene explicada en el apndice C. Podemos decir que el comando "u" es para
desensamblar el cdigo del programa ESQCOMM1.COM. De todas estas lneas las que nos interesan son
las tres primeras, las siguientes son desensamblado de las siguientes posiciones de memoria al programa.
Podemos observar que el desensamblado ha sido excelente.
El cdigo mquina en hexadecimal EB00 equivale a JMP 0102, que significa saltar a la posicin de
memoria 0102, que es la lnea siguiente. B8004C equivale a MOV AX, 4C00 y CD21 a INT 21.
Aqu est todo nuestro programa. Lo nico que hace es devolver la ejecucin al sistema operativo.
Vamos a dar a continuacin los otros dos esqueletos posibles para construir un archivo COM con MASM:
EsqCmM1b

EsqComM2

EsqComM3

Cdigo

Cdigo

Cdigo

[bin]

[bin]

[bin]

Resultado en pantalla

Source 01-03 - EsqCmM??.asm

EsqCmM1b.asm
Ya hemos dicho que los archivos COM no usan diferentes segmentos puesto que todo est dentro
del mismo y que tampoco se define una pila puesto que es el propio DOS el que se encarga de
definirsela al final del programa. Sin embargo vemos en esta estructura que se definen diferentes
segmentos y adems una pila. Pero todo esto es virtual porque al final todo ello se engloba dentro
del mismo segmento llamado grupo mediante la directiva de la lnea 4:
grupo group codigo, datos, pila

Le indicamos al ensamblador que agrupe todos estos segmentos en uno solo: grupo.
Y luego, en la siguiente lnea le decimos que asuma que todos los registros de segmento apunten a
nuestro segmento grupo.
Tambin vemos como diferencia que el ttulo del programa lo especificamos con la etiqueta
"TITLE", esto es exactamente igual a utilizar punto y coma, pero es ms vistoso y legible.

EsqComM2.asm
Esta estructura es semejante a la primera pero con unas directivas simplificadas llamadas "de
segmento".
.model tiny indica al compilador que el modelo de datos que vamos a usar va a ser el ms pequeo
de todos, apropiado para archivos COM.
.code indica que aqu empieza el segmento de cdigo y termina donde empieza el siguiente.
.STARTUP es una directiva que sirve para inicializar los segmentos.
.EXIT es equivalente a hacer un mov ax, 4C00h; int 21h.
El resto de las sentencias ya las hemos estudiado. Estas estructuras no son rgidas, se pueden usar
una mezcla de ellas. Por ejemplo:

EsqComM3.asm
Podemos ver la mezcla de sintaxis clsica con simplificada.

1.5.3. Programas EXE


Los programas EXE, al igual que los COM no se cargan en una direccin de memoria fija, sino en alguna
divisible por 16 y, al contrario que los COM, no tienen la limitacin de 64 Kb para el cdigo y poseen
segmentos separados para cdigo, datos y pila que se pueden alinear en orden cualquiera. Dado que los
archivos EXE pueden contener varios segmentos, el empleo de instrucciones FAR es inevitable si se
quiere llamar a un subprograma en el segmento de cdigo X desde el segmento de cdigo Y. Esto nos crea
un problema puesto que a parte de la direccin del subprograma tambin necesita la direccin de segmento
(esto no es sencillo puesto que no se puede prever esta direccin de segmento durante el desarrollo del
programa y en cada ejecucin del programa resulta diferente). En los programas EXE este problema se
resuelve de la siguiente manera: el linkador coloca al inicio de cada archivo EXE una estructura de datos
que contiene las direcciones de todas las referencias de segmento, es decir, la direccin de todos aquellos
comandos FAR, en los que se hace referencia a la direccin de segmento de uno de los diferentes
segmentos de cdigo a datos.
El cdigo mquina de un SALTO LEJANO se compone de cinco bytes:

El primero contiene el cdigo del comando.

La siguiente palabra (dos bytes) la direccin de segmento.

La siguiente palabra (dos bytes) la direccin de segmento a la que ha de saltarse.

No se indica la direccin del cdigo de nuestro comando, sino la direccin del segmento siguiente.
Evidentemente esto no se hace en un archivo COM puesto que como todo est dentro de un rango de 64K
(el mismo segmento), no es necesario.
Veamos la estructura de una cabecera de un archivo EXE:
Direccin Contenido

Tipo

00h-01h

Designacin de un programa EXE consistente en las letras ASCII "MZ" de Mark


Zbikowski, uno de los mejores programadores para DOS de Microsoft.

1 Word

02h-03h

Resto de la divisin de la longitud del archivo por 512

1 Word

04h-05h

Cociente de la divisin de la longitud del archivo por 512

1 Word

06h-07h

Nmero de direcciones de segmento a adaptar

1 Word

08h-09h

Tamao de la cabecera en prrafos

1 Word

0Ah-0Bh Nmero mnimo de prrafos necesitados adicionalmente

1 Word

0Ch-0Dh Nmero mximo de prrafos necesitados adicionalmente

1 Word

0Eh-0Fh

Desplazamiento en prrafos del segmento de pila dentro del mdulo cargado.

1 Word

10h-11h

Contenido del registro SP durante el inicio del programa.

1 Word

12h-13h

Suma de control de la cabecera del archivo EXE

1 Word

14h-15h

Contenido del registro IP durante el inicio del programa

1 Word

16h-17h

Inicio del segmento de cdigo en el archivo EXE

1 Word

18h-19h

Direccin de la Relocation-Table en el archivo EXE

1 Word

1Ah-1Bh Nmero de overlay

1 Word

1Ch-

Memoria de buffer

Variable

+??

Direcciones de las direcciones de segmento a adaptar

Variable

+??

Segmentos de cdigo de programa, datos y pila

Variable

Tabla 01-39 - Estructura de la Cabecera de un Archivo EXE


En un archivo EXE, el PSP se coloca al inicio, al igual que en un COM, y los registros de segmento DS y
ES apuntan al inicio de ste. La direccin de la pila y el contenido del puntero de la pila se guardan en la
cabecera del archivo EXE.
La funcin EXEC que carga los programas en memoria intenta reservar el nmero mximo de prrafos. Si
esto no es posible, se conforma con el resto de la memoria, que en ningn caso puede ser inferior al
nmero mnimo de prrafos necesitados adicionalmente, que viene en la estructura de cabecera del archivo
EXE. Por tanto, si queremos ejecutar otro programa, tenemos el mismo problema que con los archivos
COM, debiendo liberar la memoria reservada adicionalmente. Ms adelante ser cuando veamos cmo se
hace esto.
Veremos ahora cmo se puede crear un archivo de tipo EXE con MASM, NASM y FASM.
EsqExeM1

EsqExeM2

EsqExeM3

EsqExeN1

EsqExeF1

Cdigo

Cdigo

Cdigo

Cdigo

Cdigo

[bin]

[bin]

[bin]

[bin]

[bin]

Resultado en pantalla

Source 01-04 - EsqExe??.asm

EsqExeM1.asm
En las primeras lneas tenemos una explicacin somera de lo que trata el programa, del autor y de
la versin.
En la lnea 9 definimos el segmento de pila. Es necesario poner 'stack' para compilarlo con el
TASM. Definimos una pila de 30h palabras de longitud. Esto se hace con la instruccin "dw 30h
dup (?)". dw indica que estamos reservando espacio para palabras y 30h dup (?) indica que
repetimos 30h veces un valor indeterminado. La interrogacion indica indeterminado, dup indica
repetir y 30h el nmero de veces que se repite.
En la lnea 13 definimos el segmento de datos
En la lnea 17 definimos el segmento de cdigo.
En la lnea 18 hacemos corresponder a cada registro de segmento con su valor apropiado.
En la lnea 21 definimos el procedimiento principal del programa, seguidamente vendrn las
instrucciones de ste y luego la salida al DOS. Tanto despus como antes de este procedimiento
podemos definir otros procedimientos y macros.
En las lneas 29 y 30 terminamos con el segmento de cdigo y con el programa, respectivamente.
Para compilar este archivo utilizando MASM:

> ml EsqExeM1.asm

Para compilarlo utilizando TASM:


> tasm EsqExeM1
> tlink EsqExeM1

EsqExeM2.asm
Es la versin con directivas de segmento

EsqExeM3.asm
Mezclamos directivas de segmento con clsicas.
En esta ocasin hemos utilizado la directiva "Comment" para comentar varias lneas de cdigo. La
sintaxis es Comment y un carcter ASCII tras un espacio en blanco, es conveniente que este
carcter sea lo ms raro posible para que las lneas que queramos comentar no lo incluyan. Las
lneas comentadas terminan donde vuelve a aparecer este carcter; es un buen hbito de
programacin poner EndComment antes de l porque es ms visible e indica muy claramente cul
es el cometido del segundo carcter, si bien en s mismo no produce ningn efecto y adems est
comentado tambin. Lo dems est suficientemente claro.

EsqExeN1.asm
La nica diferencia existente aqu con los otros esqueletos vistos es que se indica dnde empiezan
los segmentos pero no donde terminan, pues esto ocurre donde empieza el siguiente segmento.
En la lnea 11 tenemos resb 256 que equivale al cdigo MASM "db 256 dup (?)".
Despus de definir el segmento de pila definimos una etiqueta "InicioPila:" que est situada en la
cima de la pila y nos sirve para indicar donde se va a situar el registro SP.
Finalmente, la directiva "..start:" le indica al compilador NASM que es aqu donde empieza el
programa y no hace falta indicarle dnde termina puesto que es al final del segmento de cdigo.
Para compilar el programa haremos lo siguiente:
>nasmw -fobj EsqExeN1.asm
>alink -oEXE EsqExeN1.obj

Alink es un linkador gratuito y necesitamos que est tambin dentro del PATH.

EsqExeF1.asm
Empezamos con FORMAT MZ, que indica al compilador que va a generar un .EXE.
Para ensamblar dicho cdigo usaremos uno de estos dos mtodos, el ms sencillo es el primero:
o Compilarlo directamente desde el editor que trae el paquete FASM.
o

>fasm EsqExeF1.asm EsqExeF1.exe

Vamos a desgranar la estructura de uno de estos esqueletos EXE, para lo cul vamos a utilizar el
compilador NASM, por ejemplo, y cambiaremos ligeramente nuestra definicin de la pila, para que luego
podamos ver ms claramente dnde est situada. Para ello hemos creado el archivo EjPilaN1.exe. Lo
compilamos como ya sabemos hacer y vemos la estructura hexadecimal del fichero [bin] resultante.

Fig. 01-14 - Visualizacin de la Pila de un fichero EXE en memoria


Observamos que los primeros bytes del archivo son "4d" y "5a" hexadecimales, que se corresponden con
las letras MZ, con lo que tenemos identificado el archivo como tipo EXE. En el tercer byte tenemos 91h
hexadecimal = 145 bytes de la longitud del programa EsqExN1b.exe, pues segn hemos dicho:
145 = 0*512 + 145

Tambin podemos ver claramente las etiquetas con las que definimos la pila y que ahora nos muestran sta
muy visualmente.
Veamos cmo queda en modo de ejecucin con la herramienta debug:
C:\Trabajo\AOE\Codigos\Cap01>debug EjPilaN1.exe
-d 100
0D18:0100 3C 2D 20 41 71 75 69 20-65 6D 70 69 65
0D18:0110 6C 61 20 70 69 6C 61 20-79 20 20 61 71
0D18:0120 74 65 72 6D 69 6E 61 20-00 00 00 00 00
0D18:0130 B8 28 0D 8E D0 BC 2A 00-B8 28 0D 8E D8
0D18:0140 21 C4 12 F3 A4 1F 03 E2-5F 5E 5A 59 5B
0D18:0150 12 2E 8E 16 40 05 8B E0-A1 04 15 C3 59
0D18:0160 14 8B D1 C1 E1 04 C1 EA-0C E8 61 1F 73
0D18:0170 14 C1 E9 04 8A C2 C0 E0-04 0A E8 C1 EA
-q

7A
75
00
B4
89
8B
20
04

61
69
00
4C
26
0E
A3
74

20
20
00
CD
C2
EE
D4
03

<- Aqui empieza


la pila y aqui
termina ........
.(....*..(....L.
!......._^ZY[.&.
....@.......Y...
..........a.s ..
..............t.

Vamos a utilizar aqu el editor hexadecimal gratuto "HexIT" que posee una opcin que nos va a ofrecer
una informacin muy valiosa respecto a la cabecera de nuestro archivo "EXE":

Fig. 01-15 - Cabecera de Archivo EXE


Como vemos en el recuadro de fondo azul, tras pulsar la tecla "F6", nos da informacin de todo el
contenido de la cabecera del programa EXE.
Vamos a ver la estructura del PSP que le ha correspondido a este programa. Para ello utilizamos la utilidad
CodeView de microsoft:
>cv EjPilaN1.exe

Fig. 01-16 - PSP de un archivo EXE


Los primeros 100h bytes son los correspondientes al PSP. Estamos en el segmento 0BAAh, que
corresponde con el valor del registro ES y DS, que ya hemos dicho que contienen al inicio de un programa
EXE la direccin de su PSP.

En "Run-> Set Runtime Arguments..." del CodeView podemos establecer cul va a ser el agumento de
lnea de comandos para nuestro programa, yo he elegido "miArgumento"; no es original, pero es muy
visible.
Los dos primeros bytes contienen una llamada a la interrupcin 20h: "CD 20", que produce un retorno al
DOS.
En el byte 80h nos indica el nmero de bytes que hemos ingresado por lnea de comandos sin contar el
retorno de carro: "0C", es decir, 12 en decimal.

1.6. Diferencias entre las sintaxis


1.6.1. Diferencias entre NASM y MASM
Veamos algunas diferencias:

NASM es sensible a las letras en maysculas y minsculas, mientras que MASM slo lo es usando
la opcin /Cp. Esto quiere decir que las variables miVar y MiVAR no son la misma en NASM,
pero s en MASM sin la opcin correspondiente.

Seccin sin inicializar. Nasm permite generar una seccin de variables sin inicializar con la
etiqueta .bss, eso significa que reserva ese espacio de memoria, pero no lo ocupa, con lo que el
[bin] resultante es de tamao inferior. Las variables sin inicializar en MASM s ocupan espacio.
Mientras MASM usa "stack db 64 dup (?)", NASM usa "stack resb 64", como intentando que se
lea "reserva 64 bytes de memoria".

NASM no usa etiquetas especiales para definir procedimientos, sino que quedan identificados por
una etiqueta a la que se salta.

Las etiquetas definidas por NASM dentro de un procedimiento nunca son locales a no ser que se
indique explcitamente anteponindoles un punto, mientras que MASM siempre las define como
locales dentro de un procedimiento a no ser que indiquemos explcitamente que no lo son. Al no
ser locales en cada procedimiento implica que no podremos usar etiquetas con el mismo nombre en
diferentes procedimientos

NASM no "ASSUME", por simplicidad, nunca guarda los valores de los registros de segmento y
nunca generar un prefijo dominante de segmento.

NASM no soporta Modelos de Memoria. Tampoco tiene directivas para respaldar los diferentes
modelos de memoria. El programador debe encargarse de invocar a una funcin con una llamada
cercana o una lejana y tambin volver de ella con un RETN (cercano) o un RETF (lejano),
admitiendo RET como RETN.

Diferencias con la coma flotante. NASM usa diferentes nombres de registro del coprocesador que
el que usa MASM. NASM usa st0, st1,... frente a st(0), st(1),... del MASM.

NASM requite corchetes para todas las referencias de memoria. Por ejemplo el siguiente cdigo:

uno
dos

equ 1
dw 2

mov ax, uno


mov ax, dos
mov ax, OFFSET dos
MASM
MOV AX, [dos]

;
;
;
;

AX
AX
AX
AX

=
=
=
=

1 tanto en NASM como en MASM


2 en MASM
la direccin de la variable "dos" en NASM
la direccin de la variable "dos" slo admitido en

; AX = 2 tanto en NASM como en MASM

En consecuencia, la funcin OFFSET no existe en NASM, slo en MASM, devuelve la posicin


de memoria de una etiqueta. Es decir, si "dos" es una etiqueta, las siguientes dos lneas son
equivalentes en MASM y NASM:

mov ax, dos


mov ax, OFFSET dos

El parmetro PTR slo existe en MASM, por ejemplo, las siguientes sentencias son equivalentes
en MASM y NASM:

dos
MOV
MOV

Los segmentos de memoria deben estar dentro del corchete, por ejemplo:

MOV
MOV

Nasm tiene su propio lenguaje de macros

; AX = la direccin de la variable "dos" en NASM


; AX = la direccin de la variable "dos" en MASM

dw 2
AX, WORD PTR [dos]
AX, WORD [dos]

AX, ES:[BX]
AX, [ES:BX]

; AX = 2 en MASM
; AX = 2 en NASM

; Correcto en MASM
; Correcto en NASM

1.6.1. Diferencias entre NASM y FASM


Estos dos compiladores son, bsicamente, muy parecidos, por lo que la mayora de las diferencias entre
NASM y MASM tambin aplican a FASM.
Veamos algunas diferencias entre FASM y NASM

Nasm reserva espacio con la directiva RESB, Fasm lo hace con RB o tambin con ?, por ejemplo:
Var1
Var2

DB ?
RB 1

En el coprocesador matemtico, NASM define el primer registro con ST0, mientras que FASM lo
hace con ST

Fasm no define espacios especiales con etiquetas como ".bss". En el caso de variables sin
inicializar lo hace como ya hemos indicado anteriormente.

Fasm tiene su propio lenguaje de macros

Potrebbero piacerti anche