Configurando el Entorno

Los programas que se muestran en este libro asi como los ejemplos en el directorio examples, se elaboran en el emulador DOSBox.

Requisitos

Guías por Sistema Operativo

Instalación en macOS

  1. Descarga el instalador de la página oficial de DOSBox
  2. Abre el DMG descargado y copia el archivo DOSBox a tu directorio "Aplicaciones".
  1. Crea un directorio DOSDrive, que servira como disco a montar en DOSBox. Este directorio nos permitirá agregar ejecutables obtenidos de internet para utilizar dentro de DOSBox.

Si usas la terminal, puedes ejecutar el siguiente comando para crear el directorio:

mkdir ~/DOSDrive

Si usas "Finder", abre la carpeta "Inicio" usando el menu contextual en la parte superior "Ir" > "Inicio". Y crea un directorio con el nombre DOSDrive.

  1. Copia el ejecutable TASM al directorio DOSDrive en tu directorio de Inicio, así como cualquier otro binario ejecutable de tu interés.

  2. Ejecuta DOSBox y monta el directorio ~/DOSDrive creado en el paso 3 usando el siguiente programa.

MOUNT C ~/DOSDrive

El comando MOUNT toma como primer parámetro el nombre del disco a montar, en este caso es C. Y como segundo parámetro la dirección del directorio a montar.

La ejecución de este comando habilitará un archivo de configuración dentro del directorio ~/Library/Preferences.

  1. Modifica el archivo de preferencias de DOSBox para que el comando MOUNT se ejecute automáticamente al abrir DOSBox.

Abre el directorio ~/Library/Preferences usando el terminal o Finder y abre el archivo: DOSBox 0.74 Preferences con tu editor de texto favorito, si no tienes uno puedes usar TextEdit en su lugar.

El nombre del archivo puede variar según la versión de DOSBox instalada.

Al final del archivo se encuentra la seccion AUTOEXEC, esta sección nos permite agregar comandos a ejecutar al abrir el emulador.

[autoexec]
# Lines in this section will be run at startup.
# You can put your MOUNT lines here.

Agrega el comando MOUNT utilizado en el paso 5 a esta sección para que se ejecute al abrir DOSBox.

[autoexec]
# Lines in this section will be run at startup.
# You can put your MOUNT lines here.

# Montar el disco C apuntando a ~/DOSDrive
@ECHO OFF
MOUNT C ~/DOSDrive

# Usar Disco C
C:

Instalación en Linux

TBD

Instalación en Windows

TBD

Registros

Registros Divididos en 2 Partes (High/Low)

Cada registro en la Intel 8086 tiene una capacidad de 16 bits. De los cuales 4 registros: AX, BX, CX y DX, estan internamente divididos a la mitad.

NombreEstructuraDescripción
AXAH - ALRegistro Acumulador
BXBH - BLRegistro Base
CXCH - CLRegistro Contador
DXDH - DLRegistro de Datos

Registros para Índices

NombreDescripción
SISource Index / Índice Fuente
DIDestination Index / Índice Destino

Registros para Punteros

NombreDescripción
BPBase Pointer / Puntero Base
SPStack Pointer / Puntero Stack

Registros de Segmento

Los registro de segmento se usan para consumir bloques de memoria.

NombreDescripción
CS"Code Segment", Apunta al segmento que contiene el programa actual
DS"Data Segment", Apunta al segmento donde las variables se encuentran definidas
ES"Extra Segment", habilitado para el uso del programador
SS"Stack Segment", Apunta al segmento contenido en el Stack

Registros Bandera

Los registros bandera son modificados por el CPU y nos ayudan a determinar la naturaleza del resultado de una operación aritmética llevada a cabo en la ALU.

Auxiliary Carry Flag ● AF

TBD

Carry Flag ● CF

Determina la presencia de Carry (Llevar) en el HO (High Order) bit.

ValorDescripcion
0/NCNo hay carry
1/CYHay carry

Direction Flag ● DF

TBD

Interrupt Flag ● IF

Determina el comportamiento del procesador con respecto a las interrupciones del hardware

ValorDescripcion
0Ignora instrucciones que interrumpen el Hardware
1Procesa instrucciones que interrumpen el Hardware

Overflow Flag ● OF

Índica la presencia de desboardamiento en el resultado de una operación aritmética.

Ocurre si el resultado de una operación no puede ser representado en una cantidad determinada de bits.

ValorDescripcion
0No hay desbordamiento
1Hay desbordamiento

Sign Flag ● SF

Determina el signo de un resultado aritmético

ValorDescripcion
0/PLSigno Positivo
1/NGSigno Negativo

Trap Flag ● TF

TBD

Zero Flag ● ZF

TBD

Comandos Globales

Listar Entradas en el Directorio

DIR

DEBUG.EXE

La interfaz de línea de comandos (CLI), debug se utiliza para inspeccionar la memoria y los registros del sistema.

Índice de Comandos

Para inicializarla se debe ejecutar la aplicación debug, la aplicación funciona mediante comandos, se puede utilizar el comando help escribiendo ? seguido de Enter.

Para cada comando se debe de ingresar la opción seguida de Enter.

Para cerrar la aplicación se ingresa la opción q seguida de Enter

Cambiar Dirección

-a [address]

El comando a se utiliza para cambiar la dirección a la que se quiere apuntar el debug.

Se debe escribir a seguido de la dirección en memoria al que se quiere inspeccionar.

-a 100

Escribiendo Assembler (Ensamblar)

Se pueden escribir instrucciones en assembler cuando se ejecuta el comando address (a).

-a 100
073F:0100 mov dx, 0000              ;; asigna 0 al registro DX
073F:0103 mov ah, 09                ;; establece justo a la siguiente instrucción 
073F:0105 int 21                    ;; que se escribira un mensaje en la pantalla
073F:0107 mov ax, 4c00              ;; finaliza el programa con codigo 0
073F:010A int 21                    ;; escribe un string a la salida standard (stdout)
073F:010C                           ;; finaliza sin ingresar mas instrucciones y presionando enter
-e 010C "Hello World!" 0d 0a "$"    ;; ingresa el string "Hello World!" en el espacio de memoria 010C
-a 100
073F:0100 mov dx, 10c0              ;; mueve el dato en `010C` a el registro `dx`
073F:0103
-d 100                              ;; dump, muestra los contenidos en memoria para la dirección 100

0d y 0a son equivalentes a carriage return y line feed en assembly

"$" determina que el string ha finalizado

El Segmento y el Desplazamiento

Cada intrucción que escribimos al hacer -a se escribe en un segmento otorgado por el sistema operativo.

-a 100
073F:0100 mov dx, 0000

El segmento (segment), en este caso es 073F. El mismo se verá en el registro CS.

El Desplazamiento u offset, muestra el byte en memoria dentro del segmento en el que se encuentra cada instrucción.

La forma en como se muestra ordenado es: SEGMENT:OFFSET.

Desensamblar (-u <OFFSET> <LIMIT>)

El comando u nos permite desensamblar el código en binario, pasandolo a assembler.

Modificar Instrucciónes en Memoria

Usando los comandos -u y -a, podemos modificar las intrucciónes que escribimos anteriormente en memoria.

Podemos usar el comando -u pasando el rango del offset en el que se encuentra nuestro programa.

-u 100 10c

Para ver las instrucciónes en este rango de memoria, luego usar el comando -a pasando el offset que deseamos modificar.

-a 102

Colocamos el nuevo valor:

ADD AH, 08

Y finalmente volvemos a usar -u para confirmar que la instrucción se ha actualizado satisfactoriamente.

Calcular Suma y Resta de 2 números hexadecimales

El comando h recibe como argumentos 2 números hexadecimales y calcula la suma y la resta entre ambos numeros. Posteriormente los devuevele el el orden, suma a la izquierda y resta a la derecha.

-h 123 100
0223 0023

Registros (-r / -r AX)

El comando r, muestra el estado de los registros. Se puede utilizar de 2 formas.

  1. Mostrar todos los registros -r
  2. Mostrar 1 registo especifico -r AX

Podemos usar r para cambiar el valor de un registro. Colocamos r seguido del nombre del registro a cambiar el valor, sea ax, entonces rax.

Presionamos Enter y a continuación colocamos el valor.

-rax
AX 0000
: 100

Al ejecutar r de vuelta, veremos el valor del registro AX cómo 100

-r
AX=0100 BX=0000 CX=0000 DX=0000 SP=0OFD BP=0000 SI=0000 DI=0000
D5=073F ES=073F
55=073F
C$=073F
IP=0100
NU UP FI PL NZ MA PO NC
073F: 0100 B410
MOL
AH. 10

Este comando resulta de utilidad para cambiar el Program Counter ó registro IP, para colocarlo al inicio de nuestro programa.

Trace (t)

Ejecuta la siguiente instrucción en el Program Counter (registro IP) y muestra el estado de los registros, similar a el comando r.

EDIT.EXE

El programa EDIT.EXE es un editor de texto, útil para el desarrollo de programas en Assembly dentro de DOSBox.

Creando un programa usando el editor EDIT.EXE

Para editar un archivo o crear uno nuevo se debe ejecutar EDIT.EXE, pasando el nombre del archivo como parámetro.

edit <filename>.asm

Desarrolla el código en assembler:

Guarda el archivo, usa el cursor para abrir el menú de archivo en la parte superior y luego presiona click en la opción Save As, finalmente presiona Ok.

Luego vuelve a abrir el menú File y selecciona Exit.

Compilando el Programa

Ahora debemos compilar el archivo Assembler, para ello usamos el ejecutable tasm de la siguiente forma:

tasm /l /zi <filename>.asm

Este comando compilara y creara 2 archivos a partir del código fuente en Assembly, HELLO_WORLD.LST Y HELLO_WORLD.OBJ.

Con el archivo OBJ presente, podemos hacer el linking y la compilación para obtener el archivo EXE que nos premite ejecutar el programa.

tlink /v <filename>.obj

Ejecutando el programa como binario .exe

Finalmente ejecutamos el programa.

Assembly en DOSBox

Hello World

.model small
.stack 100h

.data
  message db "Hello World!", 13, 10, "$"
.code

start:
  mov ax, @data
  mov ds, ax
  mov ah, 9
  mov dx, offset message
  int 21h
  mov ah, 4ch
  int 21h
  end
end start

Recursos

Directivas (Directives)

Las directivas permiten definir el comportamiento del programa con respecto a los segmentos de memoria usados, el tamaño del stack, valores estáticos y la sección de instrucciones a ejecutar.

.model

La directiva .model define el comportamiento de ciertos registros para tu programa.

.model tiny

Define que los registros CS, DS y SS apuntaran al mismo segmento de memoria de 64KB. El stack es colocado en la región mas alta de dicho segmento.

.model small

Define que el registro CS de tu programa apuntara a su propio segmento, seguido del segmento donde DS y SS estan apuntando. El stack se posicionará en la región mas alta del segmento SS.

.stack

TBD

Instrucciónes

Las instrucciones en Assembly son los building blocks para los programas que escribimos.

MOV <REG>, <VAL>

Asigna el valor <VAL> al registro <REG>

MOV AH, 10     ;; Coloca el valor 10 en el registro AH
MOV AL, -5     ;; Coloca el valor -5 en el registro AL
MOV AX, 4C00   ;; Coloca el valor 4C00 en el registro AX
MOV AH, 'A'    ;; Coloca el valor ASCII 'A' en el registro AH

No se puede usar esta instrucción para modificar el valor de los registros CS ó IP.

Tipos de Valor

Podemos usar valores binarios, hexadecimales, decimales y ASCII al asignar valores usando MOV.

Binario

MOV AH, 1100_0011b

Hexadecimal

MOV AX, CAFEh

Decimal

MOV AH, -5

ASCII (American Standard Code for Information Interchange)

MOV AH, 'A'

Tabla de Códigos ASCII

ADD <REG>, <VAL>

Suma el valor en <VAL> a el contenido en <REG>. Si vamos a sumar por primera vez, es recomendable asegurarse el valor en <REG> colocando 0 antes.

MOV AH, 0
ADD AH, 10

SUB <REG>, <VAL>

Resta o substrae, el valor <VAL> a el contenido en el registro <REG>.

SUB AH, 10
SUB AL, -5