SlideShare a Scribd company logo
1 of 79
Centro Escolar “Felipe Carrillo Puerto”

                                     Licenciatura en Ciencias Computacionales


MATERIA:                      LENGUAJE ENSAMBLADOR
NIVEL:                        SEXTO SEMESTRE
PROFESOR:                     L. C. C. MIGUEL ANGEL SUASTE ESCALANTE
SEMESTRE:                     FEBRERO-JULIO DEL 2008
HORARIO:                      Martes y Jueves de 8:00-9:30

Objetivo General: Al finalizar el curso el alumno podrá aplicar los conceptos y características sobre
la arquitectura de una computadora para elaborar y depurar programas escritos en lenguaje
ensamblador.

Criterios de Evaluación:
        1er. Bimestre                                2º. Bimestre                              Ordinario
Criterio de Evaluación         Puntos      Criterio de Evaluación       Puntos    Criterio de Evaluación           Puntos
Examen escrito                  15        Examen escrito                 15      Examen escrito                     15
Participación                    5        Participación                   5      Participación                      NA
Trabajos y/o proyectos           5        Trabajos y/o proyectos          5      Trabajos y/o proyectos             15
Tareas o ensayos                10        Tareas o ensayos               10      Tareas o ensayos                   NA
Exposiciones de trabajo         NA        Exposiciones de trabajo        NA      Exposiciones de trabajo            NA
Otros                           NA        Otros                          NA      Otros                              NA
                      Total     35                              Total    35                                Total    30
Fechas de Evaluaciones
Primer Parcial:
Segundo Parcial:

                                                   CONTENIDO
1. FUNDAMENTOS DE LA PROGRAMACIÓN EN ENSAMBLADOR
       El alumno comprenderá y aplicará los conceptos relacionados con la estructura de las
computadoras y el Lenguaje Ensamblador.
   1.1. La familia de computadoras IBM
   1.2. Macroensamblador
   1.3. Ventajas que se obtienen al aprender un Lenguaje Ensamblador
   1.4. Sistemas Numéricos
       1.4.1.Numeración binaria
       1.4.2.Bits, nibbles, Bytes y Words
       1.4.3.Representación de enteros
           1.4.3.1.Magnitud con signo
           1.4.3.2.Complemento a uno
           1.4.3.3.Complemento a dos
           1.4.3.4.Exceso 2n-1
       1.4.4.Representación de punto flotante
           1.4.4.1.Representación de números de punto flotante en la PDP-11 e IBM
           1.4.4.2.Bit Escondido
   1.5. El Debug
Centro Escolar “Felipe Carrillo Puerto”

                          Licenciatura en Ciencias Computacionales


2. INTRODUCCIÓN A LA PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR
        El alumno conocerá cómo representa la computadora de manera interna los datos e
instrucciones que procesa mediante el debug.
    2.1. El Debug y su uso
    2.2. Aritmética del 8088/80286/80386 mediante el DEBUG
        2.2.1.Registros como variables
        2.2.2.Memoria del Procesador
        2.2.3.Estilos de adición y resta
        2.2.4.Números negativos
        2.2.5.Multiplicación y división
    2.3. Imprimiendo caracteres
        2.3.1.INT 21h: El poder de las interrupciones
        2.3.2.INT 20h: una salida con gracia
        2.3.3.Programas enteros
        2.3.4.Moviendo datos entre registros
        2.3.5.Escribiendo strings de caracteres
    2.4. Registro de Banderas
    2.5. Imprimiendo números binarios
        2.5.1.Banderas de acarreo y rotación
        2.5.2.Adición con la bandera de acarreo
        2.5.3.Looping
        2.5.4.Escribiendo números binarios
    2.6. Imprimiendo en hexadecimal
        2.6.1.Comparando y status de bits
        2.6.2.Imprimiendo un dígito en hexadecimal
    2.7. Leyendo caracteres
        2.7.1.Leyendo un caracter
        2.7.2.Leyendo un número hexadecimal
        2.7.3.Leyendo dos dígitos hexadecimales
    2.8. Procedimientos y pilas
        2.8.1.La pila y direcciones de retorno
        2.8.2.Leyendo números en hexadecimal
        2.8.3.Etiquetas

3. PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR
        El alumno programará en Lenguaje Ensamblador para trabajar a bajo nivel en la computadora
y desarrollará diversas aplicaciones.
    3.1. Proceso de Ensamble
    3.2. Rutinas utilizadas en el Ensamblador
    3.3. Tipos de Instrucciones en Lenguaje Ensamblador
    3.4. Instrucciones en Macroensamblador
    3.5. Estructura de un programa
    3.6. Parámetros de Pseudo-Op Segment
    3.7. Programando con el MASM
    3.8. Modos de Direccionamiento
    3.9. Los Procedimientos y el Ensamblador
Centro Escolar “Felipe Carrillo Puerto”

                       Licenciatura en Ciencias Computacionales


3.10.Imprimiendo en Decimal
3.11.Segmentos y Desplazamientos
3.12.Mapa de la memoria RAM
3.13.Segmentos
   3.13.1.Seccionando la memoria del Microprocesador
   3.13.2.La Pila
   3.13.3.El priefijo del Segmento de Programa (PSP o Scratch área)
   3.13.4.La directiva DOSSEG
   3.13.5.Llamadas (NEAR y FAR)
   3.13.6.Vector de Interrupciones
3.14.Vaciando la memoria
   3.14.1.Instrucción group
   3.14.2.Rutinas varias
Centro Escolar “Felipe Carrillo Puerto”

                          Licenciatura en Ciencias Computacionales



   3.15.Diseño de software
   3.16.Instrucciones de control
      3.16.1.Instrucciones de salto
      3.16.2.Instrucciones de comparación
   3.17.Optimización del diseño
      3.17.1.Programación modular
      3.17.2.Diseño descendente
   3.18.Diagramas de flujo y pseudocódigo
   3.19.Enfoque a la programación estructurada
   3.20.Estilo y forma
   3.21.Instrucciones de uso más frecuentes
      3.21.1.Instrucciones aritméticas
      3.21.2.Instrucciones de transferencia
      3.21.3.Instrucciones de carga
      3.21.4.Instrucciones Loop
      3.21.5.Instrucciones de Stack
      3.21.6.Instrucciones de conteo
      3.21.7.Otras instrucciones
      3.21.8.Instrucciones de corrimiento
      3.21.9.Instrucciones de rotación
      3.21.10.Instrucciones de almacenamiento
      3.21.11.Instrucciones de manejo de cadenas
      3.21.12.Instrucciones de conversión
      3.21.13.Instrucciones de procedimiento y control
      3.21.14.instrucciones ASCII
      3.21.15.instrucciones de aritmética decimal
      3.21.16.Instrucciones de I/O
      3.21.17.Instrucciones diversas
   3.22.Ejemplos y ejercicios de programación.

Bibliografía

   1. Lenguaje ensamblador para Microcomputadores IBM para principiantes y
      avanzados; J. Terry Godfrey; Prentice Hall; 1991
   2. System Programming; J. J. Donovan; Mc Graw-Hill
   3. Fundamental Concepto of Programming Systems; Jefrey D. Ullman; Addisson-
      Wesley
FUNDAMENTOS DE LA PROGRAMACIÓN EN ENSAMBLADOR
      El alumno comprenderá y aplicará los conceptos relacionados con la estructura de las
computadoras y el Lenguaje Ensamblador.

Introducción
¿Qué es el Lenguaje Ensamblador?
       Es un lenguaje de bajo nivel que traduce instrucciones en lenguaje máquina1. Este utiliza
nemotécnicos (abreviaturas) que representan operaciones, nombres simbólicos, operadores y símbolos
especiales.

Entonces, ¿Por que estudiar el Lenguaje Ensamblador si existen Lenguajes de Alto Nivel?
      La importancia del Lenguaje ensamblador es que trabaja directamente con el microprocesador.

       Los programadores que emplean lenguajes de alto nivel para desarrollar aplicaciones donde el
tiempo no es un factor crítico o que hacen uso de dispositivos estándar de entrada/salida (I/O), rara vez
necesitan llamar rutinas que no formen parte de la librería del compilador. En otras palabras, las
necesidades de programar en lenguaje ensamblador en este tipo de aplicaciones, son mínimas.

        Sin embargo, alguien debe escribir las rutinas de librería que estos programadores emplean, con
el fin de obtener la interfaz estándar. Estas rutinas forman la parte no transportable del lenguaje que
utilizan y están escritas en lenguaje ensamblador.

La familia de computadoras IBM
       En el presente curso se estudiará la programación en ensamblador basado en el ambiente del
sistema de la computadora personal IBM debido a que:
       1. Está bien definida la descripción de las interfaces del Hw. en el BIOS, tales como
           interrupciones, rutinas de servicio, diagramas.
       2. Arquitectura del sistema claramente delineada.
       3. La presentación en pantalla es buena para el desarrollo de programas.
       4. Amplio soporte de Sw.
       5. El desarrollo de código es una tarea que se facilita, debido a:
               a. Énfasis en el teclado y su sintaxis I/O
               b. Líneas de 80 caracteres
               c. I/O orientado a textos
               d. Editores bien desarrollados
               e. Depuradores bien desarrollados
               f. Enlazadores y ensambladores bien desarrollados
               g. BIOS bien documentado.
       6. Finalmente, el ambiente de IBM ofrece compatibilidad con otros modelos; por tanto, la
           experiencia y habilidad ganadas por el usuario aumentarán continuamente.

       IBM desarrolló un conjunto de microcomputadoras basados en los microprocesadores 8088,
8086, 80286 y 80386 fabricados por INTEL, los tres primeros de 16 bits (es decir, tiene registros
internos de 16 bits) y el último de 32 bits.



1
  El Lenguaje de Máquina son aquellas instrucciones que son directamente entendidas por lo computadora y no necesitan
traducción posterior para que la CPU pueda comprender y ejecutar el programa. Dichas instrucciones se expresan con bits.

                                                                                                                      1
Los microprocesadores 8088 y 8086 se programan con un conjunto básico de instrucciones que
son la base de la versión 1.0 de macroensamblador (que emplea un modelo de memoria pequeña). El
80286 se programa en uno de dos modos posibles: el modo de direcciones reales o el modo de
direcciones virtuales (o modo protegido). Todo el código desarrollado para el 8088 y 8086 se ejecuta
en el primero modo. De manera similar todo el código, salvo para unas instrucciones específicas
desarrollado para el 80286 en el modo de direcciones reales será ejecutado sin ningún problema, tanto
en el 8088 como en el 8086, La versión 2.0 del macroensamblador incluye también instrucciones
específicas del 80286, 8087 y 80287.

        En modo protegido el 80286 es muy diferente del 8088 y 80286. En este modo existen
instrucciones orientadas a soportes de sistemas que no están disponibles en las versiones 1.0 y 2.0 del
macroensamblador. Además, estas instrucciones no están diseñadas para que el programador de
aplicaciones haga uso de ellas ya que proporcionan funciones para el manejo de memoria y multitarea.
El 80386 tiene muchas instrucciones que son iguales al 80286 tanto en direcciones reales como en
modo protegido. Además, el 80386 tiene un modo virtual para el 8086 que permite ejecutar los
programas desarrollados para este microprocesador en el ambiente multitarea.

                              Registros del INTEL 8088/8086 y el 80286
 Registros                                         Descripción
AX (AH, AL)    Registro del acumulador
BX (BH, BL)    Registro de base
CX (CH, CL)    Registro para conteo
DX (DH, DL)    Registro de datos
    SP         Registro apuntador de pila
    BP         Registro apuntador de base
    SI         Registro de índice de fuente
    DI         Registro de índice de destino
    CS         Registro de segmento de código
    DS         Registro de segmento de datos
    SS         Registro de segmento de pila
    ES         Registro de segmento extra
    IP         Apuntador de instrucciones
  FLAGS        Registro de estado de banderas

       El INTEL 80386/80486 tienen 14 registros de propósito general, un apuntador de instrucciones
EIP y un registros de banderas EFLAGS.




                                                                                                     2
Registros del INTEL 80386/80486
  Registros                                            Descripción
EAX (AH, AL)     Registro del acumulador (32 bits)
EBX (BH, BL)     Registro de base (32 bits)
ECX (CH, CL)     Registro para conteo (32 bits)
EDX (DH, DL)     Registro de datos (32 bits)
    ESP          Registro apuntador de pila (32 bits)
    EBP          Registro apuntador de base (32 bits)
    ESI          Registro de índice de fuente (32 bits)
    EDI          Registro de índice de destino (32 bits)
    ECS          Registro de segmento de código (16 bits)
    EDS          Registro de segmento de datos (16 bits)
    ESS          Registro de segmento de pila (16 bits)
    EES          Registro de segmento extra (16 bits)
    EIP          Apuntador de instrucciones (16 bits)
  EFLAGS         Registro de estado de banderas (16 bits)


                           |31             16|15   8|7          |0
                                                AH     AL            EAX
                                                     AX
Macroensamblador
       El macroensamblador es un programa de computadora que traduce programas escritos en
ensamblador en instrucciones en lenguaje máquina. Es un programa muy específico que guarda
estrecha relación con la arquitectura del Hw específico de cada computadora. En la CPU’s de las
computadoras personales se conectan circuitos electrónicos de memoria de propósito general para
formar registros. Los registros son dispositivos (circuitos) de memoria muy sencillos ubicados dentro
del microprocesador. El trabajo del macroensamblador es traducir las instrucciones en series de 1 y 0’s
que causan que el contenido de los registros sean manejados de manera correcta.

       Ejemplos de Ensamblador:
      MACRO (PDP-11)
      COMPASS (CYBER)
      ZILOGZ-80 (RADIO SHACK)
      MACROENSAMBLADOR (INTEL)
      IBM MACRO ASSEMBLER
      MICROSOFT MACROASSEMBLER, TURBO, EDITASAM ASSEMBLER

Ejemplo de instrucciones en Ensamblador:
a) SUB AX, BX               ;Se resta a AX el Valor de BX
b) MOV AX, BAM[4]

Las ligas a continuación, muestra la forma en que se programaba en ensamblador usando una PDP-11:
   • Parte 1 (http://www.youtube.com/watch?v=XV-7J5y1TQc&feature=related)
   • Parte 2 (http://www.youtube.com/watch?v=7zaaD_xP6nU&feature=related)
   • Parte 3 (http://www.youtube.com/watch?v=xiE2QldpQRQ&feature=related)
   • Parte 4 (http://www.youtube.com/watch?v=NUSn59iY8U8&feature=related)


                                                                                                     3
En el macroensamblador de IBM las instrucciones no ejecutables que se emplean para
estructurar el código fuente toma la forma de pseudoperaciones, el ensamblador permite que un
programa que se ejecute en una CPU 8086, 8088 u 80286 haga uso de 4 tipos de segmentos: el de
código, de datos, de pila y uno mas de datos o segmento extra de código.

       El 80386 y el 80486 tiene dos segmentos adicionales de datos que fueron añadidos para la
congestión de registro ES y para mejorar la coincidencia de los registros índice y base disponibles en el
conjunto general de registros, estos segmentos son FS y GS.

     Los programas con extensión .EXE pueden ser colocados en cualquier parte de la memoria
RAM o el sistema operativo. El programa LINK únicamente añade cabeceras al programa.

                                    Ventajas del programa .EXE
   a) El archivo es reubicable. Mas de un programa puede ser cargado a memoria.
   b) Los archivos .EXE permiten el uso de hasta 4 segmentos. Esto permite una buena modularidad
      y la creación de grandes programas.

                                  Ventajas del programa en .COM
   a) Ocupa menos memoria que el .EXE. Contiene solamente un segmento, este segmento incluye
      toda la información necesaria que requiere el programa.

                                 Desventaja del programa en .COM
       No es reubicable y siempre debe comenzar en la dirección 0100H

       El MASM es un ensamblador de dos pasadas:
       1ª pasada: Se realiza la traducción de tablas de símbolos, códigos, literales, etc.
       2ª pasada se crea el código objeto, listado de errores, etc.

Ejemplo:
Etiqeta1:     MOV AX, 01
              CMP AX, BX
              JNZ Etiqueta2
              SUB BX, 10
              JMP Etiqueta1
Etiqueta2:    ADD BX, AX
              HLT
              END

                                            Tabla de símbolos
     Nombre                 Valor               Longitud             Reubicable              Acceso Ext.
Etiqueta1                     0                    10                    --                      1
Etiqueta2                    10                     6                    --                      0




                                                                                                           4
Tabla de códigos
       OP Code                             Cod. Hex                 Long Int                      Tipo de inst
         MOV                                 7B                         2                            R/M
          CMP                                3D                         4                            R/R
            ...                               ...                      ...                             ...
R = registro y M = memoria

                                                     Tabla de literales
                                                  Valor            Localidad
                                                   01                500H
                                                   10                502H

Ventajas que se obtienen al aprender un Lenguaje Ensamblador
      1. Habilidad para controlar el Hw.
      2. Habilidad para desarrollar fragmentos de programas que sean de rápida ejecución.
      3. Habilidad para accesar, de manera óptima y eficiente, el coprocesador2.
      4. Comprensión de los métodos utilizados para realizar la sintaxis asociada con lenguajes de
          alto nivel.
      5. Conocimiento profundo de los sistemas basados en microcomputadoras y de interfaz de Hw/
          Sw.
      6. Disciplina para programar de manera estructurada.
      7. Comprensión de la forma en que se manejan, a bajo nivel, diversas estructuras de datos.

Sistemas Numéricos
Numeración binaria
       Un bit representa un dígito que tiene uno de dos valores posibles: uno o cero. El dígito
representa uno de dos estados y se define como aritmética binaria o de base-2.

      N-bits pueden representarse de la siguiente manera, siendo el bit más significativo el que se
encuentra mas a la izquierda.


                                2n-1     2n-2        ......       23       22       21       20

       En la memoria de la computadora, los números positivos se representan como enteros sin signo.
En general, con palabras de 16 bits se puede representar cualquier entero positivo en el intervalo de
0-65,535 (216 - 1). Si el bit 16 se emplea para indicar el signo del número, entonces el mayor entero que
puede representarse con los 15 bits restantes está en el intervalo de (-32,767, +32,767).

        Las computadoras generalmente utilizan aritmética de complemento a 2. En esta, los números
positivos se representan de manera normal, y los negativos con su complemento ya que esto permite
que las restas se conviertan en suma.




2
    El coprocesador es el que lleva a cabo operaciones de punto flotante a muy alta velocidad.

                                                                                                                 5
Bits, nibbles, Bytes, Words
Bit = 1 ó 0
Nibble = 4 bits
Byte = 2 Nibbles = 8 bits
Word = 2 Bytes = 4 Nibbles = 16 bits

Representación de enteros
Magnitud con signo
       En éste método de numeración binaria los valores positivos empiezan con cero y los negativos
con uno. El bit más significativo representa el signo.
Ejemplo: Escribir con 3 bits los valores posibles
       0|00 = 0
       0|01 = 1
       0|10 = 2
       0|11 = 3
       1|00 = -0
       1|01 = -1
       1|10 = -2
       1|11 = -3

Complemento a uno
        Los positivos comienzan con cero (magnitud con signo) y para escribir los negativos se escribe
el valor positivo y se complementa lógicamente (es decir, los 0 se convierten en 1 y viceversa)
Ejemplo: Escribir con 3 bits todos los valores positivos y negativos posibles
        0|00 = 0
        0|01 = 1
        0|10 = 2
        0|11 = 3
        1|00 = -3
        1|01 = -2
        1|10 = -1
        1|11 = -0

Complemento a dos
       Los positivos se escriben igual que en complemento a uno y magnitud con signo. Los negativos
provienen de sumarle 1 al valor del complemento a uno.
Ejemplo: Escribir ±131 en complemento a dos con 9 bits
131 = 0|10000011 => además es m.c.s., complemento a uno y complemento a dos
       1|01111100 => -131 en complemento a uno
              + 1
_______________
       1|01111101 => -131 en complemento a dos

Exceso 2n-1
        Para escribir cualquier cantidad positiva o negativa bastará con sumarle 2 n-1, donde n=número
de bits empleados.
Ejemplo: Escribir ±36 en exceso 2n-1 con 7 bits.
        36 + 27-1= 36 + 26 = 36 + 64 = 100 => 1100100
        -36 + 27-1= -36 + 26 = -36 + 64 = 28 => 0011100

                                                                                                    6
Representación de punto flotante
         Los números de punto flotante se representan en la forma a·be donde:
         a=es la mantiza normalizada
         b=es la base del sistema de numeración
         e=es el exponente de la base

Ejemplo:
      Representar 1943 en punto flotante en base decimal
      .1943 x 104 donde a=.1943, b=10 y e=4

      se dice que un número es de punto flotante normalizado cuando se cumple:
       1
         ≤ x < 1 donde b=es la base del sistema de numeración, x=es el número en punto flotante
       b
normalizado.
                                             1
Ejemplo: en el sistema decimal debe cumplir    ≤ x < 1 o sea .1 ≤ x < 1
                                            10
                                1
      En binario debe cumplir ≤ x < 1 o sea .5 ≤ x < 1
                                2

         La familia PDP-11 de DEC representan sus números de punto flotante con 32 bits:
   1                 8                                                23



       Signo de la       Exponente                                Mantiza en M. C. S.
        mantiza          en Exceso                                 y 1 bit escondido
                            2n-1

         La IBM representa sus números así:

   1                 7                                                24



       Signo de la       Exponente                                Mantiza en M. C. S.
        mantiza          en Exceso                                 y 1 bit escondido
                            2n-1

0.5x2=1.0
0.0x2=0.0

Bit escondido
       La mantiza se supondrá normalizada (siempre empezará con .1) y el primer 1 después del punto
binario se omitirá suponiendo que esté presente (escondido).

        Ejemplo Escribir –135.5 como la PDP-11 y como la IBM
135=10000111
-135=110000111 mcs
0.5 x 2 =1.0
entonces –135.5=110000111.1=.1100001111x29, en PDP-11 es:

                                                                                                 7
9 + 28-1(8 por el número de bits del exponente)=9 + 27=9 + 128=137 (en exceso 2n-1)
137=10001001 (exponente)


 1             10001001                                   .00001111000000000000000




Representar el punto flotante como la IBM el 237.57

  0              1001001                                   .110110110010001111010111


El Debug
       El Debug es una herramienta de edición y comprobación de programas el cual proporciona un
control de pruebas en un ambiente binario y de archivos ejecutables. Se puede ejecutar de dos maneras:
     Introduciendo DEBUG desde la línea de comandos (C:>Debug <↵>)
     Para depurar un archivo ejecutable (C:>Debug ejemplo.EXE <↵>)
       DEBUG [[unidad:][ruta]archivo [parámetros_de_test]]
       Donde [unidad:][ruta]archivo Especifica el archivo que se desea comprobar.
       parámetros_de_test Especifica la información de línea de comandos que precisa el archivo que
se desea comprobar.

        Si decide trabajar desde la línea de comandos del debug, al momento de presionar el enter
aparecerá un nuevo prompt esperando instrucciones. La línea de comandos del debug consiste en una
sola letra con uno a más parámetros. Después de iniciar Debug, escriba ? para visualizar una lista de los
comandos de depuración. Si un error de sintaxis ocurriera se indicará mediante un ^Error

Lista de comandos
                      Comando                                            Función
A [address]                                          Assemble
C range address                                      Compare Intervalo de direcciones
D [range]                                            Dump
E address [list]                                     Enter
F range list                                         Fill
G [=address [address …]]                             Go
H value value                                        Hex
I value                                              Input
L [addres [drive record record]]                     Load
M range address                                      Move
N file descriptor [file descriptor]                  Name
O value byte                                         Output
P [=dirección] [número]                              Proceed
Q                                                    Quit
R [register-name]                                    Register
S range list                                         Search
T [=address] [value]                                 Trace
U [range]                                            Unassemble
W [address [drive record record]]                    Write
XA [N.páginas]                                       allocate expanded memory

                                                                                                       8
Comando                                             Función
XD [identificador]                                 deallocate expanded memory
XM [páginaL] [páginaP] [identificador]             map expanded memory pages
XS                                                 display expanded memory status

      El debug permite colocar en memoria y ejecutar un grupo de instrucciones en lenguaje de
máquina una a una en un tiempo, permitiendo observar cómo el programa trabaja. El debug utiliza
números hexadecimales puesto que en términos de longitud es más fácil que con números binario.

        Trace (T) ejecuta una o más instrucciones comenzando con la dirección actual del apuntador de
instrucciones (CS:IP)

       Dump (D) Muestra el contenido de la memoria comenzando con una determinada localidad
(indicada ésta como segmento:desplazamiento)

       Quit (Q) termina la ejecución del DEBUG




                                                                                                   9
INTRODUCCIÓN A LA PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR
       El alumno conocerá cómo representa la computadora de manera interna los datos e instrucciones que
procesa mediante el debug.


                                             EL DEBUG y su Uso


        El término Debugging nació en los primeros días de la computación, en particular, un día en el
cual la computadora Mark I de Harvard falló. Después de buscar el problema lo encontraron: una
pequeña basura estaba entre los contactos de un relay (contacto electromagnético), la limpiaron y en el
libro técnico de la Mark I escribieron acerca del Debugguing.

        El debug permite colocar en memoria y ejecutar un grupo de instrucciones en lenguaje de máquina una a
una en un tiempo, permitiendo observar cómo el programa trabaja. El debug utiliza números hexadecimales,
puesto que en términos de longitud es más fácil que con números binarios.

        El nombre hexadecimal proviene de hexa (6) y deca (10), lo cual combinado representa 16 dígitos (0 – 9,
A - F). Con dos números hexadecimales se pueden representar 256 diferentes números con dos dígitos.

           Para ejecutar el Debug deberá estar en el símbolo del sistema (DOS) e introducir:

           C:>Debug <↵>3                                          Para ejecutar el debug
           Inmediatamente aparece un prompt ( - )
           Para salir del Debug deberá teclear Q
           - Q <↵>                                                 Para salir Q (Quit)

           El comando H (Hexarithmetic) suma y resta dos números hexadecimales
           - H 3 2 <↵>
           0005 0001

           - H 3D5C 2A10
           676C 134C
           - H 3A7 1ED
           0594 01BA

           -H91
           000A 0008

           -H96
           000F 0003

           ¿Qué pasa si nosotros usamos H 2 3?
           -H23
           0005 000F

           El FFFFh es igual al 65,535 ó 64 Kb alias –1
           H 5 FFFF
           0004 0006


3
    <↵> Significa Enter

                                                                                                            10
¿Qué pasa si nosotros utilizamos números de 5 dígitos?
       H 5CF00        4BC6
              ^ERROR

        El 8088/8088/80286/80386/80486 puede usar números con signo o sin signo. En la forma binaria para
números positivos el bit 5 es siempre 0, para los negativos 1. Si nosotros usamos instrucciones para números sin
signo en nuestro programa, el procesador ignora el bit de signo, de tal manera que nosotros podemos usarlo a
nuestra conveniencia. Los números negativos son conocidos como complemento a dos del número positivo.




                                                                                                             11
ARITMÉTICA DEL 8086/8088/80286 MEDIANTE EL DEBUG


       Conociendo algo del Debug y la aritmética binaria del procesador, nosotros podemos aprender cómo el
procesador trabaja y puede ejecutar órdenes internas llamadas instrucciones.

REGISTROS COMO VARIABLES
        Debug, nuestro guía e intérprete, conoce mucho acerca del procesador. Vamos a preguntar al Debug qué
podemos hacer respecto a esas pequeñas piezas llamadas registros que podemos usar como variables en donde
podemos almacenar datos. El procesador contiene un número fijo de registros conocidos como registros de
propósito general, los cuales no son parte de la memoria RAM de la PC.

        Nosotros le podemos solicitar al Debug que despliegue la información contenida en los registros con el
comando R (Register). Probablemente vea diferentes números en las líneas dos y tres del desplegado en la
pantalla, éstos números reflejan la cantidad de memoria de su computadora.

        Por ahora, el Debug nos ha proporcionado mucha información. Nos concentraremos en los registros AX,
BX, CX y DX, los cuales deben ser iguales a 0000. Los números de cuatro dígitos siguientes para cada registro
están en notación hexadecimal. Una palabra está compuesta por cuatro dígitos hexadecimales. Cada uno de estos
registros son de 16 bits, esto explica porque 8086/8088/80286 son conocidas como máquinas de 16 bits.

        Los otros registros, también son conocidos como de propósito especial: SP, BP, SI, DI, DS, ES, SS, CS,
e IP.

        El comando R hace más que desplegar los registros, también nos permite cambiarlos. Por ejemplo,
nosotros podemos cambiar el valor de registro AX.

        - R AX <↵>
        AX 0000
        : 3A7 <↵>
        R      (Para comprobar)

        Desde este momento utilizaremos el Debug como un intérprete, así que nosotros podremos trabajar
directamente con el procesador.

        Ahora, colocaremos un número en BX y otro en AX y, le pediremos al procesador que los sume y deje el
resultado en AX. Coloque AX=3A7h y en BX=92A con el comando R. Verifíquelo.

LA MEMORIA DEL PROCESADOR
        ¿Cómo le podemos decir al procesador que adicione BX a AX?. Nosotros colocaremos dos bytes de
código de máquina en algún lugar de su vasta memoria RAM, que le diga al procesador que sume los registros
con la ayuda del debug.

        La memoria está dividida en piezas de hasta 64Kb llamados segmentos. Nosotros colocaremos la
instrucción en algún lugar de un segmento y luego le diremos dónde está y que la ejecute sin saber dónde inicia
dicho segmento.

         Todos los bytes de la memoria RAM están etiquetados con números iniciando con 0000h. Pero recuerda
que la limitación de los números hexadecimales es de 4 dígitos. De esta manera, el número más alto que puede
ser usado como etiqueta de memoria es de 65,535, lo cual, implica la longitud máxima de los segmentos.

                                                                                                            12
Sin embargo, el procesador puede llamar más de los 64 Kb de memoria. ¿Cómo puede ser esto?. Se usan
dos números, uno para cada segmento de 64 Kb. y otro para el desplazamiento dentro del segmento. De tal
manera, que los segmentos están traslapados pudiendo el procesador utilizar más de un millón de bytes en
memoria.

       Todas las etiquetas de dirección serán usadas como resultado del principio de un segmento. Por ejemplo:
3756:0100 significará que nosotros estamos en la dirección 0100h del segmento 3756.

        Por ahora, confiaremos del debug para cuidar el segmento por nosotros. Así, que nosotros trabajaremos
sin prestar atención a los números de segmento. Ahora, cada dirección se refiere a un byte de un segmento y las
direcciones son consecutivas.

       Colocaremos la instrucción de adición ADD AX, BX en la posición 0100h y 0101h del segmento. El
código de la instrucción es 01D8h.

      El Comando del Debug para examinar y cambiar los datos en la memoria es E (de Enter). Use éste
comando para colocar la instrucción.

        - E 100
        3756:100                B4.01<↵>

        - E 101
        3756: 0101              85.D8<↵>

        El número de segmento que observa, probablemente sea diferente pero eso no afecta la operación.

ESTILOS DE ADICIÓN
        Si damos R, verificaremos que está cargada la instrucción correcta. Los bytes 01h y D8h tal vez no
significan nada para nosotros, pero para la máquina sí; es el código para el nemotécnico ADD AX, BX.

        Ahora, debemos decir al procesador dónde encontrar la instrucción (el segmento y el desplazamiento), lo
cual lo encuentra a partir de los registros CS e IP. Al desplegar nuevamente los registros veremos el valor del
segmento en CS, la segunda parte de la dirección se almacena en IP. Colocaremos IP= 0100, inicialmente,
siempre apunta a 0100h.

        Ahora le diremos al debug que utilice la instrucción mediante el comando T (Trace), el cual ejecuta la
instrucción en un tiempo. Después de ejecutar una instrucción el IP se incrementa y apunta a la siguiente
dirección, es decir, en 0102h (nosotros no hemos colocado ninguna instrucción en esa dirección, pero el
procesador sí). AX contiene ahora el resultado CD1h. Repita la instrucción, con los valores que conservan los
registros, el resultado en AX=15FBh y en BX=092Ah.

ESTILOS DE RESTA
       Ahora, vamos a escribir una instrucción para restar BX a AX, con los datos que conservan. Así que, el
código para la resta es 29h y D8h. Cárguelo a partir de la dirección IP=0100h, ahora ejecute la instrucción T, el
Resultado en AX es 0CD1h, repita nuevamente, ahora AX es 03A7h.

NÚMEROS NEGATIVOS
        El procesador usa el complemento a dos para los números negativos. Ahora, trabajaremos con la
instrucción SUB para calcular números negativos. Le haremos una pequeña prueba al procesador para obtener el
resultado FFFFh alias -1. Nosotros le restaremos un 1 a 0 colocando AX=0000 y BX=0001. Repitamos la
instrucción SUB en la dirección 0100. ¿Cuál es el resultado?. Haga la prueba con otros datos.


                                                                                                              13
BYTES
        Todos los datos hasta ahora han sido representados en palabras. ¿El procesador sabe cómo representar la
aritmética con Byte?. La respuesta es sí.

        Los registros de propósito general están divididos en dos bytes, conocidos como alto (High) y bajo
(low). Ahora ejecutaremos la instrucción ADD AH, AL, lo cual es una adición de dos bytes del registro AX y el
resultado quedará en AH. El código para esta instrucción es 00h y C4h.

        Carguemos AX =0102h, es decir AH=01 y AL=02; almacene el código de la instrucción a partir de la
dirección 100h y haga IP=0100h y ejecute la instrucción con el comando T. Ahora encontrará que AX=0302h. El
resultado de 01h + 02h = 03h que está almacenado en AH.

       Ahora, suponga que deseamos sumar 01h y 03h. ¿Podemos colocar 01h en AL?, la respuesta es no.
Tendrá que colocar 0301 porque el debug sólo nos permite cambiar la palabra completa.

        Ejecute nuevamente la instrucción, el resultado es 0401h, la suma de 03h + 01h está ahora en AH.

ESTILOS DE MULTIPLICACIÓN Y DIVISIÓN
       La instrucción de multiplicación llamada MUL y su código de máquina para multiplicar AX y BX es
F7h y E3h. La instrucción MUL almacena su respuesta en los registros AX y DX, puesto que multiplicar dos
números de 16 bits da como resultado uno de 32 bits. La parte alta de los 16 bits en DX y la parte baja en AX.
Nosotros escribiremos esta combinación de registros como DX:AX.

        Coloque el código de MUL a partir de la dirección 0100h y coloque AX=7C4Bh y BX=0100h.
Compruebe con R la instrucción, la cual observará como MUL BX. El procesador siempre realiza la operación
por default en AX.

       0100h * 7C4B. Los tres dígitos del 100 tienen el mismo efecto que en haxadecimal. El resultado es
7C4B00h, es decir, se suman dos ceros a la derecha DX=007Ch y AX=4B00h. Multiplicar dos palabras juntas
nunca pueden ser más de 2 palabras.

       Cuando nosotros dividimos dos números, el procesador da como resultado el cociente y el resto. El
código para la división es F7h y F3h. Colóquelo en la dirección 0100h y 010h. Como la instrucción MUL, DIV
también usa DX:AX. Si desplegamos con R, veremos la instrucción DIV BX.

        Ahora, dividamos el resultado de MUL que está en DX:AX, es decir, 007Ch:4B00h. Hagamos la
división 7C4B00h/0100h, por lo tanto pongamos 0100h en BX. El resultado, el cociente en AX=7C4Bh y el
resto en DX=0000h.




                                                                                                            14
IMPRIMIENDO CARACTERES


        Vamos a iniciar con las interrupciones del DOS para enviar un carácter a la pantalla. Construiremos un
pequeño programa y aprenderemos otra manera de poner datos en los registros. Ahora, veamos si podemos
hablar con el DOS.

INT 21h (El poder de la Interrupción)
        Usaremos la instrucción llamada INT para interrumpir lo que está haciendo el procesador y decirle al
DOS que imprima el carácter A en la pantalla. La función 02h de la interrupción 21h del DOS imprime un
carácter en la pantalla.

       Entraremos al Debug y haremos AX= 0200h y DX=0041h. El código en hexadecimal para la instrucción
INT 21h es CD21h, es una instrucción de dos bytes que iniciará en la dirección 100h, use R para confirmar que
IP=100h.

         No podemos usar el comando T para ejecutar esta instrucción (puesto que ejecuta una instrucción en un
tiempo), pero la instrucción INT llama (invoca) a un programa largo “subroutine” del DOS, porque trazaríamos
a través de una instrucción en un tiempo. Nosotros queremos ejecutar nuestra línea de programa, pero detenernos
antes de ejecutar la instrucción de la localidad 102h. Lo anterior, podemos hacerlo con el comando G (GO),
indicando la dirección en la cual queremos detenernos.

       - G 102 <↵>

        DOS imprimirá el carácter A y retornará el control a nuestro programa. En cierto sentido, nuestra línea
de instrucción es en realidad dos instrucciones, la segunda instrucción está en 102h.

        INT 21
        MOV SP BP
El registro 02h en AH le dijo al DOS que imprima un carácter. Otro número en AH, le dirá al DOS que realice
una función diferente. El DOS usa el número en DL como el código ASCII para el carácter a imprimir. El código
de A=41h.

       Son muchas las operaciones que realiza el DOS para imprimir un carácter simple.

INT 20h (Una salida con gracia)
       Si nosotros usamos la interrupción 20h, INT 20h (cuyo código hexadecimal es CD20h), le decimos al
DOS que deseamos salir de nuestro programa, así que el DOS puede tomar el control de nuevo. En nuestro caso,
INT 20h enviará el control de nuevo al Debug porque nosotros estamos ejecutando nuestro programa desde el
Debug en vez del DOS.

        Coloque la instruscción INT 20h iniciando en la localidad 100h, verifique con el comando R. Ahora,
ejecute la instrucción con el comando
        - G 102 <↵>
        Program terminated normally (El programa ha finalizado con normalidad)

UN PROGRAMA DE DOS LÍNEAS, PONIENDO LAS PIEZAS JUNTAS
      Ahora, juntemos los dos tipos de instrucciones colocándolas a partir de la dirección 0100h (sus códigos
son CD21h y CD20h).


                                                                                                            15
Para listar varias instrucciones (es decir, ver los nemónicos), necesitamos el comando U (Unassembler).
Al proporcionar
       - U 100 <↵>

        La computadora desplegará varias instrucciones, nosotros reconoceremos las dos primeras.
Posteriormente, coloque AX=0200h y DX= cualquier número ASCII del carácter que desee imprimir en
pantalla. Para ejecutar las instrucciones

        - G 104 <↵>
        (X) es la letra que se deseó imprimir en DX
        Program terminated normally

PROGRAMAS ENTEROS
      Hasta ahora, nosotros hemos cargado nuestras instrucciones con números (códigos de máquina). El
comando A (Assembler) nos permite cargar nemotécnicos directamente en memoria.

        - A 100 <↵>
        3970:0100       INT 21
        3970:0102       INT 20
        3970:0104       <↵>

         Aquí, el comando A le dijo al Debug que deseamos colocar instrucciones en forma nomotécnica a partir
de la dirección 0100h.

MOVIENDO DATOS ENTRE REGISTROS
     Coloque 1234h en AX (AH=12h y AL=34h) y ABCDh en DX (DH=ABh y DL=CDh).
     - A 100 <↵>
     3970:0100     MOV AH, DL
     3970:0102     MOV AL, DH
     3970:0104     <↵>

       Verifique que IP=0100h y ejecute las instrucciones con
       - G 104
       Observe los datos almacenados en AX.
Ahora, almacene a partir de la dirección 0200h las siguientes instrucciones

        MOV AH, 02               ; Carga tipo de función
        MOV DL, 2A               ;Carga código ASCII del *
        INT 21                   ;Solicita la INT 21h para imprimir un carácter
        INT 20                   ;Retorna el control al Debug

        Ejecútelo y observe qué pasa.

        Para grabar el programa en disco, use primero el comando N (Name), el cual asigna un nombre a un
archivo antes de grabarse.
        - N imprime.com

        Antes de grabar, debemos proporcionar el número de bytes a grabar a partir de la dirección contenida en
IP. Para hacer esto, se calcula: 4 instrucciones * 2 bytes = 8 bytes de longitud. Otra manera, es observar la
dirección final del programa y hacer
        - H 208 200 <↵>

        Siempre se debe proporcionar una localidad después de la última instrucción

                                                                                                            16
El debug utiliza los registros BX:CX para almacenar la longitud de un archivo a grabar, por lo tanto,
colocaremos en CX el 08h y en BX el 00h. Por último, para grabar el programa, usaremos el comando W (Write)
        - W <↵>
        Writing 0008 bytes

       Para correrlo desde el DOS sólo se da el nombre del programa.
       A: imprime <↵>

ESCRIBIENDO STRINGS DE CARACTERES
        Debemos usar la interrupción 21h con una función diferente en AH para escribir una string en la
pantalla. Antes debemos almacenar en memoria y decirle al DOS dónde se encuentra.
        02= Imprime un carácter en pantalla.
        09 Imprime una string y se detiene al encontrar el carácter $

       Colocaremos la string a partir de la localidad 0200h con E 200
                               48            65            6C           6C
                               6F            2C            20           44
                               4F            53            20           68
                               65            72            65           2E
                               24

       La string termina con el número 24h, que indica fin de la string. Lo anterior, explica porqué el DOS
nunca utiliza el $, es decir, no puede imprimirlo.

       Con el comando D (Dump), podemos ver las cadenas de caracteres en memoria.
       - D 200 <↵>
       ------------        ------------------------------------------------------ HELLO, DOS HERE

        Vemos 16 bytes hexadecimales, seguidos de los mismos pero en ASCII. Donde vea un puntoen la
ventana de ASCII, representa un carácter especial, por ejemplo la letra griega beta o theta. El comando D
despliega 96 caracteres de los 256 caracteres usados en la computadora, es decir, que 160 caracteres son
representados por un punto (.).
        MOV AH, 09              ;Función imprime string
        MOV DX, 0200            ;Dirección donde inicia la string
        INT 21
        INT 20
        Al ejecutarlo,
        HELLO, DOS HERE.
        El programa ha finalizado con normalidad

        Ahora, asigna un nombre al programa y grábalo en disco, puedes usar el comando H para auxiliarte a
calcular la longitud del programa.




                                                                                                          17
Registro de banderas
Usos comunes de los registros internos del 8088
Registro Descripción
Datos
AX        Acumulador: usado para almacenamiento de programación en general, también para
          algunas instrucciones como multiplicación, división, I/O, manejo de cadena de caracteres.
BX        Base: Cuando se accesa la memoria, con frecuencia se utiliza este registro para contener
          valores de direcciones. Al hacer uso de rutinas de servicios de interrupción, este registro
          debe contener un valor que se usa para selección de opciones
CX        Contador: durante la ejecución de un loop, este registro contiene el valor de un índice de
          conteo
DX        Datos: usado para almacenamiento general y también para operaciones de multiplicación y
          división
Segmento
CS        Registro de segmento de código: éste registro apunta al inicio del segmento donde el
          programa en ejecución se encuentra situado
DS        Registro de segmento de datos: Señala el inicio del segmento de datos
SS        Registro de segmento de pila: Señala el inicio del segmento de pila
ES        Registro de segmento extra: Señala el inicio del segmento de extra
Apuntador
SP        Apuntador de pila: para algunas instrucciones este registro contiene valores de
          desplazamiento para el stack
BP        Apuntador base: Similar a SP. Algunas instrucciones hacen uso de el con el fin de guardar
          el valor de un desplazamiento
Índice
SI        Índice fuente: para ciertas instrucciones, este registro contiene la dirección fuente con
          frecuencia las instrucciones que hacen uso de este recurso no requieren de operandos
DI        Índice destino: Contraparte con SI y contiene la dirección destino para algunas
          instrucciones.

IP          Apuntador de instrucciones: apunta a la localidad de memoria donde se encuentra la
            próxima instrucción a ser ejecutada
SF          Banderas o registro de estado de banderas: existen 9. estas proporcionan información con
            respecto al resultado de varias operaciones

                                                Bits
 15    14     13       12   11   10     9     8      7     6     5      4     3      2     1     0
 X     X      X        X    OF   DF    IF    TF     SF    ZF     X     AF     X     PF     X    CF
                                                SF

Notas: AX, BX, CX, DX se subdividen en 2 bytes (p.e. AX = AH,AL)
       AX = 16 bits = 1 word
       AH, AL = 8 bits cada uno = 1 byte
       Los demás registros requieren de 1 word o sea 16 bits

      Todos los nombres de registros son palabras reservadas al efectuar un programa en
ensamblador.


                                                                                                  18
Bandera                                                                                                                Debug
No. Bit Designación                                            Descripción                                                  S    O
  0         CF      Bandera de acarreo: el valor de este bit es 1 si el resultado de una operación de adición CY NC
                    o sustracción genera un acarreo o préstamo.
  1      No usado -------------------------------------------------------------------------------------------------------- ---- ----
                    -
  2         PF      Bandera de paridad: es un 1 si el resultado de una operación de datos tiene un número PE PO
                    par de bits iguales a 1
  3      No usado -------------------------------------------------------------------------------------------------------- ---- ----
                    -
  4         AF      Bandera de auxiliar de acarreo: indica la presencia de un acarreo generado del cuarto AC NA
                    bit de 1 byte. Su mayor uso es durante operaciones aritméticas con números decimales
                    codificados en binario
  5      No usado -------------------------------------------------------------------------------------------------------- ---- ----
                    -
  6         ZF      Bandera de cero: es activada si el resultado de una operación es cero                                  ZR NZ
  7         SF      Bandera de signo: se activa si el resultado de una operación con números signados es NG PL
                    negativo.
  8         TF      Bandera de trampa: cuando este bit es activado, el 8088 ejecuta una instrucción a la ---- ----
                    vez (No se considera en el debug)
  9          IF     Bandera de habilitación de interrupción: el 8088 atenderá a las interrupciones solo EI                       DI
                    cuando este bit sea activado
 10         DF      Bandera de dirección: Cuando es activada, causa que el contenido de los registros DN UP
                    índice se decremente después de cada operación de una cadena de caracteres
 11         OF      Bandera de sobreflujo: es activada cuando el resultado de una operación es mayor que OV VN
                    el máximo valor que es posible representar con el número de bits del operando destino
12-15    No usado -------------------------------------------------------------------------------------------------------- ---- ----
                    -




                                                                                                                                 19
IMPRIMIENDO NÚMEROS BINARIOS


       Ahora nosotros construiremos un programa para escribir números binarios en la pantalla.

BANDERAS DE ACARREO Y ROTACIÓN
        Si le adicionamos 1h a FFFFh, el resultado debería ser 10000h; sin embargo, se produce un
overflow. Solamente los 4 dígitos más a la derecha encajan en una palabra, pero el 1 no. El 1 es un
overflow y no está perdido. Se va a un lugar llamado bandera, en este caso, la bandera de acarreo o CF.
Las banderas contienen un bit (0,1). Si nosotros necesitamos un acarreo de un 1 dentro del dígito
quinto, éste va dentro de la bandera de acarreo.

       Si hacemos AX = FFFFh y BX = 01h y ADD AX, BX. Al final de la segunda línea del debug al
dar R, verá 8 pares de letras. Podrá leer NC o CY (acarreo). El resultado de la operación, resultará un
overflow de 1, entonces, la bandera estará en CY (carry). El acarreo es de 1, es decir está activada.

       Para comprobar que se ha almacenado el bit 17 (o el noveno para una operación de 8 bits),
adicione 1 a 0 en AX, con IP = 0100h y repitiendo la instrucción de nuevo. La bandera estará afectada
por cada instrucción ADD, y en este momento no hubo acarreo, por lo que se desactivará, lo que indica
con NC (no carry) al dar R.

       Al imprimir un número binario, la información del acarreo nos es útil. Imprimiremos solamente
un caracter a un tiempo y sacaremos los bits de nuestro número uno por uno, desde la izquierda a la
derecha. Por ejemplo, el primer caracter del número 1000 0000b es el uno.

       Nosotros podemos mover un byte un lugar hacia la izquierda, almacenando el uno en la bandera
de acarreo y adicionando un 0 a la izquierda, repitiendo el proceso para cada dígito sucesivo. Para
hacer esto, usamos la instrucción RCL (rotación de acarreo hacia la izquierda). Ejemplo:

       RCL BL, 1             ;Rota el byte en BL un lugar hacia la izquierda.

       Esto lo hace a través de la bandera de acarreo. La instrucción es llamada rotación porque RCL
mueve el bit de la izquierda a la bandera de acarreo. En este proceso, todos los demás bits son movidos
o rotados a la izquierda. Después de cierto número de rotaciones suficientes (17 para una palabra, 9
para un byte), los bits serán movidos a la posición original y se regresará al número original.

       Ponga B7 en BX y ejecute la instrucción 9 veces. Convirtiendo sus resultados a binario,
observará:

     Carry                               Registro BL                            No. Hexadecimal
       0                                 1011 0111                                    B7
       1                                 011 01110                                    6E
       0                                 11 011101                                    DD
      …                                      …                                        …
       0                                 1011 0111                                    B7


                                                                                                    20
Ahora veremos cómo convertir el bit en la bandera de acarreo en un carácter 0 ó 1.

ADICIÓN CON LA BANDERA DE ACARREO
        La instrucción ADC (adiciona con acarreo), adiciona tres números, los dos normales mas un bit
de acarreo. El 0 = 30h y el 1 = 31h en código ascii. Así que adicionando a la bandera de acarreo el 30
conseguiremos el 0 cuando el bit de acarreo está en 0 (desactivado) y 1 cuando el bit de acarreo está en
1 (activado).

      Si DL = 0 y la bandera de acarreo está activada (1) y ejecutamos: ADC DL, 30 entonces
conseguimos el 31h = 1b, es decir, nosotros podemos convertir el acarreo en un caracter que podemos
imprimir.

        Ahora, nosotros necesitamos un loop para ejecutar RCL, ADC e INT 21h 8 veces, una para cada
bit del byte.

LOOPING
      El loop es como un for – next, pero no tan general. Loop decrementa CX y finaliza cuando
CX=0.

        Aquí presentamos un programa simple que rotará BX 8 veces, moviendo BL en BH (pero no al
revés), puesto que nosotros rotamos a través de la bandera de acarreo. El loop inicia en 106h y termina
en la instrucción loop.

                  0100    MOV BX, A3C5
                  0103    MOV CX, 0008
                  0106    RCL BX, 1
                  0108    LOOP 0106
                  010A    INT 20

        Para ejecutarlo, puede hacerse paso a paso con T o con G 010A (sin ejecutar INT 20 puesto que
inicializa los registros). Podemos comprobar que CX = 0 y que BX = C551 o BX = C5D1, dependiendo
del valor inicial de la bandera de acarreo.

ESCRIBIENDO NÚMEROS BINARIOS
             0100 MOV AH, 02
             0102 MOV CX, 0008
             0105 MOV DL, 00
             0107 RCL BL, 1
             0109 ADC DL, 30
             010C INT 21
             010A LOOP 0105
             0110 INT 20

       Ejecútese con G después de INT 20, BL contiene el número impreso en binario. Recuerde que
no se puede ejecutar con T la instrucción INT 21 e INT 20.




                                                                                                     21
IMPRIMIENDO EN HEXADECIMAL


COMPARANDO CON LA AYUDA DEL REGISTRO DE BANDERA.
       Si el resultado de la última operación de la bandera del cero (ZF) es cero, entonces, la bandera
será ZR (Zero), en caso contrario, al activarse será NZ (Not Zero).

        Si la bandera del signo (SF) es cero, entonces, la bandera será PL (Plus o positivo), en caso
cotrario, al activarse será NG (Negative).

       Si la bandera del overflow (OF) es cero, entonces, la bandera será VN (No overflow), en caso
contrario, al activarse será OV (Overflow).

      JZ (Salta si es cero), salta si el resultado de la última operación aritmética es cero, es decir,
cuando la bandera ZF es ZR.

        JNZ (Salta si no es cero), salta si el resultado de la última operación aritmética no es cero, es
decir, si la bandera ZF es NZ.

       Ejemplo:
       396F:0100      MOV AL,05
       396F:0102      SUB AL,01
       396F:0104      JNZ 0102
       396F:0106      INT 20

        CMP (Compare), permite realizar comparaciones sin almacenar el resultado, es decir, puede
activar únicamente el registro de banderas. Ejemplo:

       CMP AX, BX

       Si el resultado es cero se activa la bandera del cero en ZR = 1, pero los datos en los registros se
conservan.

IMPRIMIENDO UN DÍGITO EN HEXADECIMAL.
       Iniciaremos colocando un pequeño número entre 0h y Fh en BL. Los caracteres ASCII del 0 al 9
son 30h a 39h, de la A a la F, son 41h a 46h. Estos dos grupos ASCII, están separados por 7 caracteres.
Como resultado, la conversión ASCII será diferente para los dos grupos de números. Cada grupo se
manejará en forma diferente.

       If BL < 0Ah
              Then BL = BL +30h
              Else BL = BL + 37h




                                                                                                       22
Otra manera
      BL = BL +30h
      If BL >= 3A
             Then BL = BL +07h

        El siguiente programa cargará en BL un simple dígito en hexadecimal y lo imprimirá en
pantalla.

       127B:0100      MOV AH,02
       127B:0102      MOV DL, BL
       127B:0104      ADD DL, 30
       127B:0107      CMP DL, 3A
       127B:010A      JL 010F
       127B:010C      ADD DL,07
       127B:010F      INT 21
       127B:0111      INT 20

      CMP compara DL con 3Ah y activa banderas pero no cambia DL. JL (Jump if less than, Salta si
DL < 3Ah).

        Mediante una operación lógica podemos aislar los 4 bits más bajos que representan el segundo
dígito hexadecimal. Para rotaciones de más de un bit utilizamos el registro CL para llevar la cuenta. CL
se usa para indicar el número de veces que va a rotar el byte o palabra.

¿Cómo podremos imprimir dos dígitos hexadecimales?
        Nuestro plan ahora, es rotar el byte en DL cuatro dígitos a la derecha, usando SHR (corrimiento
a la derecha). Moviendo los 4 bits más altos a la derecha. Si hacemos:

       MOV CL, 04
       MOV DL, 5D
       SHR DL, CL

       Entonces DL = 5D, o sea, el primer dígito de 5Dh, lo cual se imprimirá.

       Escribiremos un programa para colocar un número en BL e imprimirlo.

              MOV AH, 02
              MOV DL, BL            ;Se inicializa con el número hexadecimal a imprimir
              MOV CL, 04
              SHR DL, CL
              ADD DL, 30
              CMP DL, 3A
              JL BRINCO             ; Aquí debe ir la dirección donde se encentra la INT 21h
              ADD DL, 07
BRINCO:       INT 21
              INT 20

        Para aislar e imprimir el segundo dígito, dejando DL = a los 4 bits inferiores, se activan los 4
bits superiores en cero con la función lógica AND, herramienta de lógica formal.
                                                                                                     23
Por ejemplo, AND BL, CL
     BL     1011 0101
     CL     0111 0110
            ---------------
     AND 0011 0100

     Usando AND BL, 0Fh tenemos:
     BL    1011 0101
     0Fh 0000 1111
           ---------------
     AND 0000 1111

     El programa que imprime el segundo dígito hexadecimal es:

           MOV AH, 02
           MOV DL, BL
           AND DL, 0F
           ADD DL, 30
           CMP DL, 3A
           JL BRINCO
           ADD DL, 07
BRINCO:    INT 21
           INT 20




                                                                 24
LEYENDO CARACTERES


       Ahora realizaremos el proceso inverso, leeremos dos caracteres en hexadecimal del teclado y lo
convertiremos a un byte.

LEYENDO UN CARACTER
       La interrupción 21h puede ser utilizada con la función 01h para leer un caracter (con eco) del
teclado. Al ejecutarse, el cursor se detendrá parpadeando en espera de que presionemos una tecla. Al
hacerlo, el DOS colocará el código ASCII del caracter leído en AL.

LEYENDO UN NÚMERO HEXADECIMAL
        Para leer un carácter hexadecimal como 0, 1, …, 9, A, B, …, F, y convertirlo a un byte debemos
sustraer al código ASCII del caracter leído 30h (si el caracter es 0, 1, …, 9), o 37h (si el caracter es A,
B, …, F).

                      MOV AH, 01h            ;Función lee un caracter
                      INT 21                 ;Lee caracter y guarda su código ASCII en AL
                      SUB AL, 30             ;Restar a AL 30h
                      CMP AL, 09h            ;¿Es número o letra?
                      JLE Salto1             ; Si es número salta
                      SUB AL, 07h            ; Como es letra restar al AL 07h
       Salto1:        INT 20                 ; Regresa el control al DOS.

       JLE (Jump if Less Than or Equal), salta si es menor o igual. Ocasiona que la ejecución de un
programa se ramifique hacia la dirección del operando si la bandera de signo no es igual a la de
sobreflujo o si la bandera de cero está activada. Esta instrucción es funcionalmente igual que JNG
(Jump in Not Greater Than), salta si no es mayor que.

      Nota: trabaja correctamente con números en hexadecimal válidos (o sea las letras en
mayúsculas).

LEYENDO DOS NÚMEROS HEXADECIMALES
       Se lee el primer dígito colocando su valor en hexadecimal en DL y lo multiplicamos por 16.
para multiplicar haremos un SHL (corrimiento a la izquierda) en DL, poniéndole un cero hexadecimal
(cuatro bits a la derecha). Al hacer SHL DL, CL con CL = 4 realizamos un corrimiento aritmético (ya
que tiene el mismo efecto que una multiplicación aritmética por 2, 4, 8, 16, …, etc.), dependiendo del
valor en CL. Posteriormente leeremos el segundo dígito hexadecimal y se lo adicionaremos al primero
en DL.




                                                                                                        25
MOV AH, 01h
          INT 21
          MOV DL, AL
          SUB DL, 30h
          CMP DL, 09h
          JLE Salto1
          SUB DL, 07h
Salto1:   MOV CL, 04h
          SHL DL, CL
          INT 21
          SUB AL, 30
          CMP AL, 09h
          JLE Salto2
          SUB AL, 07h
Salto2:   ADD DL, AL
          INT 20




                        26
PROCEDIMIENTOS Y PILAS


PROCEDIMIENTOS
      Un procedimiento es una lista de instrucciones que podemos ejecutar desde varios lugares de un
programa, en vez de tener que repetirlos cada vez que las necesitemos.

        Llamaremos a un procedimiento con la instrucción CALL y regresaremos de este con la
instrucción RET.

Programa Principal
      ------                                                         Procedimiento1
      ------                                                           ------
      ------                                                           ------
      CALL PROCEDIMIENTO1                                              ------
      ------                                                           ------
      ------                                                         RET
      ------
      CALL PROCEDIMIENTO1
      ------
      ------
      ------
End

       Ejemplo de un programa en DEBUG que imprime las letras de la A a la J
0100   MOV DL, 41h
0102   MOV CX, 000A
0105   CALL 0200
0108   LOOP 0105
010A   INT 20
                                             0200 MOV AH, 02
                                             0202 INT 21
                                             0204 INC DL
                                             0206 RET

       La primera instrucción coloca el código ASCII de la letra A (41h) en DL para imprimir el
carácter mediante la INT 21, pero esta instrucción se ejecutará de forma lejana.

        Cuando llamamos el procedimiento localizado en 0200 colocamos en AH el valor de 02 que es
la función para imprimir el carácter contenido en DL usando la INT 21.

      INC DL, es una nueva instrucción que incrementa en uno el registro DL. RET, regresa al
programa principal situándose en la primera instrucción ejecutable después de su llamada en este caso
LOOP 0105.



                                                                                                  27
Ejecute el programa para ver el resultado mediante el comando G.

LA PILA Y EL RETORNO DE DIRECCIONES
        La instrucción CALL de nuestro programa necesita salvar la dirección de retorno en algún lugar
del microprocesador sabiendo qué instrucción ejecutar cuando regrese de la instrucción RET. Para
poderlo almacenar, necesitaremos una porción de la memoria conocida como pila. Para poder seguirle
el rastro de lo que hace la pila, existen dos registros que podremos observar al ejecutar R: estos son el
SP (Stack Point, Apuntador de Pila) y el SS (Stack Segment, Segmento de Pila) los cuales tendrán el
número del segmento.

                                       Dirección        Pila

                                         0098:
                    SP:0100              0100:          0203
                                         0102:          0103
                                         0104:



       En una Pila el último que entra será el primero en salir a esto es conocido como LIFO (Last In,
First Out), esta secuencia es precisamente lo que necesitamos para revertir el regreso de direcciones
después de que hacemos llamadas anidadas como en el presente ejemplo.

396F:0100 E8FD00      CALL 0200
                            …
396F:0200 E8FD00      CALL 0300
396F:0203 C3          RET
                            …
396F:0300 E8FD00      CALL 0400
396F:0303 C3          RET
                            …
396F:0400 C3          RET

        Aquí la instrucción en la dirección 0100h llama a uno en la dirección 0200h, la cual llama a otra
en la dirección 0300h la cual llama a otra en la dirección 0400 donde finalmente vemos una instrucción
de retorno (RET). Este RET, regresa a la instrucción siguiente previa a la instrucción CALL de la
dirección 0300h o sea el microprocesador ejecuta la instrucción 0303h. pero encontrará otra instrucción
RET en 303h la cual será empujada por la siguiente dirección (la 203h) dejándola fuera de la pila. De
este modo el microprocesador retomará la instrucción ejecutando 2003h al inicio. Cada RET saca en
que se encuentra al inicio regresando la dirección fuera de la pila de este modo cada RET siguiente el
mismo camino volverá a las llamadas hechas atrás.

                                       Dirección        Pila

                                         0098:          0303
                    SP:0098              0100:          0203
                                         0102:          0103


                                                                                                      28
0104:




METIENDO Y SACANDO (PUSHing and POPping)
        La pila es un útil lugar para guardar palabras (words) de datos momentáneamente,
proporcionándonos el cuidado de restablecer la pila después de una instrucción RET. Hemos visto que
una instrucción CALL mete una dirección de retorno (una palabra, word) colocándolo al tope
(principio) de la pila mientras que una instrucción RET saca esta palabra del tope de la pila. Cargándola
dentro del registro IP y expone la palabra que se encontraba debajo de esta. Nosotros podremos hacer
mucho entendiendo perfectamente las instrucciones de PUSH y POP.

        Es conveniente salvar los valores de los registros de inicio de un procedimiento y restaurarlos al
finalizar justo antes de la instrucción RET. Entonces liberaremos el uso de estos registros y de paso
entender los procedimientos.

       Los registros están compuestos por varios niveles de procedimientos, conduce al siguiente nivel
de abajo. Por salvar los registros al inicio de un procedimiento y restaurarlo al final de este, no
necesitamos remover instrucciones este procedimiento de los diferentes niveles, haciendo nuestra
programación muy sencilla.

Ejemplo.
0200 PUSH CX
0201 PUSH DX
0202 MOV CX,0008
0205 CALL 0300
0208 INC DL
020A LOOP 0205
020C POP DX
020D POP CX
020E RET

       Note que los POP’s están en orden inverso que los PUSH’s esto es porque un POP remueve una
palabra situada más recientemente en la pila y el último valor de DX está sobre el último valor de CX.

       Salvando y restaurando CX y DX nos permite cambiar los registros dentro del procedimiento
iniciado en 0200h pero sin cambiar los valores usados por el procedimiento llamado y teniendo salvado
CX y DX podremos usar estos registros como variables locales.

LEYENDO NÚMEROS HEXADECIMALES CON MÁS CLASE
       Podemos crear un procedimiento ocultando las lecturas de caracteres hasta recibir uno que
pueda convertirse en número hexadecimal entre 0 y Fh. No desplegaremos algún carácter inválido por
lo tanto usaremos la función 08 de la Int 21h que lee caracteres pero no los coloca en pantalla y
haremos un eco (desplegaremos) solo si es uno válido.

       Coloque 8h en el registro AH y ejecute esta instrucción digitando A justo después de ejecutar G
102
100 INT 21
                                                                                                       29
El código ASCII de A (41h) está ahora en el registro AL, pero A no aparece en la pantalla.
Usando esta función, nuestro programa puede leer caracteres sin eco hasta leer un dígito hexadecimal
válido (0-9 o A-F) con eco.

      Este es el procedimiento que hace eso y convierte un carácter hexadecimal a un número
hexadecimal.

0200   PUSH DX
0201   MOV AH,08
0203   INT 21
0205   CMP AL,30
0207   JB 0203
0209   CMP AL,46
020B   JA 0203
020D   CMP AL,39
020F   JA 21B
0211   MOV AH,02
0213   MOV DL,AL
0215   INT 21
0217   SUB AL,30
0219   POP DX
021A   RET
021B   CMP AL,41
021D   JB 0203
021F   MOV AH,02
0221   MOV DL,AL
0223   INT 21
0225   SUB AL,37
0227   POP DX
0228   RET

        El procedimiento lee un carácter en AL (con la INT 21 de 203h) y verifica que sea válido con
las comparaciones (CMP) y los saltos condicionales. Si el carácter leído no es válido la instrucción es
de salto condicional enviando al microprocesador atrás en la dirección 0203 donde la INT 21 lee otro
caracter (JA, salta si está arriba; JB, Salta si está debajo; ambos tratos son para números sin signo hay
instrucciones JL que usaremos para tratar a números con signo).

       En la línea 211h sabremos si tenemos un dígito válido entre 0 y 9 por lo tanto sustraemos el
código para colocar 0 y regresamos el resultado en el registro AL recordando sacar el registro DX
cuando lo salvemos iniciando el procedimiento. El proceso del dígito hexadecimal de A - F es similar.
Observe que tendremos 2 instrucciones RET en este procedimiento; tendremos varios o solamente uno.

     Este es un simple programa de prueba del procedimiento.
0100 CALL 0200
0103 INT 20




                                                                                                      30
Como hemos hecho antes, use el comando G, con un punto de interrupción, o use el comando P.
Ejecute la instrucción CALL 200h sin ejecutar la instrucción INT 20h, para que vea los registros antes
de finalizar el programa y que se restablezcan los registros.
        Usted verá el cursor al lado izquierdo de la pantalla, esperando un carácter. Teclee k que no es
un carácter válido. Nada debe pasar. Ahora, teclee cualquiera de los caracteres del hexadecimal
mayúsculos. Usted debe ver el valor del hexadecimal del carácter en AL y el propio carácter hechos
eco de en la pantalla. Pruebe este procedimiento con las condiciones del límite: ' ' (el carácter antes del
cero), 0, 9, ': ' (el carácter sólo después de 9), y así sucesivamente.
        Ahora que nosotros tenemos este procedimiento, el programa para leer un número hexadecimal
de dos dígitos, con el tratamiento de errores, bastante aceptable:
0100   CALL 0200
0103   MOV DL, AL
0105   MOV CL, 04
0107   SHL DL, CL
0109   CALL 0200
010C   ADD DL, AL
010E   MOV AH, 02
0110   INT 21
0112   INT 20

       Podemos ejecutar este programa en el DOS, desde que lee en un número hexadecimal de dos
dígitos y entonces muestra el carácter ASCII correspondiente al número tecleado. Aparte del
procedimiento, el programa principal es mas simple que la versión escrita anteriormente, sin tener que
duplicar las instrucciones para leer los caracteres. Nosotros agregamos tratamiento de errores, sin
embargo, y aun cuando complicó nuestro procedimiento, también asegura que el programa acepta sólo
entradas válidas.

       Hemos visto la razón de salvar el registro DX en el procedimiento. El programa principal
almacena el número hexadecimal en DL, para que nosotros no cambiemos DL en nuestro
procedimiento situado en 200h. Por otro lado, el procedimiento situado en 200h usa el propio DL para
hacer eco de los caracteres. Así, usando la instrucción PUSH DX de al principio del procedimiento, y
POP DX al final, nos libramos de los problemas.

      A partir de ahora, evitaremos las interacciones complicadas entre los procedimientos, nosotros
seremos muy estrictos sobre guardar cualquier registro usado por un procedimiento.




                                                                                                         31
PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR
      El alumno programará en Lenguaje Ensamblador para trabajar a bajo nivel en la
computadora y desarrollará diversas aplicaciones.

Proceso de ensamble
   1. Editar el programa con un editor de texto simple y que se guarde con extensión .ASM
   2. MASM <nombre del archivo>.ASM;
   3. LINK <nombre del archivo>;
   4. EXE2BIN <nombre del archivo>.EXE <nombre del archivo>.COM

Rutinas utilizadas en Ensamblador
Programa       Descripción
Editor         Programa que permite crear un código fuente. DOS proporciona el Edit.
MASM           Es el programa macroensamblador de IBM para cargarlo en memoria se requieren 96K
               de RAM. Existe una versión más modesta denominada small assembler (ASM), que
               solo necesita 64K de memoria pero no ofrece muchas de las características de MASM
               (entre ellas el soporte a macros). MASM se emplea para ensamblar código fuente y
               generar código objeto. Durante su operación, MASM pide al usuario los nombres para
               el archivo fuente (extensión .ASM), el archivo objeto que se genera (OBJ), el listado de
               los nombres de archivo (LST), y finalmente un listado de referencias cruzadas (CRF)
LINK           Este programa LINK se emplea para encadenar diversos módulos objetos generados ya
               sea pos MASM o por otros compiladores. El programa se encarga de asignar
               localidades de memoria absolutas para relocalizar al código objeto. El encadenador
               permite el desarrollo de código modular ya que con él es posible cambiar módulos
               individuales y para producir un programa completo. Cada módulo se puede depurar pr
               separado y después ser integrado al programa.
DEBUG          El programa DEBUG es útil durante la fase de desarrollo de programas. Tienen
               características que permiten al usuario ejecutar, por ejemplo, un programa paso a paso y
               examinar dinámicamente cómo cambia la memoria, también observar las banderas y la
               ejecución del programa desde un punto determinado (break point) monitoreando los
               registros.

Tipos de instrucciones en lenguaje ensamblador
       Las instrucciones del lenguaje ensamblador pueden ser de diferentes estructuras dependiendo
del número de direcciones que maneje.

       Instrucciones de 3 + 1 direcciones:

                                                                           Dirección
                   Código de      Dirección      Dirección   Dirección       de la
                   operación        OP1            OP2       de destino    siguiente
                                                                          instrucción
Ejemplos:
                    ADD A,B,C,D
                    MUL K,R,PZ

       Instrucciones de 3 direcciones:
       Eliminando la dirección de la siguiente instrucción surgió la máquina con 3 direcciones. Se
ejecutaría la instrucción siguiente en orden físico:

                                                                                                    32
Dirección
                          Código de                                       del
                                            OP1            OP2
                          operación                                    resultado
                                                                        destino

       Máquinas con instrucciones de 2 direcciones: se eliminó la dirección del destino y el resultado
se guardó en la localidad del segundo operando

                                                  OP1              OP2
                                 Código de      Dirección       Dirección
                                 operación       fuente         de destino
Ejemplo:
                    MUL R1,R2     ; Multiplica R1 a R2 y guarda el resultado en R2

       Máquinas con instrucciones de una dirección: Eliminando y usando un registro llamado
acumulador en la cual se pueden realizar operaciones aritméticas, las instrucciones quedan con una sola
dirección. Ésta podrá ser fuente o destino según sea lo que indique la instrucción usada.

                                                         Operando
                                       Código de
                                                          fuente /
                                       operación
                                                          destino

Ejemplo:
                    SUB AL, AL    ;SUB AL se resta a AL
                    ADD AH, BH    ; ADD BH se suma a AH
                    DIV AX        ; Se divide a AX el valor de AX
                    DIV AX, CX    ;DIV CX se divide AX entre CX

        Máquinas de cero instrucciones: Manejando una pila se puede hablar de una máquina con cero
instrucciones (aunque en verdad no son cero instrucciones).
        Ésta máquina usa dos instrucciones PUSH (empuja un dato) POP (Jala un dato) para llevar a la
pila y sacar de ella un dato.

        Las operaciones se efectúan con los elementos superiores de la pila y el resultado se queda en
ella. Por ejemplo Calcular C=(a+b)/(d-e). La pila es una estructura de datos en memoria en la cual el
primer elemento que entra es el último en salir.

                                                     .
                                                     .
                                                     .
                           Apuntador de
                           base (BP)                                 Apuntador
                           indica la                                 de    pila
                           dirección base                            (SP)
                           de la pila




                                                                                                    33
B
                 E                           A           A            A+B
  D              D              D-E         D-E         D-E           D-E             C
Push D         Push E           SUB        Push A       Push B        ADD            DIV          Pop C


Instrucciones en Macroensamblador
                  [etiqueta] mnemónico de instrucción [operando] [;comentario]

       [ ] significa que es opcional
       etiqueta: se usa como punto de entrada o regreso. El nombre se asocia con la dirección donde
comienza una instrucción y puede tener hasta 31 caracteres [A-Z, a-z, 0-9, ?, ., @, _, $] y debe iniciar
con cualquier carácter distinto de 0-9.
       mnemónico de instrucción: debe contener una de las 92 instrucciones posible. Por ejemplo:
                        SUB destino, fuente
                        SUB AX, AX; AX AX-AX
                        SUB AX, 18D

                        MOV to, from
                        MOV AX, 18
         con D = Decimal;        H = Hexadecimal    O = Octal     B = Binario

Atributos de distancia de los segmentos
       NEAR: Corresponden a etiquetas o procedimientos definidos en el mismo segmento
       FAR: Corresponden a etiquetas o procedimientos definidos en otro segmento.

         Cuando la referencia es NEAR, el registro IP cambia y si es FAR, IP y CS cambian.

Estructura de un programa
        En el Macroensamblador es posible procesar hasta cuatro tipos de segmentos. El programa
mínimo requiere de dos segmentos: el de código y el de pila (CS, SS), el ensamblador busca la
definición del segmento stack y genera un error, si el usuario olvida incluirlo. El pseudo-operador
SEGMENT del macroensamblador sirve para definir un segmento.

        Los pseudo-operadores son el medio por el que el programador le indica al ensamblador lo que
debe hacer para preparar y estructurar el código en lenguaje de máquina. Este código de máquina está
basado en los datos e interrupciones contenidos en el programa fuente. Los pseudo-operadores no
generan código máquina. Existen cuatro tipos de pseudo-operadores: de datos (SEGMENT es incluido
en este tipo), de ramificación condicional, macros y listados.




                                                                                                     34
Ejemplo de un programa en MASM
     PAGE 50, 132
     TITLE PRUEBA
     COMMENT *
               ELABORADO POR: Sexto semestre de L. C. C. del Centro Escolar Felipe Carrillo Puerto
               FECHA: 1 de marzo de 2005
               DESCRIPCIÓN: Este módulo limpia el contenido del registro AX, dejando ceros. Después coloca en
     AX el valor de 18. Todas las operaciones pueden ser observadas en el debug. *
     ;
     ;
     STACK SEGMENT PARA STACK ‘STACK’
     ;
     ;Se inicializará con cero el segmento del stack y se cargará con una cadena de caracteres: 64
     ;valores de ‘stack ’
     ;
     DB 64 DUP (‘STACK ’)
     STACK ENDS
     CSEG SEGMENT PARA PUBLIC ‘CODE’
                        ASUME CS:CSEG, SS:STACK
     ;
               SUB AX, AX
               MOV AX, 18
               SUB AX, 18
     ;
     CSEG ENDS
               END

        PAGE (pseudo-operador de listado): sirve para definir las dimensiones de la página y solo
tiene efecto cuando se pone en lista el archivo general durante el ensamble.

                                   PAGE operando1, operando2
      donde operando1 indica el número de líneas verticales por página en el listado producido en el
ensamblado (por default 66) y operando2 es el número de caracteres por línea (por default 80).

       TITLE (pseudo-operador de listado): indica el título que será impreso en el encabezado de
cada página de listado generado por el ensamblado.

       ; y COMMENT: El ‘;’ sirve para indicar un comentario de una línea y COMMENT para
indicar comentarios multilínea. Para COMMENT el primer carácter diferente de un espacio se usa
como delimitador; todos los demás caracteres que se encuentren entre los delimitadores son
considerados comentarios y por lo tanto ignorados por el ensamblador.

Parámetros de Pseudo-Op Segment
       SEGMENT: El pseudo-operador SEGMENT tiene el siguiente formato:

                  nombre-seg SEGMENT tipo-alineamiento tipo-combinación ‘clase’

      donde:
      nombre-seg: indica el nombre del segmento
      tipo-alineamiento: señala al ensamblador la manera en la que comenzarán los segmentos en la
memoria. Existen 4 tipos:
            PARA: es el predeterminado e indica que el segmento comienza en los límites de un
              párrafo (dirección divisible por 16)
            BYTE: el segmento puede comenzar en localidad de memoria
            WORD: el segmento debe iniciar en el límite de una palabra (donde la dirección sea par)
            PAGE: el segmento debe iniciar en una página (los últimos 8 bits de la dirección son
              cero)
      tipo-combinación: indica la manera en la que los segmentos serán combinados o cargados
cuando se ejecute el encadenador (linker). Existen 5 formas:



                                                                                                                35
 PUBLIC: todos los segmentos con el mismo nombre y con atributo PUBLIC serán
                  encadenados juntos.
               COMMON: todos los segmentos con el mismo nombre empezarán en la misma
                  dirección y se traslaparán en memoria.
               AT(exp): se utiliza para definir variables con un desplazamiento fijo de memoria. El
                  segmento se coloca en el párrafo indicado por el resultado obtenido después de
                  evaluar “exp”.
               STACK: Sirve Para indicar que el segmento es parte del STACK.
               MEMORY: todos los segmentos de este tipo se colocarán en direcciones de número
                  mayor que cualesquiera otros segmentos.
      ‘clase’: se emplea para hacer referencia a una colección de segmentos. Los segmentos con el
mismo nombre de clase se colocan en memoria secuencial, siguiendo el orden en que los encontró el
encadenador.

       Cada segmento debe terminar con la siguiente sentencia:
                                        nombre-seg ENDS

     DB(pseudo-operador de datos): sirve para definir una variable o para inicializar un área de
memoria (DB = Define Byte). Tiene la siguiente forma:
                                [nombre-variable] DB expresion

       DUP (duplica), en el ejemplo DB 64 DUP (‘stack ’) está inicializando un área de memoria con
64 duplicaciones de ‘stack ’

       [nombre-variable]: es opcional y dependerá su uso si se desea asociar un nombre simbólico con
un valor.

       ASSUME (pseudo-operador de datos): le indica al ensamblador a cuál registro pertenece un
determinado segmento. Tiene la forma
                     ASSUME segmento de registro: nombre de segmento, …




                                                                                                 36
PROGRAMANDO CON EL MASM


       Ya estamos en condiciones de utilizar el ensamblador, este es un programa del DOS que hará
nuestra programación más fácil. De aquí en adelante, escribiremos las instrucciones mnemónicas,
directamente usando el ensamblador, para convertir nuestros programas en código máquina.

UN PROGRAMA SIN EL DEBUG
        Actualmente hemos utilizado el DEBUG, tecleando instrucciones del programa. Ahora
escribiremos los programas sin él, y nosotros tendremos que usar un editor o un procesador de texto
para crear el código, archivos que contienen nuestras instrucciones del lenguaje ensamblador.

      Use el “edit”4 para ingresar las siguientes líneas de código el archivo se llamará
WRITESTR.ASM (la extensión .ASM quiere decir éste es un archivo de origen ensamblador). Así
como con el Debug, puede escribir el código con minúscula o con mayúscula sin embargo nosotros
usaremos las mayúsculas para evitar la confusión entre el número 1 (uno) y la letra minúscula l (ele):
.MODEL SMALL
.CODE
      MOV AH, 02h
      MOV DL,2Ah
      INT    21h
      INT    20h
END

       Ignore por ahora las tres nuevas líneas en nuestro archivo de origen, note que hay un ‘h’
después de cada número hexadecimal. Esta h le indica al ensamblador que los números son en
hexadecimal. DEBUG supone que todos los números son en hexadecimal, en el ensamblador supone
todos los números decimales. Nosotros le indicaremos que será un número hexadecimal poniendo una
h después de cualquier número.

Nota: El ensamblador puede confundirse por los números, por ejemplo, ACh que se parece un nombre
o una instrucción. Para evitar esto, siempre teclee un cero antes, para diferenciar el número
hexadecimal que empieza con una letra. Por ejemplo, no teclee ACh.

       Veamos lo que pasa cuando Ensamblemos un programa con ACh, en lugar de 0ACh. Aquí está
el programa:
.MODEL SMALL
.CODE
      MOV DL,ACh
      INT    20h
END




4
 Sin embargo para facilitar nuestro trabajo usaremos el Programmer’s File Editor, ya que nos proporciona la ventaja de
agregar números de línea que nos ayudará a localizar el número de línea que marque error al momento de compilar.

                                                                                                                   37
Aquí está la salida
A> MASM TEST;
Microsoft (R) Macro Assembler Version 6.11
Copyright (C) Microsoft Corp 1981, 1998. All rights reserved.

test.ASM(4)   :        error A2009: Symbol not defined:         ACH
       49842 + 224473 Bytes symbol-space free
       0 Warning Errors
       1 Severe Errors
A>     .

       Pero cambiando el ACh a 0ACh se soluciona el ensamblador. También note el espacio de los
comandos en nuestro programa ensamblador. Usaremos los tabuladores para alinear y hacer el texto
más legible. Compare el programa en que usted entró con esta versión:

        Ahora regresemos a las 3 líneas nuevas del archivo. Las tres nuevas líneas son todas las
directivas (también llamadas pseudo-ops, o pseudo-operadores). Son llamadas directivas porque, en
lugar de generar instrucciones, proporcionan información y direcciones al ensamblador. El pseudo-op
END marca el fin del archivo, para que el ensamblador sepa qué hacer cuando encuentra un END.
Después, veremos que este END es útil de otras maneras, también. Por ahora, apartemos cualquier
discusión extensa de él o las otras dos directivas y vea cómo usar el ensamblador.

Creando archivos de origen
       Aunque usted ha ingresado las líneas de WRITESTR.ASM, hay una consideración más. El
ensamblador puede usar archivos del origen que sólo contienen los carácteres de ASCII estándares. Si
usted está usando un procesador de texto, tenga en cuenta que no todos los procesadores de texto
guardan los caracteres ASCII estándares.

      Antes de que probemos el archivo WRITESTR.ASM, asegúrese que todavía es ASCII. Haga
Type del DOS:
A>TYPE WRITESTR.ASM

       Debe ver el mismo texto que ingresó. Si ve caracteres extraños en su programa, tendrá que usar
un editor diferente para escribir los programas. Ahora, empecemos a ensamblar Writestr; teclee lo
siguiente:
A>MASM WRITESTR;
Microsoft (R) Macro Assembler
Copyright (C) Microsoft Corp 1981, 1988. A11 rights reserved.

49822 + 219323 Bytes symbol space free

0 Harning Errors
0 Severe Errars

A>

       Nosotros no hacemos nada todavía. El ensamblador ha producido un archivo llamado
WRITESTR.OBJ que usted encontrará ahora en su disco. Éste es un archivo intermedio, llamado
archivo objeto.



                                                                                                  38
Linking
       Ahora queremos que nuestro LINK tome nuestro .OBJ y cree uno .EXE de él. Enlace
WRITESTR.OBJ tecleando:
A>LINK WRITESTR;
Microsoft (R) Overlay Linker
Copyright (C) Microsoft Corp 1963-1988.
All rights reserved. LINK: warning L4021: no stack segment
A>

       Aunque el LINK nos advierte que no hay ningún segmento de la pila, nosotros no necesitamos
uno ahora mismo. Después de que nosotros aprendemos a agregar más instrucciones, veremos porqué
nosotros podríamos querer un segmento de la pila.

       Ahora nosotros guardemos nuestro .EXE, pero este no es el último paso. Nosotros tenemos un
archivo .COM tal y como lo creamos con el DEBUG. De nuevo, se verá después porqué nosotros
necesitamos todos estos pasos. Para ahora, creemos un archivo .COM de Writestr.

        Nosotros necesitamos el programa EXE2BIN.EXE del DOS. Exe2bin, como su nombre lo
indica, convierte un .EXE a .COM, o archivo binario.
A>EXE2BIN WRITESTR WRITESTR.COM
A>

      La contestación no nos dijo mucho. Para ver si Exe2bin trabajó, listemos todo el Writestr
guardados hasta ahora: con DIR WRITESTR.*

Regresando al DEBUG
      Leamos nuestro archivo .COM (o .EXE) en el DEBUG y desensamble para ver cómo el
DEBUG reconstruye nuestro programa en código-máquina de WRITESTR.COM
A>DEBUG WRITESTR.COM
_U
397F:0100 8402    MOV AH, 02
397F:0102 822A    MOV DL, 2A
397F:0104 CD21    INT 21
397F:0106 CD20    INT 20

Los comentarios
       En los programas del lenguaje ensamblador, nosotros ponemos los comentarios después de un
punto y coma El ensamblador ignora algo en la línea después de un punto y coma, para que nosotros
podemos agregar algo que nosotros queremos.
.MODEL SMALL
.CODE
      MOV AH, 2h ;Selecciona la función 2 de DOS para sacar un caracter
      MOV DL, 2Ah ;Carga el código ASCII a ser impreso
      INT    21h ;Imprime con la NT 21h
      INT    20h ;y Sale del DOS
      END

Las etiquetas
        Cuando quisimos bifurcar (saltar) en una parte del programa a otro con uno de los comandos de
la bifurcación (JNZ, JLE, etc), nosotros teníamos que saber la dirección específica nosotros estábamos
saltando a. Cada vez que programábamos, insertábamos nuevas instrucciones obligando a que

                                                                                                   39
cambiemos las direcciones en las instrucciones de salto. El ensamblador cuida de este problema con
nombres de etiqueta que nosotros damos a las direcciones de cualquier instrucción o situaciones de la
memoria. Una etiqueta tiene lugar. En cuanto el ensamblador vea una etiqueta, reemplaza la etiqueta
con la dirección correcta antes de enviarlo delante del microprocesador.

        Las etiquetas pueden ser de hasta 31 caracteres y puede contener letras, números, y algunos de
los siguientes símbolos: un signo de interrogación (?), un punto (.), una arroba ( @ ) un guión bajo ( _ )
o un signo de peso ( $ ). Sin embargo no puede empezar con un dígito (0-9) y el punto puede ser usado
solamente como el primer carácter.

Ejemplo:
                                              0111
                                  010C   JLE DIGIT1
                                  010E   SUB DL
                   DIGIT1:        0111   MOV CL
                                  0113   SHL DL,1

       Tomemos como ejemplo práctico el código empleado para leer 2 dígitos hexadecimales.
       0100           MOV AH, 01h
       0102           INT 21
       0104           MOV DL, AL
       0106           SUB DL, 30h
       0109           CMP DL, 09h
       010C           JLE Salto1
       010E           SUB DL, 07h
       0111           MOV CL, 04h
       0113           SHL DL, CL
       0115           INT 21
       0117           SUB AL, 30
       0119           CMP AL, 09h
       011B           JLE Salto2
       011D           SUB AL, 07h
       011F           ADD DL, AL
       0121           INT 20

        No será obvio lo que este programa hace, y si no está fresco en su mente, usted puede tener que
trabajar un poco para entender el programa de nuevo. Agreguemos etiquetas y comentarios para
clarificar su función:
.MODEL SMALL
.CODE
                      MOV AH, 01h    ;Seleccione la función 1 del DOS, para introducir un carcater
                      INT 21         ;Lee un caracter, y retorna el código ASCII en el registro AL
                      MOV DL, AL     ;Mueve el código ASCII dentro de DL
                      SUB DL, 30h    ;Resta 30H para convertirlo en digito de 0 a 9
                      CMP DL, 09h    ;Está el dígito entre 0 y 9?
                      JLE Salto1     ;Si, entonces tenemos el primer dígito
                      SUB DL, 07h    ;No, Resta 7H para convertirlo en letra de la A a la F
       Salto1:        MOV CL, 04h    ;Prepara para multiplicar por 16
                      SHL DL, CL     ;Realiza el corrimiento hacia la izquierda
                      INT 21         ;Solicita el siguiente caracter
                      SUB AL, 30     ;Repite la operación
                      CMP AL, 09h    ;Es un dígito de 0-9?
                      JLE Salto2     ;Si, tenemos el segundo dígito


                                                                                                       40
SUB AL, 07h   ;No, restamos 7H
       Salto2:       ADD DL, AL    ;Agregamos el segundo dígito
                     INT 20        ;Finalizamos

                     END

      Las etiquetas, SALTO1 y SALTO2, son de un tipo conocido como Etiquetas Cercanas (NEAR),
porque los dos puntos (:) aparecen después de las etiquetas cuando ellos están definidos. El término
NEAR tiene que ver con segmentos que nosotros hablaremos más adelante junto con las directivas
.MODEL, y .CODE. Si ensambla el programa y lo desensambla con el DEBUG, verá que SALTO1 se
reemplazó por 0111h y SALTO2 se reemplazó por 011Fh.




                                                                                                 41
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador
Temario lenguaje ensamblador

More Related Content

What's hot

Sensores opticos -MECATRONICA
Sensores opticos -MECATRONICASensores opticos -MECATRONICA
Sensores opticos -MECATRONICArkohafc
 
135127015 microcontroladores-1-1-ppt
135127015 microcontroladores-1-1-ppt135127015 microcontroladores-1-1-ppt
135127015 microcontroladores-1-1-pptCarlos Martir
 
Acceso de Red del Modelo TCP/IP
Acceso de Red del Modelo TCP/IPAcceso de Red del Modelo TCP/IP
Acceso de Red del Modelo TCP/IPWendy Leyva
 
Microcontroladores AVR
Microcontroladores AVRMicrocontroladores AVR
Microcontroladores AVRabemen
 
Registros del procesador 01
Registros del procesador 01Registros del procesador 01
Registros del procesador 01Isaias Castro
 
Unidad 2 ensamblador
Unidad 2   ensambladorUnidad 2   ensamblador
Unidad 2 ensambladoreveTalavera
 
Informe practica #1 23 06-17
Informe practica #1 23 06-17Informe practica #1 23 06-17
Informe practica #1 23 06-17Zambrano Daniel
 
codificaciones unipolar, polar, bipolar
codificaciones unipolar, polar, bipolarcodificaciones unipolar, polar, bipolar
codificaciones unipolar, polar, bipolarthejp
 
Transistor como interruptor
Transistor como interruptorTransistor como interruptor
Transistor como interruptorRogelio Beltrán
 
Origen del Modelo OSI y su impacto en als estructuras de redes
Origen del Modelo OSI y su impacto en als estructuras de redesOrigen del Modelo OSI y su impacto en als estructuras de redes
Origen del Modelo OSI y su impacto en als estructuras de redesKim Sorel Rush
 

What's hot (20)

Taller de Base de Datos - Unidad 7 Conectividad
Taller de Base de Datos - Unidad 7 ConectividadTaller de Base de Datos - Unidad 7 Conectividad
Taller de Base de Datos - Unidad 7 Conectividad
 
04.Entradas y salidas digitales
04.Entradas y salidas digitales04.Entradas y salidas digitales
04.Entradas y salidas digitales
 
Programación de microcontroladores
Programación de microcontroladoresProgramación de microcontroladores
Programación de microcontroladores
 
Sensores opticos -MECATRONICA
Sensores opticos -MECATRONICASensores opticos -MECATRONICA
Sensores opticos -MECATRONICA
 
135127015 microcontroladores-1-1-ppt
135127015 microcontroladores-1-1-ppt135127015 microcontroladores-1-1-ppt
135127015 microcontroladores-1-1-ppt
 
Analisis lexico automatas i
Analisis lexico automatas iAnalisis lexico automatas i
Analisis lexico automatas i
 
UNIDAD 2 PROGRAMACIÓN BASICA
UNIDAD 2 PROGRAMACIÓN BASICAUNIDAD 2 PROGRAMACIÓN BASICA
UNIDAD 2 PROGRAMACIÓN BASICA
 
Acceso de Red del Modelo TCP/IP
Acceso de Red del Modelo TCP/IPAcceso de Red del Modelo TCP/IP
Acceso de Red del Modelo TCP/IP
 
Microcontroladores AVR
Microcontroladores AVRMicrocontroladores AVR
Microcontroladores AVR
 
Registros del procesador 01
Registros del procesador 01Registros del procesador 01
Registros del procesador 01
 
Unidad 2 ensamblador
Unidad 2   ensambladorUnidad 2   ensamblador
Unidad 2 ensamblador
 
Informe practica #1 23 06-17
Informe practica #1 23 06-17Informe practica #1 23 06-17
Informe practica #1 23 06-17
 
Final1 tomasi
Final1 tomasiFinal1 tomasi
Final1 tomasi
 
Direccionamiento
DireccionamientoDireccionamiento
Direccionamiento
 
RS422 y RS495
RS422 y RS495RS422 y RS495
RS422 y RS495
 
Bios
BiosBios
Bios
 
codificaciones unipolar, polar, bipolar
codificaciones unipolar, polar, bipolarcodificaciones unipolar, polar, bipolar
codificaciones unipolar, polar, bipolar
 
Transistor como interruptor
Transistor como interruptorTransistor como interruptor
Transistor como interruptor
 
Origen del Modelo OSI y su impacto en als estructuras de redes
Origen del Modelo OSI y su impacto en als estructuras de redesOrigen del Modelo OSI y su impacto en als estructuras de redes
Origen del Modelo OSI y su impacto en als estructuras de redes
 
U2S2: Memoria Principal (RAM)
U2S2: Memoria Principal (RAM)U2S2: Memoria Principal (RAM)
U2S2: Memoria Principal (RAM)
 

Viewers also liked

Lenguaje Ensamblador
Lenguaje EnsambladorLenguaje Ensamblador
Lenguaje Ensambladorgbermeo
 
Lenguaje ensamblador del microprocesador
Lenguaje ensamblador del microprocesadorLenguaje ensamblador del microprocesador
Lenguaje ensamblador del microprocesadorsmfch
 
Lenguaje ensamblador basico
Lenguaje ensamblador basicoLenguaje ensamblador basico
Lenguaje ensamblador basicoGustavo Davila
 
Sesion 1 atmega8
Sesion 1 atmega8Sesion 1 atmega8
Sesion 1 atmega8davidepn2
 
The EMAIL MARKETINGscape
 The EMAIL MARKETINGscape The EMAIL MARKETINGscape
The EMAIL MARKETINGscapeFluent, Inc
 
summer startup school
summer startup schoolsummer startup school
summer startup schoolr_castellanos
 
Proyecto final
Proyecto final Proyecto final
Proyecto final rlunab
 
ударение и интонация в немецком языке
ударение и интонация в немецком языкеударение и интонация в немецком языке
ударение и интонация в немецком языкеKirrrr123
 
Victoria Hill Midterm Reflection
Victoria Hill Midterm ReflectionVictoria Hill Midterm Reflection
Victoria Hill Midterm ReflectionVictoriaBHill
 
Como empezar a pescar con mosca 01 pesca
Como empezar a pescar con mosca 01   pescaComo empezar a pescar con mosca 01   pesca
Como empezar a pescar con mosca 01 pescaDemi Pank
 
Next-Gen уже здесь
Next-Gen уже здесьNext-Gen уже здесь
Next-Gen уже здесьCEE-SEC(R)
 
The Importance of Multi-Channel Contact and Social Media to the Customer Expe...
The Importance of Multi-Channel Contact and Social Media to the Customer Expe...The Importance of Multi-Channel Contact and Social Media to the Customer Expe...
The Importance of Multi-Channel Contact and Social Media to the Customer Expe...RightNow Technologies
 
Programa en emu8086
Programa en emu8086Programa en emu8086
Programa en emu8086Fredy Soncco
 

Viewers also liked (20)

Lenguaje Ensamblador
Lenguaje EnsambladorLenguaje Ensamblador
Lenguaje Ensamblador
 
Lenguaje ensamblador
Lenguaje ensambladorLenguaje ensamblador
Lenguaje ensamblador
 
Lenguaje ensamblador del microprocesador
Lenguaje ensamblador del microprocesadorLenguaje ensamblador del microprocesador
Lenguaje ensamblador del microprocesador
 
Emulador 8086.
Emulador 8086.Emulador 8086.
Emulador 8086.
 
Div, idiv, Neg ensamblador
Div, idiv, Neg ensambladorDiv, idiv, Neg ensamblador
Div, idiv, Neg ensamblador
 
Lenguaje ensamblador basico
Lenguaje ensamblador basicoLenguaje ensamblador basico
Lenguaje ensamblador basico
 
Lenguaje Ensamblador
Lenguaje EnsambladorLenguaje Ensamblador
Lenguaje Ensamblador
 
Sesion 1 atmega8
Sesion 1 atmega8Sesion 1 atmega8
Sesion 1 atmega8
 
Boletin 80, Octubre 2012 - Programa Educativo PROEDUCAR SOLACI
Boletin 80, Octubre 2012 - Programa Educativo PROEDUCAR SOLACIBoletin 80, Octubre 2012 - Programa Educativo PROEDUCAR SOLACI
Boletin 80, Octubre 2012 - Programa Educativo PROEDUCAR SOLACI
 
The EMAIL MARKETINGscape
 The EMAIL MARKETINGscape The EMAIL MARKETINGscape
The EMAIL MARKETINGscape
 
summer startup school
summer startup schoolsummer startup school
summer startup school
 
Proyecto final
Proyecto final Proyecto final
Proyecto final
 
ударение и интонация в немецком языке
ударение и интонация в немецком языкеударение и интонация в немецком языке
ударение и интонация в немецком языке
 
Victoria Hill Midterm Reflection
Victoria Hill Midterm ReflectionVictoria Hill Midterm Reflection
Victoria Hill Midterm Reflection
 
Como empezar a pescar con mosca 01 pesca
Como empezar a pescar con mosca 01   pescaComo empezar a pescar con mosca 01   pesca
Como empezar a pescar con mosca 01 pesca
 
Next-Gen уже здесь
Next-Gen уже здесьNext-Gen уже здесь
Next-Gen уже здесь
 
The Importance of Multi-Channel Contact and Social Media to the Customer Expe...
The Importance of Multi-Channel Contact and Social Media to the Customer Expe...The Importance of Multi-Channel Contact and Social Media to the Customer Expe...
The Importance of Multi-Channel Contact and Social Media to the Customer Expe...
 
Programa en emu8086
Programa en emu8086Programa en emu8086
Programa en emu8086
 
Tutorial ensamblador
Tutorial ensambladorTutorial ensamblador
Tutorial ensamblador
 
Codigo Hamming
Codigo HammingCodigo Hamming
Codigo Hamming
 

Similar to Temario lenguaje ensamblador

Programacion ensamblador-procesadoresk
Programacion ensamblador-procesadoreskProgramacion ensamblador-procesadoresk
Programacion ensamblador-procesadoreskJohann Chambilla
 
Ensamblador
EnsambladorEnsamblador
EnsambladorCEUNISAL
 
Aprenda C++ como si estuviera en primero
Aprenda C++ como si estuviera en primeroAprenda C++ como si estuviera en primero
Aprenda C++ como si estuviera en primeroAndy Juan Sarango Veliz
 
programacion c++ basico
programacion c++  basicoprogramacion c++  basico
programacion c++ basicoLoyda PM
 
Fundamentos y Lógica de Programación
Fundamentos y Lógica de ProgramaciónFundamentos y Lógica de Programación
Fundamentos y Lógica de ProgramaciónTensor
 
estructuras básicas.docx
estructuras básicas.docxestructuras básicas.docx
estructuras básicas.docxSofiaA30
 
Programación Y Simulación De Robot SCARA, documento
Programación Y Simulación De Robot SCARA, documentoProgramación Y Simulación De Robot SCARA, documento
Programación Y Simulación De Robot SCARA, documentoBronson Duhart
 
Programacion i ing civil
Programacion i ing civilProgramacion i ing civil
Programacion i ing civilAugusto
 
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN.pdf
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN.pdfESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN.pdf
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN.pdfMariannaGutierrezGom
 
ESTRUCTURAS BÁSICAS- CONCEPTOS BÁSICOS DE PROGRAMACIÓN-1.pdf
ESTRUCTURAS BÁSICAS- CONCEPTOS BÁSICOS DE PROGRAMACIÓN-1.pdfESTRUCTURAS BÁSICAS- CONCEPTOS BÁSICOS DE PROGRAMACIÓN-1.pdf
ESTRUCTURAS BÁSICAS- CONCEPTOS BÁSICOS DE PROGRAMACIÓN-1.pdfjuanisvelez2
 
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN (1).pdf
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN (1).pdfESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN (1).pdf
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN (1).pdfMariannaGutierrezGom
 
Construcci__n_de_Compiladores_Principios_y_Pr__ctica__1ra_Edicion__Kenneth_Lo...
Construcci__n_de_Compiladores_Principios_y_Pr__ctica__1ra_Edicion__Kenneth_Lo...Construcci__n_de_Compiladores_Principios_y_Pr__ctica__1ra_Edicion__Kenneth_Lo...
Construcci__n_de_Compiladores_Principios_y_Pr__ctica__1ra_Edicion__Kenneth_Lo...Claudia Naveda
 

Similar to Temario lenguaje ensamblador (20)

Programacion ensamblador-procesadoresk
Programacion ensamblador-procesadoreskProgramacion ensamblador-procesadoresk
Programacion ensamblador-procesadoresk
 
Ensamblador
EnsambladorEnsamblador
Ensamblador
 
Proyecto fernando compiladores 1
Proyecto fernando compiladores 1Proyecto fernando compiladores 1
Proyecto fernando compiladores 1
 
Programacion micros
Programacion microsProgramacion micros
Programacion micros
 
Cppbasico
CppbasicoCppbasico
Cppbasico
 
Tutorial de C
Tutorial de CTutorial de C
Tutorial de C
 
Aprenda C++ como si estuviera en primero
Aprenda C++ como si estuviera en primeroAprenda C++ como si estuviera en primero
Aprenda C++ como si estuviera en primero
 
C++ basico subido JHS
C++ basico subido JHSC++ basico subido JHS
C++ basico subido JHS
 
Cppbasico
CppbasicoCppbasico
Cppbasico
 
Tutorial de c++
Tutorial de c++Tutorial de c++
Tutorial de c++
 
programacion c++ basico
programacion c++  basicoprogramacion c++  basico
programacion c++ basico
 
Fundamentos y Lógica de Programación
Fundamentos y Lógica de ProgramaciónFundamentos y Lógica de Programación
Fundamentos y Lógica de Programación
 
estructuras básicas.docx
estructuras básicas.docxestructuras básicas.docx
estructuras básicas.docx
 
Programación Y Simulación De Robot SCARA, documento
Programación Y Simulación De Robot SCARA, documentoProgramación Y Simulación De Robot SCARA, documento
Programación Y Simulación De Robot SCARA, documento
 
Septimo ciclo
Septimo cicloSeptimo ciclo
Septimo ciclo
 
Programacion i ing civil
Programacion i ing civilProgramacion i ing civil
Programacion i ing civil
 
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN.pdf
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN.pdfESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN.pdf
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN.pdf
 
ESTRUCTURAS BÁSICAS- CONCEPTOS BÁSICOS DE PROGRAMACIÓN-1.pdf
ESTRUCTURAS BÁSICAS- CONCEPTOS BÁSICOS DE PROGRAMACIÓN-1.pdfESTRUCTURAS BÁSICAS- CONCEPTOS BÁSICOS DE PROGRAMACIÓN-1.pdf
ESTRUCTURAS BÁSICAS- CONCEPTOS BÁSICOS DE PROGRAMACIÓN-1.pdf
 
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN (1).pdf
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN (1).pdfESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN (1).pdf
ESTRUCTURAS BÁSICAS_ CONCEPTOS BÁSICOS DE PROGRAMACIÓN (1).pdf
 
Construcci__n_de_Compiladores_Principios_y_Pr__ctica__1ra_Edicion__Kenneth_Lo...
Construcci__n_de_Compiladores_Principios_y_Pr__ctica__1ra_Edicion__Kenneth_Lo...Construcci__n_de_Compiladores_Principios_y_Pr__ctica__1ra_Edicion__Kenneth_Lo...
Construcci__n_de_Compiladores_Principios_y_Pr__ctica__1ra_Edicion__Kenneth_Lo...
 

Recently uploaded

La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafiosFundación YOD YOD
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx241523733
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.241514949
 
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfSergioMendoza354770
 
Plan Sarmiento - Netbook del GCBA 2019..
Plan Sarmiento - Netbook del GCBA 2019..Plan Sarmiento - Netbook del GCBA 2019..
Plan Sarmiento - Netbook del GCBA 2019..RobertoGumucio2
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxJOSEFERNANDOARENASCA
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA241531640
 
Mapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptxMapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptxMidwarHenryLOZAFLORE
 
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptxLAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptxAlexander López
 
FloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptxFloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptx241522327
 
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptxEl_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptxAlexander López
 
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxCrear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxNombre Apellidos
 
definicion segun autores de matemáticas educativa
definicion segun autores de matemáticas  educativadefinicion segun autores de matemáticas  educativa
definicion segun autores de matemáticas educativaAdrianaMartnez618894
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadMiguelAngelVillanuev48
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxaylincamaho
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaarkananubis
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELmaryfer27m
 
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptxGoogle-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptxAlexander López
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptMiguelAtencio10
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxazmysanros90
 

Recently uploaded (20)

La era de la educación digital y sus desafios
La era de la educación digital y sus desafiosLa era de la educación digital y sus desafios
La era de la educación digital y sus desafios
 
GonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptxGonzalezGonzalez_Karina_M1S3AI6... .pptx
GonzalezGonzalez_Karina_M1S3AI6... .pptx
 
El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.El uso de las TIC's en la vida cotidiana.
El uso de las TIC's en la vida cotidiana.
 
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdfPARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
PARTES DE UN OSCILOSCOPIO ANALOGICO .pdf
 
Plan Sarmiento - Netbook del GCBA 2019..
Plan Sarmiento - Netbook del GCBA 2019..Plan Sarmiento - Netbook del GCBA 2019..
Plan Sarmiento - Netbook del GCBA 2019..
 
Arenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptxArenas Camacho-Practica tarea Sesión 12.pptx
Arenas Camacho-Practica tarea Sesión 12.pptx
 
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6    CREAR UN RECURSO MULTIMEDIAActividad integradora 6    CREAR UN RECURSO MULTIMEDIA
Actividad integradora 6 CREAR UN RECURSO MULTIMEDIA
 
Mapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptxMapa-conceptual-del-Origen-del-Universo-3.pptx
Mapa-conceptual-del-Origen-del-Universo-3.pptx
 
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptxLAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
LAS_TIC_COMO_HERRAMIENTAS_EN_LA_INVESTIGACIÓN.pptx
 
FloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptxFloresMorales_Montserrath_M1S3AI6 (1).pptx
FloresMorales_Montserrath_M1S3AI6 (1).pptx
 
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptxEl_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
El_Blog_como_herramienta_de_publicacion_y_consulta_de_investigacion.pptx
 
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptxCrear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
Crear un recurso multimedia. Maricela_Ponce_DomingoM1S3AI6-1.pptx
 
definicion segun autores de matemáticas educativa
definicion segun autores de matemáticas  educativadefinicion segun autores de matemáticas  educativa
definicion segun autores de matemáticas educativa
 
Presentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidadPresentación inteligencia artificial en la actualidad
Presentación inteligencia artificial en la actualidad
 
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptxMedidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
Medidas de formas, coeficiente de asimetría y coeficiente de curtosis.pptx
 
R1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en minaR1600G CAT Variables de cargadores en mina
R1600G CAT Variables de cargadores en mina
 
El uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFELEl uso delas tic en la vida cotidiana MFEL
El uso delas tic en la vida cotidiana MFEL
 
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptxGoogle-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
Google-Meet-como-herramienta-para-realizar-reuniones-virtuales.pptx
 
dokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.pptdokumen.tips_36274588-sistema-heui-eui.ppt
dokumen.tips_36274588-sistema-heui-eui.ppt
 
tics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptxtics en la vida cotidiana prepa en linea modulo 1.pptx
tics en la vida cotidiana prepa en linea modulo 1.pptx
 

Temario lenguaje ensamblador

  • 1. Centro Escolar “Felipe Carrillo Puerto” Licenciatura en Ciencias Computacionales MATERIA: LENGUAJE ENSAMBLADOR NIVEL: SEXTO SEMESTRE PROFESOR: L. C. C. MIGUEL ANGEL SUASTE ESCALANTE SEMESTRE: FEBRERO-JULIO DEL 2008 HORARIO: Martes y Jueves de 8:00-9:30 Objetivo General: Al finalizar el curso el alumno podrá aplicar los conceptos y características sobre la arquitectura de una computadora para elaborar y depurar programas escritos en lenguaje ensamblador. Criterios de Evaluación: 1er. Bimestre 2º. Bimestre Ordinario Criterio de Evaluación Puntos Criterio de Evaluación Puntos Criterio de Evaluación Puntos Examen escrito 15 Examen escrito 15 Examen escrito 15 Participación 5 Participación 5 Participación NA Trabajos y/o proyectos 5 Trabajos y/o proyectos 5 Trabajos y/o proyectos 15 Tareas o ensayos 10 Tareas o ensayos 10 Tareas o ensayos NA Exposiciones de trabajo NA Exposiciones de trabajo NA Exposiciones de trabajo NA Otros NA Otros NA Otros NA Total 35 Total 35 Total 30 Fechas de Evaluaciones Primer Parcial: Segundo Parcial: CONTENIDO 1. FUNDAMENTOS DE LA PROGRAMACIÓN EN ENSAMBLADOR El alumno comprenderá y aplicará los conceptos relacionados con la estructura de las computadoras y el Lenguaje Ensamblador. 1.1. La familia de computadoras IBM 1.2. Macroensamblador 1.3. Ventajas que se obtienen al aprender un Lenguaje Ensamblador 1.4. Sistemas Numéricos 1.4.1.Numeración binaria 1.4.2.Bits, nibbles, Bytes y Words 1.4.3.Representación de enteros 1.4.3.1.Magnitud con signo 1.4.3.2.Complemento a uno 1.4.3.3.Complemento a dos 1.4.3.4.Exceso 2n-1 1.4.4.Representación de punto flotante 1.4.4.1.Representación de números de punto flotante en la PDP-11 e IBM 1.4.4.2.Bit Escondido 1.5. El Debug
  • 2. Centro Escolar “Felipe Carrillo Puerto” Licenciatura en Ciencias Computacionales 2. INTRODUCCIÓN A LA PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR El alumno conocerá cómo representa la computadora de manera interna los datos e instrucciones que procesa mediante el debug. 2.1. El Debug y su uso 2.2. Aritmética del 8088/80286/80386 mediante el DEBUG 2.2.1.Registros como variables 2.2.2.Memoria del Procesador 2.2.3.Estilos de adición y resta 2.2.4.Números negativos 2.2.5.Multiplicación y división 2.3. Imprimiendo caracteres 2.3.1.INT 21h: El poder de las interrupciones 2.3.2.INT 20h: una salida con gracia 2.3.3.Programas enteros 2.3.4.Moviendo datos entre registros 2.3.5.Escribiendo strings de caracteres 2.4. Registro de Banderas 2.5. Imprimiendo números binarios 2.5.1.Banderas de acarreo y rotación 2.5.2.Adición con la bandera de acarreo 2.5.3.Looping 2.5.4.Escribiendo números binarios 2.6. Imprimiendo en hexadecimal 2.6.1.Comparando y status de bits 2.6.2.Imprimiendo un dígito en hexadecimal 2.7. Leyendo caracteres 2.7.1.Leyendo un caracter 2.7.2.Leyendo un número hexadecimal 2.7.3.Leyendo dos dígitos hexadecimales 2.8. Procedimientos y pilas 2.8.1.La pila y direcciones de retorno 2.8.2.Leyendo números en hexadecimal 2.8.3.Etiquetas 3. PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR El alumno programará en Lenguaje Ensamblador para trabajar a bajo nivel en la computadora y desarrollará diversas aplicaciones. 3.1. Proceso de Ensamble 3.2. Rutinas utilizadas en el Ensamblador 3.3. Tipos de Instrucciones en Lenguaje Ensamblador 3.4. Instrucciones en Macroensamblador 3.5. Estructura de un programa 3.6. Parámetros de Pseudo-Op Segment 3.7. Programando con el MASM 3.8. Modos de Direccionamiento 3.9. Los Procedimientos y el Ensamblador
  • 3. Centro Escolar “Felipe Carrillo Puerto” Licenciatura en Ciencias Computacionales 3.10.Imprimiendo en Decimal 3.11.Segmentos y Desplazamientos 3.12.Mapa de la memoria RAM 3.13.Segmentos 3.13.1.Seccionando la memoria del Microprocesador 3.13.2.La Pila 3.13.3.El priefijo del Segmento de Programa (PSP o Scratch área) 3.13.4.La directiva DOSSEG 3.13.5.Llamadas (NEAR y FAR) 3.13.6.Vector de Interrupciones 3.14.Vaciando la memoria 3.14.1.Instrucción group 3.14.2.Rutinas varias
  • 4. Centro Escolar “Felipe Carrillo Puerto” Licenciatura en Ciencias Computacionales 3.15.Diseño de software 3.16.Instrucciones de control 3.16.1.Instrucciones de salto 3.16.2.Instrucciones de comparación 3.17.Optimización del diseño 3.17.1.Programación modular 3.17.2.Diseño descendente 3.18.Diagramas de flujo y pseudocódigo 3.19.Enfoque a la programación estructurada 3.20.Estilo y forma 3.21.Instrucciones de uso más frecuentes 3.21.1.Instrucciones aritméticas 3.21.2.Instrucciones de transferencia 3.21.3.Instrucciones de carga 3.21.4.Instrucciones Loop 3.21.5.Instrucciones de Stack 3.21.6.Instrucciones de conteo 3.21.7.Otras instrucciones 3.21.8.Instrucciones de corrimiento 3.21.9.Instrucciones de rotación 3.21.10.Instrucciones de almacenamiento 3.21.11.Instrucciones de manejo de cadenas 3.21.12.Instrucciones de conversión 3.21.13.Instrucciones de procedimiento y control 3.21.14.instrucciones ASCII 3.21.15.instrucciones de aritmética decimal 3.21.16.Instrucciones de I/O 3.21.17.Instrucciones diversas 3.22.Ejemplos y ejercicios de programación. Bibliografía 1. Lenguaje ensamblador para Microcomputadores IBM para principiantes y avanzados; J. Terry Godfrey; Prentice Hall; 1991 2. System Programming; J. J. Donovan; Mc Graw-Hill 3. Fundamental Concepto of Programming Systems; Jefrey D. Ullman; Addisson- Wesley
  • 5. FUNDAMENTOS DE LA PROGRAMACIÓN EN ENSAMBLADOR El alumno comprenderá y aplicará los conceptos relacionados con la estructura de las computadoras y el Lenguaje Ensamblador. Introducción ¿Qué es el Lenguaje Ensamblador? Es un lenguaje de bajo nivel que traduce instrucciones en lenguaje máquina1. Este utiliza nemotécnicos (abreviaturas) que representan operaciones, nombres simbólicos, operadores y símbolos especiales. Entonces, ¿Por que estudiar el Lenguaje Ensamblador si existen Lenguajes de Alto Nivel? La importancia del Lenguaje ensamblador es que trabaja directamente con el microprocesador. Los programadores que emplean lenguajes de alto nivel para desarrollar aplicaciones donde el tiempo no es un factor crítico o que hacen uso de dispositivos estándar de entrada/salida (I/O), rara vez necesitan llamar rutinas que no formen parte de la librería del compilador. En otras palabras, las necesidades de programar en lenguaje ensamblador en este tipo de aplicaciones, son mínimas. Sin embargo, alguien debe escribir las rutinas de librería que estos programadores emplean, con el fin de obtener la interfaz estándar. Estas rutinas forman la parte no transportable del lenguaje que utilizan y están escritas en lenguaje ensamblador. La familia de computadoras IBM En el presente curso se estudiará la programación en ensamblador basado en el ambiente del sistema de la computadora personal IBM debido a que: 1. Está bien definida la descripción de las interfaces del Hw. en el BIOS, tales como interrupciones, rutinas de servicio, diagramas. 2. Arquitectura del sistema claramente delineada. 3. La presentación en pantalla es buena para el desarrollo de programas. 4. Amplio soporte de Sw. 5. El desarrollo de código es una tarea que se facilita, debido a: a. Énfasis en el teclado y su sintaxis I/O b. Líneas de 80 caracteres c. I/O orientado a textos d. Editores bien desarrollados e. Depuradores bien desarrollados f. Enlazadores y ensambladores bien desarrollados g. BIOS bien documentado. 6. Finalmente, el ambiente de IBM ofrece compatibilidad con otros modelos; por tanto, la experiencia y habilidad ganadas por el usuario aumentarán continuamente. IBM desarrolló un conjunto de microcomputadoras basados en los microprocesadores 8088, 8086, 80286 y 80386 fabricados por INTEL, los tres primeros de 16 bits (es decir, tiene registros internos de 16 bits) y el último de 32 bits. 1 El Lenguaje de Máquina son aquellas instrucciones que son directamente entendidas por lo computadora y no necesitan traducción posterior para que la CPU pueda comprender y ejecutar el programa. Dichas instrucciones se expresan con bits. 1
  • 6. Los microprocesadores 8088 y 8086 se programan con un conjunto básico de instrucciones que son la base de la versión 1.0 de macroensamblador (que emplea un modelo de memoria pequeña). El 80286 se programa en uno de dos modos posibles: el modo de direcciones reales o el modo de direcciones virtuales (o modo protegido). Todo el código desarrollado para el 8088 y 8086 se ejecuta en el primero modo. De manera similar todo el código, salvo para unas instrucciones específicas desarrollado para el 80286 en el modo de direcciones reales será ejecutado sin ningún problema, tanto en el 8088 como en el 8086, La versión 2.0 del macroensamblador incluye también instrucciones específicas del 80286, 8087 y 80287. En modo protegido el 80286 es muy diferente del 8088 y 80286. En este modo existen instrucciones orientadas a soportes de sistemas que no están disponibles en las versiones 1.0 y 2.0 del macroensamblador. Además, estas instrucciones no están diseñadas para que el programador de aplicaciones haga uso de ellas ya que proporcionan funciones para el manejo de memoria y multitarea. El 80386 tiene muchas instrucciones que son iguales al 80286 tanto en direcciones reales como en modo protegido. Además, el 80386 tiene un modo virtual para el 8086 que permite ejecutar los programas desarrollados para este microprocesador en el ambiente multitarea. Registros del INTEL 8088/8086 y el 80286 Registros Descripción AX (AH, AL) Registro del acumulador BX (BH, BL) Registro de base CX (CH, CL) Registro para conteo DX (DH, DL) Registro de datos SP Registro apuntador de pila BP Registro apuntador de base SI Registro de índice de fuente DI Registro de índice de destino CS Registro de segmento de código DS Registro de segmento de datos SS Registro de segmento de pila ES Registro de segmento extra IP Apuntador de instrucciones FLAGS Registro de estado de banderas El INTEL 80386/80486 tienen 14 registros de propósito general, un apuntador de instrucciones EIP y un registros de banderas EFLAGS. 2
  • 7. Registros del INTEL 80386/80486 Registros Descripción EAX (AH, AL) Registro del acumulador (32 bits) EBX (BH, BL) Registro de base (32 bits) ECX (CH, CL) Registro para conteo (32 bits) EDX (DH, DL) Registro de datos (32 bits) ESP Registro apuntador de pila (32 bits) EBP Registro apuntador de base (32 bits) ESI Registro de índice de fuente (32 bits) EDI Registro de índice de destino (32 bits) ECS Registro de segmento de código (16 bits) EDS Registro de segmento de datos (16 bits) ESS Registro de segmento de pila (16 bits) EES Registro de segmento extra (16 bits) EIP Apuntador de instrucciones (16 bits) EFLAGS Registro de estado de banderas (16 bits) |31 16|15 8|7 |0 AH AL EAX AX Macroensamblador El macroensamblador es un programa de computadora que traduce programas escritos en ensamblador en instrucciones en lenguaje máquina. Es un programa muy específico que guarda estrecha relación con la arquitectura del Hw específico de cada computadora. En la CPU’s de las computadoras personales se conectan circuitos electrónicos de memoria de propósito general para formar registros. Los registros son dispositivos (circuitos) de memoria muy sencillos ubicados dentro del microprocesador. El trabajo del macroensamblador es traducir las instrucciones en series de 1 y 0’s que causan que el contenido de los registros sean manejados de manera correcta. Ejemplos de Ensamblador:  MACRO (PDP-11)  COMPASS (CYBER)  ZILOGZ-80 (RADIO SHACK)  MACROENSAMBLADOR (INTEL)  IBM MACRO ASSEMBLER  MICROSOFT MACROASSEMBLER, TURBO, EDITASAM ASSEMBLER Ejemplo de instrucciones en Ensamblador: a) SUB AX, BX ;Se resta a AX el Valor de BX b) MOV AX, BAM[4] Las ligas a continuación, muestra la forma en que se programaba en ensamblador usando una PDP-11: • Parte 1 (http://www.youtube.com/watch?v=XV-7J5y1TQc&feature=related) • Parte 2 (http://www.youtube.com/watch?v=7zaaD_xP6nU&feature=related) • Parte 3 (http://www.youtube.com/watch?v=xiE2QldpQRQ&feature=related) • Parte 4 (http://www.youtube.com/watch?v=NUSn59iY8U8&feature=related) 3
  • 8. En el macroensamblador de IBM las instrucciones no ejecutables que se emplean para estructurar el código fuente toma la forma de pseudoperaciones, el ensamblador permite que un programa que se ejecute en una CPU 8086, 8088 u 80286 haga uso de 4 tipos de segmentos: el de código, de datos, de pila y uno mas de datos o segmento extra de código. El 80386 y el 80486 tiene dos segmentos adicionales de datos que fueron añadidos para la congestión de registro ES y para mejorar la coincidencia de los registros índice y base disponibles en el conjunto general de registros, estos segmentos son FS y GS. Los programas con extensión .EXE pueden ser colocados en cualquier parte de la memoria RAM o el sistema operativo. El programa LINK únicamente añade cabeceras al programa. Ventajas del programa .EXE a) El archivo es reubicable. Mas de un programa puede ser cargado a memoria. b) Los archivos .EXE permiten el uso de hasta 4 segmentos. Esto permite una buena modularidad y la creación de grandes programas. Ventajas del programa en .COM a) Ocupa menos memoria que el .EXE. Contiene solamente un segmento, este segmento incluye toda la información necesaria que requiere el programa. Desventaja del programa en .COM No es reubicable y siempre debe comenzar en la dirección 0100H El MASM es un ensamblador de dos pasadas: 1ª pasada: Se realiza la traducción de tablas de símbolos, códigos, literales, etc. 2ª pasada se crea el código objeto, listado de errores, etc. Ejemplo: Etiqeta1: MOV AX, 01 CMP AX, BX JNZ Etiqueta2 SUB BX, 10 JMP Etiqueta1 Etiqueta2: ADD BX, AX HLT END Tabla de símbolos Nombre Valor Longitud Reubicable Acceso Ext. Etiqueta1 0 10 -- 1 Etiqueta2 10 6 -- 0 4
  • 9. Tabla de códigos OP Code Cod. Hex Long Int Tipo de inst MOV 7B 2 R/M CMP 3D 4 R/R ... ... ... ... R = registro y M = memoria Tabla de literales Valor Localidad 01 500H 10 502H Ventajas que se obtienen al aprender un Lenguaje Ensamblador 1. Habilidad para controlar el Hw. 2. Habilidad para desarrollar fragmentos de programas que sean de rápida ejecución. 3. Habilidad para accesar, de manera óptima y eficiente, el coprocesador2. 4. Comprensión de los métodos utilizados para realizar la sintaxis asociada con lenguajes de alto nivel. 5. Conocimiento profundo de los sistemas basados en microcomputadoras y de interfaz de Hw/ Sw. 6. Disciplina para programar de manera estructurada. 7. Comprensión de la forma en que se manejan, a bajo nivel, diversas estructuras de datos. Sistemas Numéricos Numeración binaria Un bit representa un dígito que tiene uno de dos valores posibles: uno o cero. El dígito representa uno de dos estados y se define como aritmética binaria o de base-2. N-bits pueden representarse de la siguiente manera, siendo el bit más significativo el que se encuentra mas a la izquierda. 2n-1 2n-2 ...... 23 22 21 20 En la memoria de la computadora, los números positivos se representan como enteros sin signo. En general, con palabras de 16 bits se puede representar cualquier entero positivo en el intervalo de 0-65,535 (216 - 1). Si el bit 16 se emplea para indicar el signo del número, entonces el mayor entero que puede representarse con los 15 bits restantes está en el intervalo de (-32,767, +32,767). Las computadoras generalmente utilizan aritmética de complemento a 2. En esta, los números positivos se representan de manera normal, y los negativos con su complemento ya que esto permite que las restas se conviertan en suma. 2 El coprocesador es el que lleva a cabo operaciones de punto flotante a muy alta velocidad. 5
  • 10. Bits, nibbles, Bytes, Words Bit = 1 ó 0 Nibble = 4 bits Byte = 2 Nibbles = 8 bits Word = 2 Bytes = 4 Nibbles = 16 bits Representación de enteros Magnitud con signo En éste método de numeración binaria los valores positivos empiezan con cero y los negativos con uno. El bit más significativo representa el signo. Ejemplo: Escribir con 3 bits los valores posibles 0|00 = 0 0|01 = 1 0|10 = 2 0|11 = 3 1|00 = -0 1|01 = -1 1|10 = -2 1|11 = -3 Complemento a uno Los positivos comienzan con cero (magnitud con signo) y para escribir los negativos se escribe el valor positivo y se complementa lógicamente (es decir, los 0 se convierten en 1 y viceversa) Ejemplo: Escribir con 3 bits todos los valores positivos y negativos posibles 0|00 = 0 0|01 = 1 0|10 = 2 0|11 = 3 1|00 = -3 1|01 = -2 1|10 = -1 1|11 = -0 Complemento a dos Los positivos se escriben igual que en complemento a uno y magnitud con signo. Los negativos provienen de sumarle 1 al valor del complemento a uno. Ejemplo: Escribir ±131 en complemento a dos con 9 bits 131 = 0|10000011 => además es m.c.s., complemento a uno y complemento a dos 1|01111100 => -131 en complemento a uno + 1 _______________ 1|01111101 => -131 en complemento a dos Exceso 2n-1 Para escribir cualquier cantidad positiva o negativa bastará con sumarle 2 n-1, donde n=número de bits empleados. Ejemplo: Escribir ±36 en exceso 2n-1 con 7 bits. 36 + 27-1= 36 + 26 = 36 + 64 = 100 => 1100100 -36 + 27-1= -36 + 26 = -36 + 64 = 28 => 0011100 6
  • 11. Representación de punto flotante Los números de punto flotante se representan en la forma a·be donde: a=es la mantiza normalizada b=es la base del sistema de numeración e=es el exponente de la base Ejemplo: Representar 1943 en punto flotante en base decimal .1943 x 104 donde a=.1943, b=10 y e=4 se dice que un número es de punto flotante normalizado cuando se cumple: 1 ≤ x < 1 donde b=es la base del sistema de numeración, x=es el número en punto flotante b normalizado. 1 Ejemplo: en el sistema decimal debe cumplir ≤ x < 1 o sea .1 ≤ x < 1 10 1 En binario debe cumplir ≤ x < 1 o sea .5 ≤ x < 1 2 La familia PDP-11 de DEC representan sus números de punto flotante con 32 bits: 1 8 23 Signo de la Exponente Mantiza en M. C. S. mantiza en Exceso y 1 bit escondido 2n-1 La IBM representa sus números así: 1 7 24 Signo de la Exponente Mantiza en M. C. S. mantiza en Exceso y 1 bit escondido 2n-1 0.5x2=1.0 0.0x2=0.0 Bit escondido La mantiza se supondrá normalizada (siempre empezará con .1) y el primer 1 después del punto binario se omitirá suponiendo que esté presente (escondido). Ejemplo Escribir –135.5 como la PDP-11 y como la IBM 135=10000111 -135=110000111 mcs 0.5 x 2 =1.0 entonces –135.5=110000111.1=.1100001111x29, en PDP-11 es: 7
  • 12. 9 + 28-1(8 por el número de bits del exponente)=9 + 27=9 + 128=137 (en exceso 2n-1) 137=10001001 (exponente) 1 10001001 .00001111000000000000000 Representar el punto flotante como la IBM el 237.57 0 1001001 .110110110010001111010111 El Debug El Debug es una herramienta de edición y comprobación de programas el cual proporciona un control de pruebas en un ambiente binario y de archivos ejecutables. Se puede ejecutar de dos maneras:  Introduciendo DEBUG desde la línea de comandos (C:>Debug <↵>)  Para depurar un archivo ejecutable (C:>Debug ejemplo.EXE <↵>) DEBUG [[unidad:][ruta]archivo [parámetros_de_test]] Donde [unidad:][ruta]archivo Especifica el archivo que se desea comprobar. parámetros_de_test Especifica la información de línea de comandos que precisa el archivo que se desea comprobar. Si decide trabajar desde la línea de comandos del debug, al momento de presionar el enter aparecerá un nuevo prompt esperando instrucciones. La línea de comandos del debug consiste en una sola letra con uno a más parámetros. Después de iniciar Debug, escriba ? para visualizar una lista de los comandos de depuración. Si un error de sintaxis ocurriera se indicará mediante un ^Error Lista de comandos Comando Función A [address] Assemble C range address Compare Intervalo de direcciones D [range] Dump E address [list] Enter F range list Fill G [=address [address …]] Go H value value Hex I value Input L [addres [drive record record]] Load M range address Move N file descriptor [file descriptor] Name O value byte Output P [=dirección] [número] Proceed Q Quit R [register-name] Register S range list Search T [=address] [value] Trace U [range] Unassemble W [address [drive record record]] Write XA [N.páginas] allocate expanded memory 8
  • 13. Comando Función XD [identificador] deallocate expanded memory XM [páginaL] [páginaP] [identificador] map expanded memory pages XS display expanded memory status El debug permite colocar en memoria y ejecutar un grupo de instrucciones en lenguaje de máquina una a una en un tiempo, permitiendo observar cómo el programa trabaja. El debug utiliza números hexadecimales puesto que en términos de longitud es más fácil que con números binario. Trace (T) ejecuta una o más instrucciones comenzando con la dirección actual del apuntador de instrucciones (CS:IP) Dump (D) Muestra el contenido de la memoria comenzando con una determinada localidad (indicada ésta como segmento:desplazamiento) Quit (Q) termina la ejecución del DEBUG 9
  • 14. INTRODUCCIÓN A LA PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR El alumno conocerá cómo representa la computadora de manera interna los datos e instrucciones que procesa mediante el debug. EL DEBUG y su Uso El término Debugging nació en los primeros días de la computación, en particular, un día en el cual la computadora Mark I de Harvard falló. Después de buscar el problema lo encontraron: una pequeña basura estaba entre los contactos de un relay (contacto electromagnético), la limpiaron y en el libro técnico de la Mark I escribieron acerca del Debugguing. El debug permite colocar en memoria y ejecutar un grupo de instrucciones en lenguaje de máquina una a una en un tiempo, permitiendo observar cómo el programa trabaja. El debug utiliza números hexadecimales, puesto que en términos de longitud es más fácil que con números binarios. El nombre hexadecimal proviene de hexa (6) y deca (10), lo cual combinado representa 16 dígitos (0 – 9, A - F). Con dos números hexadecimales se pueden representar 256 diferentes números con dos dígitos. Para ejecutar el Debug deberá estar en el símbolo del sistema (DOS) e introducir: C:>Debug <↵>3 Para ejecutar el debug Inmediatamente aparece un prompt ( - ) Para salir del Debug deberá teclear Q - Q <↵> Para salir Q (Quit) El comando H (Hexarithmetic) suma y resta dos números hexadecimales - H 3 2 <↵> 0005 0001 - H 3D5C 2A10 676C 134C - H 3A7 1ED 0594 01BA -H91 000A 0008 -H96 000F 0003 ¿Qué pasa si nosotros usamos H 2 3? -H23 0005 000F El FFFFh es igual al 65,535 ó 64 Kb alias –1 H 5 FFFF 0004 0006 3 <↵> Significa Enter 10
  • 15. ¿Qué pasa si nosotros utilizamos números de 5 dígitos? H 5CF00 4BC6 ^ERROR El 8088/8088/80286/80386/80486 puede usar números con signo o sin signo. En la forma binaria para números positivos el bit 5 es siempre 0, para los negativos 1. Si nosotros usamos instrucciones para números sin signo en nuestro programa, el procesador ignora el bit de signo, de tal manera que nosotros podemos usarlo a nuestra conveniencia. Los números negativos son conocidos como complemento a dos del número positivo. 11
  • 16. ARITMÉTICA DEL 8086/8088/80286 MEDIANTE EL DEBUG Conociendo algo del Debug y la aritmética binaria del procesador, nosotros podemos aprender cómo el procesador trabaja y puede ejecutar órdenes internas llamadas instrucciones. REGISTROS COMO VARIABLES Debug, nuestro guía e intérprete, conoce mucho acerca del procesador. Vamos a preguntar al Debug qué podemos hacer respecto a esas pequeñas piezas llamadas registros que podemos usar como variables en donde podemos almacenar datos. El procesador contiene un número fijo de registros conocidos como registros de propósito general, los cuales no son parte de la memoria RAM de la PC. Nosotros le podemos solicitar al Debug que despliegue la información contenida en los registros con el comando R (Register). Probablemente vea diferentes números en las líneas dos y tres del desplegado en la pantalla, éstos números reflejan la cantidad de memoria de su computadora. Por ahora, el Debug nos ha proporcionado mucha información. Nos concentraremos en los registros AX, BX, CX y DX, los cuales deben ser iguales a 0000. Los números de cuatro dígitos siguientes para cada registro están en notación hexadecimal. Una palabra está compuesta por cuatro dígitos hexadecimales. Cada uno de estos registros son de 16 bits, esto explica porque 8086/8088/80286 son conocidas como máquinas de 16 bits. Los otros registros, también son conocidos como de propósito especial: SP, BP, SI, DI, DS, ES, SS, CS, e IP. El comando R hace más que desplegar los registros, también nos permite cambiarlos. Por ejemplo, nosotros podemos cambiar el valor de registro AX. - R AX <↵> AX 0000 : 3A7 <↵> R (Para comprobar) Desde este momento utilizaremos el Debug como un intérprete, así que nosotros podremos trabajar directamente con el procesador. Ahora, colocaremos un número en BX y otro en AX y, le pediremos al procesador que los sume y deje el resultado en AX. Coloque AX=3A7h y en BX=92A con el comando R. Verifíquelo. LA MEMORIA DEL PROCESADOR ¿Cómo le podemos decir al procesador que adicione BX a AX?. Nosotros colocaremos dos bytes de código de máquina en algún lugar de su vasta memoria RAM, que le diga al procesador que sume los registros con la ayuda del debug. La memoria está dividida en piezas de hasta 64Kb llamados segmentos. Nosotros colocaremos la instrucción en algún lugar de un segmento y luego le diremos dónde está y que la ejecute sin saber dónde inicia dicho segmento. Todos los bytes de la memoria RAM están etiquetados con números iniciando con 0000h. Pero recuerda que la limitación de los números hexadecimales es de 4 dígitos. De esta manera, el número más alto que puede ser usado como etiqueta de memoria es de 65,535, lo cual, implica la longitud máxima de los segmentos. 12
  • 17. Sin embargo, el procesador puede llamar más de los 64 Kb de memoria. ¿Cómo puede ser esto?. Se usan dos números, uno para cada segmento de 64 Kb. y otro para el desplazamiento dentro del segmento. De tal manera, que los segmentos están traslapados pudiendo el procesador utilizar más de un millón de bytes en memoria. Todas las etiquetas de dirección serán usadas como resultado del principio de un segmento. Por ejemplo: 3756:0100 significará que nosotros estamos en la dirección 0100h del segmento 3756. Por ahora, confiaremos del debug para cuidar el segmento por nosotros. Así, que nosotros trabajaremos sin prestar atención a los números de segmento. Ahora, cada dirección se refiere a un byte de un segmento y las direcciones son consecutivas. Colocaremos la instrucción de adición ADD AX, BX en la posición 0100h y 0101h del segmento. El código de la instrucción es 01D8h. El Comando del Debug para examinar y cambiar los datos en la memoria es E (de Enter). Use éste comando para colocar la instrucción. - E 100 3756:100 B4.01<↵> - E 101 3756: 0101 85.D8<↵> El número de segmento que observa, probablemente sea diferente pero eso no afecta la operación. ESTILOS DE ADICIÓN Si damos R, verificaremos que está cargada la instrucción correcta. Los bytes 01h y D8h tal vez no significan nada para nosotros, pero para la máquina sí; es el código para el nemotécnico ADD AX, BX. Ahora, debemos decir al procesador dónde encontrar la instrucción (el segmento y el desplazamiento), lo cual lo encuentra a partir de los registros CS e IP. Al desplegar nuevamente los registros veremos el valor del segmento en CS, la segunda parte de la dirección se almacena en IP. Colocaremos IP= 0100, inicialmente, siempre apunta a 0100h. Ahora le diremos al debug que utilice la instrucción mediante el comando T (Trace), el cual ejecuta la instrucción en un tiempo. Después de ejecutar una instrucción el IP se incrementa y apunta a la siguiente dirección, es decir, en 0102h (nosotros no hemos colocado ninguna instrucción en esa dirección, pero el procesador sí). AX contiene ahora el resultado CD1h. Repita la instrucción, con los valores que conservan los registros, el resultado en AX=15FBh y en BX=092Ah. ESTILOS DE RESTA Ahora, vamos a escribir una instrucción para restar BX a AX, con los datos que conservan. Así que, el código para la resta es 29h y D8h. Cárguelo a partir de la dirección IP=0100h, ahora ejecute la instrucción T, el Resultado en AX es 0CD1h, repita nuevamente, ahora AX es 03A7h. NÚMEROS NEGATIVOS El procesador usa el complemento a dos para los números negativos. Ahora, trabajaremos con la instrucción SUB para calcular números negativos. Le haremos una pequeña prueba al procesador para obtener el resultado FFFFh alias -1. Nosotros le restaremos un 1 a 0 colocando AX=0000 y BX=0001. Repitamos la instrucción SUB en la dirección 0100. ¿Cuál es el resultado?. Haga la prueba con otros datos. 13
  • 18. BYTES Todos los datos hasta ahora han sido representados en palabras. ¿El procesador sabe cómo representar la aritmética con Byte?. La respuesta es sí. Los registros de propósito general están divididos en dos bytes, conocidos como alto (High) y bajo (low). Ahora ejecutaremos la instrucción ADD AH, AL, lo cual es una adición de dos bytes del registro AX y el resultado quedará en AH. El código para esta instrucción es 00h y C4h. Carguemos AX =0102h, es decir AH=01 y AL=02; almacene el código de la instrucción a partir de la dirección 100h y haga IP=0100h y ejecute la instrucción con el comando T. Ahora encontrará que AX=0302h. El resultado de 01h + 02h = 03h que está almacenado en AH. Ahora, suponga que deseamos sumar 01h y 03h. ¿Podemos colocar 01h en AL?, la respuesta es no. Tendrá que colocar 0301 porque el debug sólo nos permite cambiar la palabra completa. Ejecute nuevamente la instrucción, el resultado es 0401h, la suma de 03h + 01h está ahora en AH. ESTILOS DE MULTIPLICACIÓN Y DIVISIÓN La instrucción de multiplicación llamada MUL y su código de máquina para multiplicar AX y BX es F7h y E3h. La instrucción MUL almacena su respuesta en los registros AX y DX, puesto que multiplicar dos números de 16 bits da como resultado uno de 32 bits. La parte alta de los 16 bits en DX y la parte baja en AX. Nosotros escribiremos esta combinación de registros como DX:AX. Coloque el código de MUL a partir de la dirección 0100h y coloque AX=7C4Bh y BX=0100h. Compruebe con R la instrucción, la cual observará como MUL BX. El procesador siempre realiza la operación por default en AX. 0100h * 7C4B. Los tres dígitos del 100 tienen el mismo efecto que en haxadecimal. El resultado es 7C4B00h, es decir, se suman dos ceros a la derecha DX=007Ch y AX=4B00h. Multiplicar dos palabras juntas nunca pueden ser más de 2 palabras. Cuando nosotros dividimos dos números, el procesador da como resultado el cociente y el resto. El código para la división es F7h y F3h. Colóquelo en la dirección 0100h y 010h. Como la instrucción MUL, DIV también usa DX:AX. Si desplegamos con R, veremos la instrucción DIV BX. Ahora, dividamos el resultado de MUL que está en DX:AX, es decir, 007Ch:4B00h. Hagamos la división 7C4B00h/0100h, por lo tanto pongamos 0100h en BX. El resultado, el cociente en AX=7C4Bh y el resto en DX=0000h. 14
  • 19. IMPRIMIENDO CARACTERES Vamos a iniciar con las interrupciones del DOS para enviar un carácter a la pantalla. Construiremos un pequeño programa y aprenderemos otra manera de poner datos en los registros. Ahora, veamos si podemos hablar con el DOS. INT 21h (El poder de la Interrupción) Usaremos la instrucción llamada INT para interrumpir lo que está haciendo el procesador y decirle al DOS que imprima el carácter A en la pantalla. La función 02h de la interrupción 21h del DOS imprime un carácter en la pantalla. Entraremos al Debug y haremos AX= 0200h y DX=0041h. El código en hexadecimal para la instrucción INT 21h es CD21h, es una instrucción de dos bytes que iniciará en la dirección 100h, use R para confirmar que IP=100h. No podemos usar el comando T para ejecutar esta instrucción (puesto que ejecuta una instrucción en un tiempo), pero la instrucción INT llama (invoca) a un programa largo “subroutine” del DOS, porque trazaríamos a través de una instrucción en un tiempo. Nosotros queremos ejecutar nuestra línea de programa, pero detenernos antes de ejecutar la instrucción de la localidad 102h. Lo anterior, podemos hacerlo con el comando G (GO), indicando la dirección en la cual queremos detenernos. - G 102 <↵> DOS imprimirá el carácter A y retornará el control a nuestro programa. En cierto sentido, nuestra línea de instrucción es en realidad dos instrucciones, la segunda instrucción está en 102h. INT 21 MOV SP BP El registro 02h en AH le dijo al DOS que imprima un carácter. Otro número en AH, le dirá al DOS que realice una función diferente. El DOS usa el número en DL como el código ASCII para el carácter a imprimir. El código de A=41h. Son muchas las operaciones que realiza el DOS para imprimir un carácter simple. INT 20h (Una salida con gracia) Si nosotros usamos la interrupción 20h, INT 20h (cuyo código hexadecimal es CD20h), le decimos al DOS que deseamos salir de nuestro programa, así que el DOS puede tomar el control de nuevo. En nuestro caso, INT 20h enviará el control de nuevo al Debug porque nosotros estamos ejecutando nuestro programa desde el Debug en vez del DOS. Coloque la instruscción INT 20h iniciando en la localidad 100h, verifique con el comando R. Ahora, ejecute la instrucción con el comando - G 102 <↵> Program terminated normally (El programa ha finalizado con normalidad) UN PROGRAMA DE DOS LÍNEAS, PONIENDO LAS PIEZAS JUNTAS Ahora, juntemos los dos tipos de instrucciones colocándolas a partir de la dirección 0100h (sus códigos son CD21h y CD20h). 15
  • 20. Para listar varias instrucciones (es decir, ver los nemónicos), necesitamos el comando U (Unassembler). Al proporcionar - U 100 <↵> La computadora desplegará varias instrucciones, nosotros reconoceremos las dos primeras. Posteriormente, coloque AX=0200h y DX= cualquier número ASCII del carácter que desee imprimir en pantalla. Para ejecutar las instrucciones - G 104 <↵> (X) es la letra que se deseó imprimir en DX Program terminated normally PROGRAMAS ENTEROS Hasta ahora, nosotros hemos cargado nuestras instrucciones con números (códigos de máquina). El comando A (Assembler) nos permite cargar nemotécnicos directamente en memoria. - A 100 <↵> 3970:0100 INT 21 3970:0102 INT 20 3970:0104 <↵> Aquí, el comando A le dijo al Debug que deseamos colocar instrucciones en forma nomotécnica a partir de la dirección 0100h. MOVIENDO DATOS ENTRE REGISTROS Coloque 1234h en AX (AH=12h y AL=34h) y ABCDh en DX (DH=ABh y DL=CDh). - A 100 <↵> 3970:0100 MOV AH, DL 3970:0102 MOV AL, DH 3970:0104 <↵> Verifique que IP=0100h y ejecute las instrucciones con - G 104 Observe los datos almacenados en AX. Ahora, almacene a partir de la dirección 0200h las siguientes instrucciones MOV AH, 02 ; Carga tipo de función MOV DL, 2A ;Carga código ASCII del * INT 21 ;Solicita la INT 21h para imprimir un carácter INT 20 ;Retorna el control al Debug Ejecútelo y observe qué pasa. Para grabar el programa en disco, use primero el comando N (Name), el cual asigna un nombre a un archivo antes de grabarse. - N imprime.com Antes de grabar, debemos proporcionar el número de bytes a grabar a partir de la dirección contenida en IP. Para hacer esto, se calcula: 4 instrucciones * 2 bytes = 8 bytes de longitud. Otra manera, es observar la dirección final del programa y hacer - H 208 200 <↵> Siempre se debe proporcionar una localidad después de la última instrucción 16
  • 21. El debug utiliza los registros BX:CX para almacenar la longitud de un archivo a grabar, por lo tanto, colocaremos en CX el 08h y en BX el 00h. Por último, para grabar el programa, usaremos el comando W (Write) - W <↵> Writing 0008 bytes Para correrlo desde el DOS sólo se da el nombre del programa. A: imprime <↵> ESCRIBIENDO STRINGS DE CARACTERES Debemos usar la interrupción 21h con una función diferente en AH para escribir una string en la pantalla. Antes debemos almacenar en memoria y decirle al DOS dónde se encuentra. 02= Imprime un carácter en pantalla. 09 Imprime una string y se detiene al encontrar el carácter $ Colocaremos la string a partir de la localidad 0200h con E 200 48 65 6C 6C 6F 2C 20 44 4F 53 20 68 65 72 65 2E 24 La string termina con el número 24h, que indica fin de la string. Lo anterior, explica porqué el DOS nunca utiliza el $, es decir, no puede imprimirlo. Con el comando D (Dump), podemos ver las cadenas de caracteres en memoria. - D 200 <↵> ------------ ------------------------------------------------------ HELLO, DOS HERE Vemos 16 bytes hexadecimales, seguidos de los mismos pero en ASCII. Donde vea un puntoen la ventana de ASCII, representa un carácter especial, por ejemplo la letra griega beta o theta. El comando D despliega 96 caracteres de los 256 caracteres usados en la computadora, es decir, que 160 caracteres son representados por un punto (.). MOV AH, 09 ;Función imprime string MOV DX, 0200 ;Dirección donde inicia la string INT 21 INT 20 Al ejecutarlo, HELLO, DOS HERE. El programa ha finalizado con normalidad Ahora, asigna un nombre al programa y grábalo en disco, puedes usar el comando H para auxiliarte a calcular la longitud del programa. 17
  • 22. Registro de banderas Usos comunes de los registros internos del 8088 Registro Descripción Datos AX Acumulador: usado para almacenamiento de programación en general, también para algunas instrucciones como multiplicación, división, I/O, manejo de cadena de caracteres. BX Base: Cuando se accesa la memoria, con frecuencia se utiliza este registro para contener valores de direcciones. Al hacer uso de rutinas de servicios de interrupción, este registro debe contener un valor que se usa para selección de opciones CX Contador: durante la ejecución de un loop, este registro contiene el valor de un índice de conteo DX Datos: usado para almacenamiento general y también para operaciones de multiplicación y división Segmento CS Registro de segmento de código: éste registro apunta al inicio del segmento donde el programa en ejecución se encuentra situado DS Registro de segmento de datos: Señala el inicio del segmento de datos SS Registro de segmento de pila: Señala el inicio del segmento de pila ES Registro de segmento extra: Señala el inicio del segmento de extra Apuntador SP Apuntador de pila: para algunas instrucciones este registro contiene valores de desplazamiento para el stack BP Apuntador base: Similar a SP. Algunas instrucciones hacen uso de el con el fin de guardar el valor de un desplazamiento Índice SI Índice fuente: para ciertas instrucciones, este registro contiene la dirección fuente con frecuencia las instrucciones que hacen uso de este recurso no requieren de operandos DI Índice destino: Contraparte con SI y contiene la dirección destino para algunas instrucciones. IP Apuntador de instrucciones: apunta a la localidad de memoria donde se encuentra la próxima instrucción a ser ejecutada SF Banderas o registro de estado de banderas: existen 9. estas proporcionan información con respecto al resultado de varias operaciones Bits 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 X X X X OF DF IF TF SF ZF X AF X PF X CF SF Notas: AX, BX, CX, DX se subdividen en 2 bytes (p.e. AX = AH,AL) AX = 16 bits = 1 word AH, AL = 8 bits cada uno = 1 byte Los demás registros requieren de 1 word o sea 16 bits Todos los nombres de registros son palabras reservadas al efectuar un programa en ensamblador. 18
  • 23. Bandera Debug No. Bit Designación Descripción S O 0 CF Bandera de acarreo: el valor de este bit es 1 si el resultado de una operación de adición CY NC o sustracción genera un acarreo o préstamo. 1 No usado -------------------------------------------------------------------------------------------------------- ---- ---- - 2 PF Bandera de paridad: es un 1 si el resultado de una operación de datos tiene un número PE PO par de bits iguales a 1 3 No usado -------------------------------------------------------------------------------------------------------- ---- ---- - 4 AF Bandera de auxiliar de acarreo: indica la presencia de un acarreo generado del cuarto AC NA bit de 1 byte. Su mayor uso es durante operaciones aritméticas con números decimales codificados en binario 5 No usado -------------------------------------------------------------------------------------------------------- ---- ---- - 6 ZF Bandera de cero: es activada si el resultado de una operación es cero ZR NZ 7 SF Bandera de signo: se activa si el resultado de una operación con números signados es NG PL negativo. 8 TF Bandera de trampa: cuando este bit es activado, el 8088 ejecuta una instrucción a la ---- ---- vez (No se considera en el debug) 9 IF Bandera de habilitación de interrupción: el 8088 atenderá a las interrupciones solo EI DI cuando este bit sea activado 10 DF Bandera de dirección: Cuando es activada, causa que el contenido de los registros DN UP índice se decremente después de cada operación de una cadena de caracteres 11 OF Bandera de sobreflujo: es activada cuando el resultado de una operación es mayor que OV VN el máximo valor que es posible representar con el número de bits del operando destino 12-15 No usado -------------------------------------------------------------------------------------------------------- ---- ---- - 19
  • 24. IMPRIMIENDO NÚMEROS BINARIOS Ahora nosotros construiremos un programa para escribir números binarios en la pantalla. BANDERAS DE ACARREO Y ROTACIÓN Si le adicionamos 1h a FFFFh, el resultado debería ser 10000h; sin embargo, se produce un overflow. Solamente los 4 dígitos más a la derecha encajan en una palabra, pero el 1 no. El 1 es un overflow y no está perdido. Se va a un lugar llamado bandera, en este caso, la bandera de acarreo o CF. Las banderas contienen un bit (0,1). Si nosotros necesitamos un acarreo de un 1 dentro del dígito quinto, éste va dentro de la bandera de acarreo. Si hacemos AX = FFFFh y BX = 01h y ADD AX, BX. Al final de la segunda línea del debug al dar R, verá 8 pares de letras. Podrá leer NC o CY (acarreo). El resultado de la operación, resultará un overflow de 1, entonces, la bandera estará en CY (carry). El acarreo es de 1, es decir está activada. Para comprobar que se ha almacenado el bit 17 (o el noveno para una operación de 8 bits), adicione 1 a 0 en AX, con IP = 0100h y repitiendo la instrucción de nuevo. La bandera estará afectada por cada instrucción ADD, y en este momento no hubo acarreo, por lo que se desactivará, lo que indica con NC (no carry) al dar R. Al imprimir un número binario, la información del acarreo nos es útil. Imprimiremos solamente un caracter a un tiempo y sacaremos los bits de nuestro número uno por uno, desde la izquierda a la derecha. Por ejemplo, el primer caracter del número 1000 0000b es el uno. Nosotros podemos mover un byte un lugar hacia la izquierda, almacenando el uno en la bandera de acarreo y adicionando un 0 a la izquierda, repitiendo el proceso para cada dígito sucesivo. Para hacer esto, usamos la instrucción RCL (rotación de acarreo hacia la izquierda). Ejemplo: RCL BL, 1 ;Rota el byte en BL un lugar hacia la izquierda. Esto lo hace a través de la bandera de acarreo. La instrucción es llamada rotación porque RCL mueve el bit de la izquierda a la bandera de acarreo. En este proceso, todos los demás bits son movidos o rotados a la izquierda. Después de cierto número de rotaciones suficientes (17 para una palabra, 9 para un byte), los bits serán movidos a la posición original y se regresará al número original. Ponga B7 en BX y ejecute la instrucción 9 veces. Convirtiendo sus resultados a binario, observará: Carry Registro BL No. Hexadecimal 0 1011 0111 B7 1 011 01110 6E 0 11 011101 DD … … … 0 1011 0111 B7 20
  • 25. Ahora veremos cómo convertir el bit en la bandera de acarreo en un carácter 0 ó 1. ADICIÓN CON LA BANDERA DE ACARREO La instrucción ADC (adiciona con acarreo), adiciona tres números, los dos normales mas un bit de acarreo. El 0 = 30h y el 1 = 31h en código ascii. Así que adicionando a la bandera de acarreo el 30 conseguiremos el 0 cuando el bit de acarreo está en 0 (desactivado) y 1 cuando el bit de acarreo está en 1 (activado). Si DL = 0 y la bandera de acarreo está activada (1) y ejecutamos: ADC DL, 30 entonces conseguimos el 31h = 1b, es decir, nosotros podemos convertir el acarreo en un caracter que podemos imprimir. Ahora, nosotros necesitamos un loop para ejecutar RCL, ADC e INT 21h 8 veces, una para cada bit del byte. LOOPING El loop es como un for – next, pero no tan general. Loop decrementa CX y finaliza cuando CX=0. Aquí presentamos un programa simple que rotará BX 8 veces, moviendo BL en BH (pero no al revés), puesto que nosotros rotamos a través de la bandera de acarreo. El loop inicia en 106h y termina en la instrucción loop. 0100 MOV BX, A3C5 0103 MOV CX, 0008 0106 RCL BX, 1 0108 LOOP 0106 010A INT 20 Para ejecutarlo, puede hacerse paso a paso con T o con G 010A (sin ejecutar INT 20 puesto que inicializa los registros). Podemos comprobar que CX = 0 y que BX = C551 o BX = C5D1, dependiendo del valor inicial de la bandera de acarreo. ESCRIBIENDO NÚMEROS BINARIOS 0100 MOV AH, 02 0102 MOV CX, 0008 0105 MOV DL, 00 0107 RCL BL, 1 0109 ADC DL, 30 010C INT 21 010A LOOP 0105 0110 INT 20 Ejecútese con G después de INT 20, BL contiene el número impreso en binario. Recuerde que no se puede ejecutar con T la instrucción INT 21 e INT 20. 21
  • 26. IMPRIMIENDO EN HEXADECIMAL COMPARANDO CON LA AYUDA DEL REGISTRO DE BANDERA. Si el resultado de la última operación de la bandera del cero (ZF) es cero, entonces, la bandera será ZR (Zero), en caso contrario, al activarse será NZ (Not Zero). Si la bandera del signo (SF) es cero, entonces, la bandera será PL (Plus o positivo), en caso cotrario, al activarse será NG (Negative). Si la bandera del overflow (OF) es cero, entonces, la bandera será VN (No overflow), en caso contrario, al activarse será OV (Overflow). JZ (Salta si es cero), salta si el resultado de la última operación aritmética es cero, es decir, cuando la bandera ZF es ZR. JNZ (Salta si no es cero), salta si el resultado de la última operación aritmética no es cero, es decir, si la bandera ZF es NZ. Ejemplo: 396F:0100 MOV AL,05 396F:0102 SUB AL,01 396F:0104 JNZ 0102 396F:0106 INT 20 CMP (Compare), permite realizar comparaciones sin almacenar el resultado, es decir, puede activar únicamente el registro de banderas. Ejemplo: CMP AX, BX Si el resultado es cero se activa la bandera del cero en ZR = 1, pero los datos en los registros se conservan. IMPRIMIENDO UN DÍGITO EN HEXADECIMAL. Iniciaremos colocando un pequeño número entre 0h y Fh en BL. Los caracteres ASCII del 0 al 9 son 30h a 39h, de la A a la F, son 41h a 46h. Estos dos grupos ASCII, están separados por 7 caracteres. Como resultado, la conversión ASCII será diferente para los dos grupos de números. Cada grupo se manejará en forma diferente. If BL < 0Ah Then BL = BL +30h Else BL = BL + 37h 22
  • 27. Otra manera BL = BL +30h If BL >= 3A Then BL = BL +07h El siguiente programa cargará en BL un simple dígito en hexadecimal y lo imprimirá en pantalla. 127B:0100 MOV AH,02 127B:0102 MOV DL, BL 127B:0104 ADD DL, 30 127B:0107 CMP DL, 3A 127B:010A JL 010F 127B:010C ADD DL,07 127B:010F INT 21 127B:0111 INT 20 CMP compara DL con 3Ah y activa banderas pero no cambia DL. JL (Jump if less than, Salta si DL < 3Ah). Mediante una operación lógica podemos aislar los 4 bits más bajos que representan el segundo dígito hexadecimal. Para rotaciones de más de un bit utilizamos el registro CL para llevar la cuenta. CL se usa para indicar el número de veces que va a rotar el byte o palabra. ¿Cómo podremos imprimir dos dígitos hexadecimales? Nuestro plan ahora, es rotar el byte en DL cuatro dígitos a la derecha, usando SHR (corrimiento a la derecha). Moviendo los 4 bits más altos a la derecha. Si hacemos: MOV CL, 04 MOV DL, 5D SHR DL, CL Entonces DL = 5D, o sea, el primer dígito de 5Dh, lo cual se imprimirá. Escribiremos un programa para colocar un número en BL e imprimirlo. MOV AH, 02 MOV DL, BL ;Se inicializa con el número hexadecimal a imprimir MOV CL, 04 SHR DL, CL ADD DL, 30 CMP DL, 3A JL BRINCO ; Aquí debe ir la dirección donde se encentra la INT 21h ADD DL, 07 BRINCO: INT 21 INT 20 Para aislar e imprimir el segundo dígito, dejando DL = a los 4 bits inferiores, se activan los 4 bits superiores en cero con la función lógica AND, herramienta de lógica formal. 23
  • 28. Por ejemplo, AND BL, CL BL 1011 0101 CL 0111 0110 --------------- AND 0011 0100 Usando AND BL, 0Fh tenemos: BL 1011 0101 0Fh 0000 1111 --------------- AND 0000 1111 El programa que imprime el segundo dígito hexadecimal es: MOV AH, 02 MOV DL, BL AND DL, 0F ADD DL, 30 CMP DL, 3A JL BRINCO ADD DL, 07 BRINCO: INT 21 INT 20 24
  • 29. LEYENDO CARACTERES Ahora realizaremos el proceso inverso, leeremos dos caracteres en hexadecimal del teclado y lo convertiremos a un byte. LEYENDO UN CARACTER La interrupción 21h puede ser utilizada con la función 01h para leer un caracter (con eco) del teclado. Al ejecutarse, el cursor se detendrá parpadeando en espera de que presionemos una tecla. Al hacerlo, el DOS colocará el código ASCII del caracter leído en AL. LEYENDO UN NÚMERO HEXADECIMAL Para leer un carácter hexadecimal como 0, 1, …, 9, A, B, …, F, y convertirlo a un byte debemos sustraer al código ASCII del caracter leído 30h (si el caracter es 0, 1, …, 9), o 37h (si el caracter es A, B, …, F). MOV AH, 01h ;Función lee un caracter INT 21 ;Lee caracter y guarda su código ASCII en AL SUB AL, 30 ;Restar a AL 30h CMP AL, 09h ;¿Es número o letra? JLE Salto1 ; Si es número salta SUB AL, 07h ; Como es letra restar al AL 07h Salto1: INT 20 ; Regresa el control al DOS. JLE (Jump if Less Than or Equal), salta si es menor o igual. Ocasiona que la ejecución de un programa se ramifique hacia la dirección del operando si la bandera de signo no es igual a la de sobreflujo o si la bandera de cero está activada. Esta instrucción es funcionalmente igual que JNG (Jump in Not Greater Than), salta si no es mayor que. Nota: trabaja correctamente con números en hexadecimal válidos (o sea las letras en mayúsculas). LEYENDO DOS NÚMEROS HEXADECIMALES Se lee el primer dígito colocando su valor en hexadecimal en DL y lo multiplicamos por 16. para multiplicar haremos un SHL (corrimiento a la izquierda) en DL, poniéndole un cero hexadecimal (cuatro bits a la derecha). Al hacer SHL DL, CL con CL = 4 realizamos un corrimiento aritmético (ya que tiene el mismo efecto que una multiplicación aritmética por 2, 4, 8, 16, …, etc.), dependiendo del valor en CL. Posteriormente leeremos el segundo dígito hexadecimal y se lo adicionaremos al primero en DL. 25
  • 30. MOV AH, 01h INT 21 MOV DL, AL SUB DL, 30h CMP DL, 09h JLE Salto1 SUB DL, 07h Salto1: MOV CL, 04h SHL DL, CL INT 21 SUB AL, 30 CMP AL, 09h JLE Salto2 SUB AL, 07h Salto2: ADD DL, AL INT 20 26
  • 31. PROCEDIMIENTOS Y PILAS PROCEDIMIENTOS Un procedimiento es una lista de instrucciones que podemos ejecutar desde varios lugares de un programa, en vez de tener que repetirlos cada vez que las necesitemos. Llamaremos a un procedimiento con la instrucción CALL y regresaremos de este con la instrucción RET. Programa Principal ------ Procedimiento1 ------ ------ ------ ------ CALL PROCEDIMIENTO1 ------ ------ ------ ------ RET ------ CALL PROCEDIMIENTO1 ------ ------ ------ End Ejemplo de un programa en DEBUG que imprime las letras de la A a la J 0100 MOV DL, 41h 0102 MOV CX, 000A 0105 CALL 0200 0108 LOOP 0105 010A INT 20 0200 MOV AH, 02 0202 INT 21 0204 INC DL 0206 RET La primera instrucción coloca el código ASCII de la letra A (41h) en DL para imprimir el carácter mediante la INT 21, pero esta instrucción se ejecutará de forma lejana. Cuando llamamos el procedimiento localizado en 0200 colocamos en AH el valor de 02 que es la función para imprimir el carácter contenido en DL usando la INT 21. INC DL, es una nueva instrucción que incrementa en uno el registro DL. RET, regresa al programa principal situándose en la primera instrucción ejecutable después de su llamada en este caso LOOP 0105. 27
  • 32. Ejecute el programa para ver el resultado mediante el comando G. LA PILA Y EL RETORNO DE DIRECCIONES La instrucción CALL de nuestro programa necesita salvar la dirección de retorno en algún lugar del microprocesador sabiendo qué instrucción ejecutar cuando regrese de la instrucción RET. Para poderlo almacenar, necesitaremos una porción de la memoria conocida como pila. Para poder seguirle el rastro de lo que hace la pila, existen dos registros que podremos observar al ejecutar R: estos son el SP (Stack Point, Apuntador de Pila) y el SS (Stack Segment, Segmento de Pila) los cuales tendrán el número del segmento. Dirección Pila 0098: SP:0100 0100: 0203 0102: 0103 0104: En una Pila el último que entra será el primero en salir a esto es conocido como LIFO (Last In, First Out), esta secuencia es precisamente lo que necesitamos para revertir el regreso de direcciones después de que hacemos llamadas anidadas como en el presente ejemplo. 396F:0100 E8FD00 CALL 0200 … 396F:0200 E8FD00 CALL 0300 396F:0203 C3 RET … 396F:0300 E8FD00 CALL 0400 396F:0303 C3 RET … 396F:0400 C3 RET Aquí la instrucción en la dirección 0100h llama a uno en la dirección 0200h, la cual llama a otra en la dirección 0300h la cual llama a otra en la dirección 0400 donde finalmente vemos una instrucción de retorno (RET). Este RET, regresa a la instrucción siguiente previa a la instrucción CALL de la dirección 0300h o sea el microprocesador ejecuta la instrucción 0303h. pero encontrará otra instrucción RET en 303h la cual será empujada por la siguiente dirección (la 203h) dejándola fuera de la pila. De este modo el microprocesador retomará la instrucción ejecutando 2003h al inicio. Cada RET saca en que se encuentra al inicio regresando la dirección fuera de la pila de este modo cada RET siguiente el mismo camino volverá a las llamadas hechas atrás. Dirección Pila 0098: 0303 SP:0098 0100: 0203 0102: 0103 28
  • 33. 0104: METIENDO Y SACANDO (PUSHing and POPping) La pila es un útil lugar para guardar palabras (words) de datos momentáneamente, proporcionándonos el cuidado de restablecer la pila después de una instrucción RET. Hemos visto que una instrucción CALL mete una dirección de retorno (una palabra, word) colocándolo al tope (principio) de la pila mientras que una instrucción RET saca esta palabra del tope de la pila. Cargándola dentro del registro IP y expone la palabra que se encontraba debajo de esta. Nosotros podremos hacer mucho entendiendo perfectamente las instrucciones de PUSH y POP. Es conveniente salvar los valores de los registros de inicio de un procedimiento y restaurarlos al finalizar justo antes de la instrucción RET. Entonces liberaremos el uso de estos registros y de paso entender los procedimientos. Los registros están compuestos por varios niveles de procedimientos, conduce al siguiente nivel de abajo. Por salvar los registros al inicio de un procedimiento y restaurarlo al final de este, no necesitamos remover instrucciones este procedimiento de los diferentes niveles, haciendo nuestra programación muy sencilla. Ejemplo. 0200 PUSH CX 0201 PUSH DX 0202 MOV CX,0008 0205 CALL 0300 0208 INC DL 020A LOOP 0205 020C POP DX 020D POP CX 020E RET Note que los POP’s están en orden inverso que los PUSH’s esto es porque un POP remueve una palabra situada más recientemente en la pila y el último valor de DX está sobre el último valor de CX. Salvando y restaurando CX y DX nos permite cambiar los registros dentro del procedimiento iniciado en 0200h pero sin cambiar los valores usados por el procedimiento llamado y teniendo salvado CX y DX podremos usar estos registros como variables locales. LEYENDO NÚMEROS HEXADECIMALES CON MÁS CLASE Podemos crear un procedimiento ocultando las lecturas de caracteres hasta recibir uno que pueda convertirse en número hexadecimal entre 0 y Fh. No desplegaremos algún carácter inválido por lo tanto usaremos la función 08 de la Int 21h que lee caracteres pero no los coloca en pantalla y haremos un eco (desplegaremos) solo si es uno válido. Coloque 8h en el registro AH y ejecute esta instrucción digitando A justo después de ejecutar G 102 100 INT 21 29
  • 34. El código ASCII de A (41h) está ahora en el registro AL, pero A no aparece en la pantalla. Usando esta función, nuestro programa puede leer caracteres sin eco hasta leer un dígito hexadecimal válido (0-9 o A-F) con eco. Este es el procedimiento que hace eso y convierte un carácter hexadecimal a un número hexadecimal. 0200 PUSH DX 0201 MOV AH,08 0203 INT 21 0205 CMP AL,30 0207 JB 0203 0209 CMP AL,46 020B JA 0203 020D CMP AL,39 020F JA 21B 0211 MOV AH,02 0213 MOV DL,AL 0215 INT 21 0217 SUB AL,30 0219 POP DX 021A RET 021B CMP AL,41 021D JB 0203 021F MOV AH,02 0221 MOV DL,AL 0223 INT 21 0225 SUB AL,37 0227 POP DX 0228 RET El procedimiento lee un carácter en AL (con la INT 21 de 203h) y verifica que sea válido con las comparaciones (CMP) y los saltos condicionales. Si el carácter leído no es válido la instrucción es de salto condicional enviando al microprocesador atrás en la dirección 0203 donde la INT 21 lee otro caracter (JA, salta si está arriba; JB, Salta si está debajo; ambos tratos son para números sin signo hay instrucciones JL que usaremos para tratar a números con signo). En la línea 211h sabremos si tenemos un dígito válido entre 0 y 9 por lo tanto sustraemos el código para colocar 0 y regresamos el resultado en el registro AL recordando sacar el registro DX cuando lo salvemos iniciando el procedimiento. El proceso del dígito hexadecimal de A - F es similar. Observe que tendremos 2 instrucciones RET en este procedimiento; tendremos varios o solamente uno. Este es un simple programa de prueba del procedimiento. 0100 CALL 0200 0103 INT 20 30
  • 35. Como hemos hecho antes, use el comando G, con un punto de interrupción, o use el comando P. Ejecute la instrucción CALL 200h sin ejecutar la instrucción INT 20h, para que vea los registros antes de finalizar el programa y que se restablezcan los registros. Usted verá el cursor al lado izquierdo de la pantalla, esperando un carácter. Teclee k que no es un carácter válido. Nada debe pasar. Ahora, teclee cualquiera de los caracteres del hexadecimal mayúsculos. Usted debe ver el valor del hexadecimal del carácter en AL y el propio carácter hechos eco de en la pantalla. Pruebe este procedimiento con las condiciones del límite: ' ' (el carácter antes del cero), 0, 9, ': ' (el carácter sólo después de 9), y así sucesivamente. Ahora que nosotros tenemos este procedimiento, el programa para leer un número hexadecimal de dos dígitos, con el tratamiento de errores, bastante aceptable: 0100 CALL 0200 0103 MOV DL, AL 0105 MOV CL, 04 0107 SHL DL, CL 0109 CALL 0200 010C ADD DL, AL 010E MOV AH, 02 0110 INT 21 0112 INT 20 Podemos ejecutar este programa en el DOS, desde que lee en un número hexadecimal de dos dígitos y entonces muestra el carácter ASCII correspondiente al número tecleado. Aparte del procedimiento, el programa principal es mas simple que la versión escrita anteriormente, sin tener que duplicar las instrucciones para leer los caracteres. Nosotros agregamos tratamiento de errores, sin embargo, y aun cuando complicó nuestro procedimiento, también asegura que el programa acepta sólo entradas válidas. Hemos visto la razón de salvar el registro DX en el procedimiento. El programa principal almacena el número hexadecimal en DL, para que nosotros no cambiemos DL en nuestro procedimiento situado en 200h. Por otro lado, el procedimiento situado en 200h usa el propio DL para hacer eco de los caracteres. Así, usando la instrucción PUSH DX de al principio del procedimiento, y POP DX al final, nos libramos de los problemas. A partir de ahora, evitaremos las interacciones complicadas entre los procedimientos, nosotros seremos muy estrictos sobre guardar cualquier registro usado por un procedimiento. 31
  • 36. PROGRAMACIÓN EN LENGUAJE ENSAMBLADOR El alumno programará en Lenguaje Ensamblador para trabajar a bajo nivel en la computadora y desarrollará diversas aplicaciones. Proceso de ensamble 1. Editar el programa con un editor de texto simple y que se guarde con extensión .ASM 2. MASM <nombre del archivo>.ASM; 3. LINK <nombre del archivo>; 4. EXE2BIN <nombre del archivo>.EXE <nombre del archivo>.COM Rutinas utilizadas en Ensamblador Programa Descripción Editor Programa que permite crear un código fuente. DOS proporciona el Edit. MASM Es el programa macroensamblador de IBM para cargarlo en memoria se requieren 96K de RAM. Existe una versión más modesta denominada small assembler (ASM), que solo necesita 64K de memoria pero no ofrece muchas de las características de MASM (entre ellas el soporte a macros). MASM se emplea para ensamblar código fuente y generar código objeto. Durante su operación, MASM pide al usuario los nombres para el archivo fuente (extensión .ASM), el archivo objeto que se genera (OBJ), el listado de los nombres de archivo (LST), y finalmente un listado de referencias cruzadas (CRF) LINK Este programa LINK se emplea para encadenar diversos módulos objetos generados ya sea pos MASM o por otros compiladores. El programa se encarga de asignar localidades de memoria absolutas para relocalizar al código objeto. El encadenador permite el desarrollo de código modular ya que con él es posible cambiar módulos individuales y para producir un programa completo. Cada módulo se puede depurar pr separado y después ser integrado al programa. DEBUG El programa DEBUG es útil durante la fase de desarrollo de programas. Tienen características que permiten al usuario ejecutar, por ejemplo, un programa paso a paso y examinar dinámicamente cómo cambia la memoria, también observar las banderas y la ejecución del programa desde un punto determinado (break point) monitoreando los registros. Tipos de instrucciones en lenguaje ensamblador Las instrucciones del lenguaje ensamblador pueden ser de diferentes estructuras dependiendo del número de direcciones que maneje. Instrucciones de 3 + 1 direcciones: Dirección Código de Dirección Dirección Dirección de la operación OP1 OP2 de destino siguiente instrucción Ejemplos: ADD A,B,C,D MUL K,R,PZ Instrucciones de 3 direcciones: Eliminando la dirección de la siguiente instrucción surgió la máquina con 3 direcciones. Se ejecutaría la instrucción siguiente en orden físico: 32
  • 37. Dirección Código de del OP1 OP2 operación resultado destino Máquinas con instrucciones de 2 direcciones: se eliminó la dirección del destino y el resultado se guardó en la localidad del segundo operando OP1 OP2 Código de Dirección Dirección operación fuente de destino Ejemplo: MUL R1,R2 ; Multiplica R1 a R2 y guarda el resultado en R2 Máquinas con instrucciones de una dirección: Eliminando y usando un registro llamado acumulador en la cual se pueden realizar operaciones aritméticas, las instrucciones quedan con una sola dirección. Ésta podrá ser fuente o destino según sea lo que indique la instrucción usada. Operando Código de fuente / operación destino Ejemplo: SUB AL, AL ;SUB AL se resta a AL ADD AH, BH ; ADD BH se suma a AH DIV AX ; Se divide a AX el valor de AX DIV AX, CX ;DIV CX se divide AX entre CX Máquinas de cero instrucciones: Manejando una pila se puede hablar de una máquina con cero instrucciones (aunque en verdad no son cero instrucciones). Ésta máquina usa dos instrucciones PUSH (empuja un dato) POP (Jala un dato) para llevar a la pila y sacar de ella un dato. Las operaciones se efectúan con los elementos superiores de la pila y el resultado se queda en ella. Por ejemplo Calcular C=(a+b)/(d-e). La pila es una estructura de datos en memoria en la cual el primer elemento que entra es el último en salir. . . . Apuntador de base (BP) Apuntador indica la de pila dirección base (SP) de la pila 33
  • 38. B E A A A+B D D D-E D-E D-E D-E C Push D Push E SUB Push A Push B ADD DIV Pop C Instrucciones en Macroensamblador [etiqueta] mnemónico de instrucción [operando] [;comentario] [ ] significa que es opcional etiqueta: se usa como punto de entrada o regreso. El nombre se asocia con la dirección donde comienza una instrucción y puede tener hasta 31 caracteres [A-Z, a-z, 0-9, ?, ., @, _, $] y debe iniciar con cualquier carácter distinto de 0-9. mnemónico de instrucción: debe contener una de las 92 instrucciones posible. Por ejemplo: SUB destino, fuente SUB AX, AX; AX AX-AX SUB AX, 18D MOV to, from MOV AX, 18 con D = Decimal; H = Hexadecimal O = Octal B = Binario Atributos de distancia de los segmentos NEAR: Corresponden a etiquetas o procedimientos definidos en el mismo segmento FAR: Corresponden a etiquetas o procedimientos definidos en otro segmento. Cuando la referencia es NEAR, el registro IP cambia y si es FAR, IP y CS cambian. Estructura de un programa En el Macroensamblador es posible procesar hasta cuatro tipos de segmentos. El programa mínimo requiere de dos segmentos: el de código y el de pila (CS, SS), el ensamblador busca la definición del segmento stack y genera un error, si el usuario olvida incluirlo. El pseudo-operador SEGMENT del macroensamblador sirve para definir un segmento. Los pseudo-operadores son el medio por el que el programador le indica al ensamblador lo que debe hacer para preparar y estructurar el código en lenguaje de máquina. Este código de máquina está basado en los datos e interrupciones contenidos en el programa fuente. Los pseudo-operadores no generan código máquina. Existen cuatro tipos de pseudo-operadores: de datos (SEGMENT es incluido en este tipo), de ramificación condicional, macros y listados. 34
  • 39. Ejemplo de un programa en MASM PAGE 50, 132 TITLE PRUEBA COMMENT * ELABORADO POR: Sexto semestre de L. C. C. del Centro Escolar Felipe Carrillo Puerto FECHA: 1 de marzo de 2005 DESCRIPCIÓN: Este módulo limpia el contenido del registro AX, dejando ceros. Después coloca en AX el valor de 18. Todas las operaciones pueden ser observadas en el debug. * ; ; STACK SEGMENT PARA STACK ‘STACK’ ; ;Se inicializará con cero el segmento del stack y se cargará con una cadena de caracteres: 64 ;valores de ‘stack ’ ; DB 64 DUP (‘STACK ’) STACK ENDS CSEG SEGMENT PARA PUBLIC ‘CODE’ ASUME CS:CSEG, SS:STACK ; SUB AX, AX MOV AX, 18 SUB AX, 18 ; CSEG ENDS END PAGE (pseudo-operador de listado): sirve para definir las dimensiones de la página y solo tiene efecto cuando se pone en lista el archivo general durante el ensamble. PAGE operando1, operando2 donde operando1 indica el número de líneas verticales por página en el listado producido en el ensamblado (por default 66) y operando2 es el número de caracteres por línea (por default 80). TITLE (pseudo-operador de listado): indica el título que será impreso en el encabezado de cada página de listado generado por el ensamblado. ; y COMMENT: El ‘;’ sirve para indicar un comentario de una línea y COMMENT para indicar comentarios multilínea. Para COMMENT el primer carácter diferente de un espacio se usa como delimitador; todos los demás caracteres que se encuentren entre los delimitadores son considerados comentarios y por lo tanto ignorados por el ensamblador. Parámetros de Pseudo-Op Segment SEGMENT: El pseudo-operador SEGMENT tiene el siguiente formato: nombre-seg SEGMENT tipo-alineamiento tipo-combinación ‘clase’ donde: nombre-seg: indica el nombre del segmento tipo-alineamiento: señala al ensamblador la manera en la que comenzarán los segmentos en la memoria. Existen 4 tipos:  PARA: es el predeterminado e indica que el segmento comienza en los límites de un párrafo (dirección divisible por 16)  BYTE: el segmento puede comenzar en localidad de memoria  WORD: el segmento debe iniciar en el límite de una palabra (donde la dirección sea par)  PAGE: el segmento debe iniciar en una página (los últimos 8 bits de la dirección son cero) tipo-combinación: indica la manera en la que los segmentos serán combinados o cargados cuando se ejecute el encadenador (linker). Existen 5 formas: 35
  • 40.  PUBLIC: todos los segmentos con el mismo nombre y con atributo PUBLIC serán encadenados juntos.  COMMON: todos los segmentos con el mismo nombre empezarán en la misma dirección y se traslaparán en memoria.  AT(exp): se utiliza para definir variables con un desplazamiento fijo de memoria. El segmento se coloca en el párrafo indicado por el resultado obtenido después de evaluar “exp”.  STACK: Sirve Para indicar que el segmento es parte del STACK.  MEMORY: todos los segmentos de este tipo se colocarán en direcciones de número mayor que cualesquiera otros segmentos. ‘clase’: se emplea para hacer referencia a una colección de segmentos. Los segmentos con el mismo nombre de clase se colocan en memoria secuencial, siguiendo el orden en que los encontró el encadenador. Cada segmento debe terminar con la siguiente sentencia: nombre-seg ENDS DB(pseudo-operador de datos): sirve para definir una variable o para inicializar un área de memoria (DB = Define Byte). Tiene la siguiente forma: [nombre-variable] DB expresion DUP (duplica), en el ejemplo DB 64 DUP (‘stack ’) está inicializando un área de memoria con 64 duplicaciones de ‘stack ’ [nombre-variable]: es opcional y dependerá su uso si se desea asociar un nombre simbólico con un valor. ASSUME (pseudo-operador de datos): le indica al ensamblador a cuál registro pertenece un determinado segmento. Tiene la forma ASSUME segmento de registro: nombre de segmento, … 36
  • 41. PROGRAMANDO CON EL MASM Ya estamos en condiciones de utilizar el ensamblador, este es un programa del DOS que hará nuestra programación más fácil. De aquí en adelante, escribiremos las instrucciones mnemónicas, directamente usando el ensamblador, para convertir nuestros programas en código máquina. UN PROGRAMA SIN EL DEBUG Actualmente hemos utilizado el DEBUG, tecleando instrucciones del programa. Ahora escribiremos los programas sin él, y nosotros tendremos que usar un editor o un procesador de texto para crear el código, archivos que contienen nuestras instrucciones del lenguaje ensamblador. Use el “edit”4 para ingresar las siguientes líneas de código el archivo se llamará WRITESTR.ASM (la extensión .ASM quiere decir éste es un archivo de origen ensamblador). Así como con el Debug, puede escribir el código con minúscula o con mayúscula sin embargo nosotros usaremos las mayúsculas para evitar la confusión entre el número 1 (uno) y la letra minúscula l (ele): .MODEL SMALL .CODE MOV AH, 02h MOV DL,2Ah INT 21h INT 20h END Ignore por ahora las tres nuevas líneas en nuestro archivo de origen, note que hay un ‘h’ después de cada número hexadecimal. Esta h le indica al ensamblador que los números son en hexadecimal. DEBUG supone que todos los números son en hexadecimal, en el ensamblador supone todos los números decimales. Nosotros le indicaremos que será un número hexadecimal poniendo una h después de cualquier número. Nota: El ensamblador puede confundirse por los números, por ejemplo, ACh que se parece un nombre o una instrucción. Para evitar esto, siempre teclee un cero antes, para diferenciar el número hexadecimal que empieza con una letra. Por ejemplo, no teclee ACh. Veamos lo que pasa cuando Ensamblemos un programa con ACh, en lugar de 0ACh. Aquí está el programa: .MODEL SMALL .CODE MOV DL,ACh INT 20h END 4 Sin embargo para facilitar nuestro trabajo usaremos el Programmer’s File Editor, ya que nos proporciona la ventaja de agregar números de línea que nos ayudará a localizar el número de línea que marque error al momento de compilar. 37
  • 42. Aquí está la salida A> MASM TEST; Microsoft (R) Macro Assembler Version 6.11 Copyright (C) Microsoft Corp 1981, 1998. All rights reserved. test.ASM(4) : error A2009: Symbol not defined: ACH 49842 + 224473 Bytes symbol-space free 0 Warning Errors 1 Severe Errors A> . Pero cambiando el ACh a 0ACh se soluciona el ensamblador. También note el espacio de los comandos en nuestro programa ensamblador. Usaremos los tabuladores para alinear y hacer el texto más legible. Compare el programa en que usted entró con esta versión: Ahora regresemos a las 3 líneas nuevas del archivo. Las tres nuevas líneas son todas las directivas (también llamadas pseudo-ops, o pseudo-operadores). Son llamadas directivas porque, en lugar de generar instrucciones, proporcionan información y direcciones al ensamblador. El pseudo-op END marca el fin del archivo, para que el ensamblador sepa qué hacer cuando encuentra un END. Después, veremos que este END es útil de otras maneras, también. Por ahora, apartemos cualquier discusión extensa de él o las otras dos directivas y vea cómo usar el ensamblador. Creando archivos de origen Aunque usted ha ingresado las líneas de WRITESTR.ASM, hay una consideración más. El ensamblador puede usar archivos del origen que sólo contienen los carácteres de ASCII estándares. Si usted está usando un procesador de texto, tenga en cuenta que no todos los procesadores de texto guardan los caracteres ASCII estándares. Antes de que probemos el archivo WRITESTR.ASM, asegúrese que todavía es ASCII. Haga Type del DOS: A>TYPE WRITESTR.ASM Debe ver el mismo texto que ingresó. Si ve caracteres extraños en su programa, tendrá que usar un editor diferente para escribir los programas. Ahora, empecemos a ensamblar Writestr; teclee lo siguiente: A>MASM WRITESTR; Microsoft (R) Macro Assembler Copyright (C) Microsoft Corp 1981, 1988. A11 rights reserved. 49822 + 219323 Bytes symbol space free 0 Harning Errors 0 Severe Errars A> Nosotros no hacemos nada todavía. El ensamblador ha producido un archivo llamado WRITESTR.OBJ que usted encontrará ahora en su disco. Éste es un archivo intermedio, llamado archivo objeto. 38
  • 43. Linking Ahora queremos que nuestro LINK tome nuestro .OBJ y cree uno .EXE de él. Enlace WRITESTR.OBJ tecleando: A>LINK WRITESTR; Microsoft (R) Overlay Linker Copyright (C) Microsoft Corp 1963-1988. All rights reserved. LINK: warning L4021: no stack segment A> Aunque el LINK nos advierte que no hay ningún segmento de la pila, nosotros no necesitamos uno ahora mismo. Después de que nosotros aprendemos a agregar más instrucciones, veremos porqué nosotros podríamos querer un segmento de la pila. Ahora nosotros guardemos nuestro .EXE, pero este no es el último paso. Nosotros tenemos un archivo .COM tal y como lo creamos con el DEBUG. De nuevo, se verá después porqué nosotros necesitamos todos estos pasos. Para ahora, creemos un archivo .COM de Writestr. Nosotros necesitamos el programa EXE2BIN.EXE del DOS. Exe2bin, como su nombre lo indica, convierte un .EXE a .COM, o archivo binario. A>EXE2BIN WRITESTR WRITESTR.COM A> La contestación no nos dijo mucho. Para ver si Exe2bin trabajó, listemos todo el Writestr guardados hasta ahora: con DIR WRITESTR.* Regresando al DEBUG Leamos nuestro archivo .COM (o .EXE) en el DEBUG y desensamble para ver cómo el DEBUG reconstruye nuestro programa en código-máquina de WRITESTR.COM A>DEBUG WRITESTR.COM _U 397F:0100 8402 MOV AH, 02 397F:0102 822A MOV DL, 2A 397F:0104 CD21 INT 21 397F:0106 CD20 INT 20 Los comentarios En los programas del lenguaje ensamblador, nosotros ponemos los comentarios después de un punto y coma El ensamblador ignora algo en la línea después de un punto y coma, para que nosotros podemos agregar algo que nosotros queremos. .MODEL SMALL .CODE MOV AH, 2h ;Selecciona la función 2 de DOS para sacar un caracter MOV DL, 2Ah ;Carga el código ASCII a ser impreso INT 21h ;Imprime con la NT 21h INT 20h ;y Sale del DOS END Las etiquetas Cuando quisimos bifurcar (saltar) en una parte del programa a otro con uno de los comandos de la bifurcación (JNZ, JLE, etc), nosotros teníamos que saber la dirección específica nosotros estábamos saltando a. Cada vez que programábamos, insertábamos nuevas instrucciones obligando a que 39
  • 44. cambiemos las direcciones en las instrucciones de salto. El ensamblador cuida de este problema con nombres de etiqueta que nosotros damos a las direcciones de cualquier instrucción o situaciones de la memoria. Una etiqueta tiene lugar. En cuanto el ensamblador vea una etiqueta, reemplaza la etiqueta con la dirección correcta antes de enviarlo delante del microprocesador. Las etiquetas pueden ser de hasta 31 caracteres y puede contener letras, números, y algunos de los siguientes símbolos: un signo de interrogación (?), un punto (.), una arroba ( @ ) un guión bajo ( _ ) o un signo de peso ( $ ). Sin embargo no puede empezar con un dígito (0-9) y el punto puede ser usado solamente como el primer carácter. Ejemplo: 0111 010C JLE DIGIT1 010E SUB DL DIGIT1: 0111 MOV CL 0113 SHL DL,1 Tomemos como ejemplo práctico el código empleado para leer 2 dígitos hexadecimales. 0100 MOV AH, 01h 0102 INT 21 0104 MOV DL, AL 0106 SUB DL, 30h 0109 CMP DL, 09h 010C JLE Salto1 010E SUB DL, 07h 0111 MOV CL, 04h 0113 SHL DL, CL 0115 INT 21 0117 SUB AL, 30 0119 CMP AL, 09h 011B JLE Salto2 011D SUB AL, 07h 011F ADD DL, AL 0121 INT 20 No será obvio lo que este programa hace, y si no está fresco en su mente, usted puede tener que trabajar un poco para entender el programa de nuevo. Agreguemos etiquetas y comentarios para clarificar su función: .MODEL SMALL .CODE MOV AH, 01h ;Seleccione la función 1 del DOS, para introducir un carcater INT 21 ;Lee un caracter, y retorna el código ASCII en el registro AL MOV DL, AL ;Mueve el código ASCII dentro de DL SUB DL, 30h ;Resta 30H para convertirlo en digito de 0 a 9 CMP DL, 09h ;Está el dígito entre 0 y 9? JLE Salto1 ;Si, entonces tenemos el primer dígito SUB DL, 07h ;No, Resta 7H para convertirlo en letra de la A a la F Salto1: MOV CL, 04h ;Prepara para multiplicar por 16 SHL DL, CL ;Realiza el corrimiento hacia la izquierda INT 21 ;Solicita el siguiente caracter SUB AL, 30 ;Repite la operación CMP AL, 09h ;Es un dígito de 0-9? JLE Salto2 ;Si, tenemos el segundo dígito 40
  • 45. SUB AL, 07h ;No, restamos 7H Salto2: ADD DL, AL ;Agregamos el segundo dígito INT 20 ;Finalizamos END Las etiquetas, SALTO1 y SALTO2, son de un tipo conocido como Etiquetas Cercanas (NEAR), porque los dos puntos (:) aparecen después de las etiquetas cuando ellos están definidos. El término NEAR tiene que ver con segmentos que nosotros hablaremos más adelante junto con las directivas .MODEL, y .CODE. Si ensambla el programa y lo desensambla con el DEBUG, verá que SALTO1 se reemplazó por 0111h y SALTO2 se reemplazó por 011Fh. 41